Git rebase and Git rebase --onto

Lately I’ve been doing the Githug tutorial to improve my Git skills. I’ve learned a lot of new Git commands while solving the problems or answering to the questions that you are asked in the tutorial (some of which rather hard!)

The toughest question I had to deal with — and which took me some time to solve — was about the command git rebase --onto. I’ve just lately started to become familiar with the command git rebase <branch> but the option --onto added to that same command has complicated things further.

That is why I decided to learn more in depth about the command rebase --onto, but also to enhance my knowledge of the basic command git rebase as I felt it wasn’t clear enough to me, since I had to struggle so much to get the --onto option.

How git rebase works

In a nutshell, git rebase takes the commits of a branch and appends them to the commits of a different branch. The commits to rebase are previously saved into a temporary area and then reapplied to the new branch, one by one, in order. Let’s look at a practical example.

In the case of two different branches below:

where other_branch is based on master, we want to copy the commits of other_branch and add them after the last commit of master in order to achieve this result:

other_branch now includes all the commits of master. In order to achieve this we have to use the following Git command:

or just

Both above commands lead to the same result. The only difference is that for the latter example you are in other_branch branch already, whereas in the former example Git first performs an automatic git checkout other_branch before rebasing other_branch to master. After rebasing you automatically are in other_branch branch.

The technical syntax for the Git command rebase is:

In case of conflict, git rebase will stop at the first problematic commit and leave conflict markers in the tree. You can use git diff to locate the markers (<<<<<<) and make edits to resolve the conflict. For each file you edit, you need to tell Git that the conflict has been resolved with the following commands:

Git rebase --onto

The syntax for Git command git rebase —-onto is:

Let’s say we had a situation like this with three branches:

branch_two is based on branch_one but we need to fork it from master. The reason for this could be, for example, that a functionality on which branch_two depends was merged into master and branch_two needs to include the commits master assimilitated after the fork.

We need to achieve something like this:

The commits of branch_two are rebased on master while the commits of branch_one stay untouched. To achieve this we use the command:

Githug exercise

The exercise from Githug that I struggled to figure out is the following:

Reproduction of Githug problem

other_branch is based on wrong_branch. We want to rebase it to master so that the commits of wrong_branch are not included in its commits.

We want to achieve this:

How the Githug problem should be resolved

The Git command to solve the above Githug problem is:

or, if you’re already in other_branch, just:

master (aka <new base>) becomes the new base for <branch> other_branch which was previously based on wrong_branch (aka <upstream>).

I think the reason why I was confused about this command at the beginning lies in the <upstream> part: I couldn’t figure out why I would have to put wrong_branch in the whole command syntax (as a matter of fact, what I tried to do at the beginning was something like git rebase --onto master other_branch, or the other way round.)

The above command makes more sense now that I was able to define the concept of upstream and the part it plays in the command as a whole, although I feel I have to look more into it and understand its meaning better.

… to become a developer!