Last Updated: September 29, 2021
·
1.616K
· saimonmoore

How do I rebase a chain of local git branches?

Suppose you have a chain of local git branches, like this:

 develop    branch1    branch2
    |          |         |
o----o----o----A----B----C----D

You pull in an upstream change onto the develop branch:

         branch1   branch2
            |         |
       A----B----C----D
      /
o----o----o----o
          |
       develop

Now you rebase branch1, giving you this:

                   branch2
                      |
       A----B----C----D
      /          
o----o----o----o----A'---B'
          |         |
       develop    branch1

Note: Because of rebasing branch1, commits A and B have been rewritten as A' and B'.

Now you want to rebase branch2 (and any other chained branches if you have them).

The obvious syntax is git rebase branch1 branch2, but that does not work.

What you'd like to do is just reapply C and D on top of branch1, but instead it tries to reconcile A and A' and it considers them conflicting.

This does work:

git rebase --onto branch1 branch2^^ branch2

However, assumes you know that branch2 has exactly 2 commits beyond the previous branch1 ref.

Solution 1:

git rebase --onto branch1 branch1tmp branch2

where branch1tmp was cloned off branch1 ** before ** branch1 was rebased with develop.

e.g.

git checkout branch1
git branch branch1tmp
git rebase develop
git rebase --onto branch1 branch1tmp branch2

Solution 2:

From git rebase man page:

ORIG_HEAD is set to point at the tip of the branch before the reset.

This is basically the marker that you need to for git --onto.

So by using ORIG_HEAD you don't even need the tmp branch:

git checkout branch1
git rebase develop
git rebase --onto branch1 ORIG_HEAD branch2
git rebase --onto branch1 ORIG_HEAD branch3
git rebase --onto branch1 ORIG_HEAD branch4

When I discovered this tip I was overjoyed. Maintaining these chained branches is a huge pain which has now disappeared.

Extracted from: http://bit.ly/1wAdQK1