You don't know how to rebase.

Even if you think you know how to rebase, you don't.

Have you ever had conflicts about a file you didn't modify? Yes? Then you don't know how to rebase.

Don't worry it will be fine, you will read this blog post, and I will save you a bunch of time in your life.

How does rebase is working?

If you are using rebase it's because you want to have a clean and flat history.

Let's say you have to develop a feature, what you will do is to create a new branch from master, and start committing on this branch.

Maybe master will do his life without you, and some commits will be added on top of master. If so, you have to rebase.

A---B---C feature, HEAD / D---E---F---G master
txt

What you want is to move commits A-B-C on top of master.

In this case it's simple, you will just use the command:

$ git rebase master
bash

How does it work? The question is legit, there is no notion of base for a branch. A branch is just a kind of tag that can make progress with the command git-commit.

To know which commits has to be moved, when you call git rebase, git will try to find a common commit between your branch and master. In our case the commit is E, then git know that the "base" of your branch is E, and git will try to change this base to "master".

What can be the problem?

What if you are working on a branch that is already on top of master? What if E is no more present on master? What if git does not understand what is the base of your branch?

Let's have a look to this case:

H--I--J feat, HEAD / A---B---C dev / D---E---A---B--C--G---F master
txt

Let's say you want to rebase H-I-J on top of master. You will instinctively use:

$ git rebase master
bash

If we follow the previous explanation of git rebase, the first step is to find the common ancestor between feat and master, which is D. So commits A-B-C-H-I-J will be rebased on top of master, right?

But they are already included in master, so you will have to manage conflicts (it can be worst if someone has modified what were introduced by A-B-C with F-G).

--onto to the rescue

git-rebase can take many arguments, and today I will introduce you --onto. In a nutshell it will allow you to define the base of your branch to help git.

$ git rebase --onto master <BASE>;
bash

If we want to rebase H-I-J on top of master. We need to know the base of the branch: C, then then command can be used like this:

$ git rebase --onto master C
bash

Then the git history will look like:

A---B---C dev / H--I--J feat, HEAD / / D---E---A---B--C--G---F master
text

No more conflicts! You're welcome!

After using this command, I realized that I don't know anymore how to use git rebase without --onto

ironic-gif