How do I rebase a chain of local git branches?

0

Issue

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

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

I pull in an upstream change onto the master branch:

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

Now I rebase branch1, giving me this:

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

Note that because of rebasing branch1, commits A and B have been rewritten as A’ and B’.

Here’s my problem: now I want to rebase branch2. The obvious syntax is git rebase branch1 branch2, but that definitely does not work. What I want it 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

This assumes I know that branch2 has exactly 2 commits beyond the previous branch1 ref.

Since git rebase --onto works, is there a 1-line git command that will rebase branch2 on top of a newly-rebased branch1, in a way that I don’t have to know exactly how many commits were part of branch2? (I want to specify some magic ref instead of branch2^^ for the middle argument.)

Or is there some other approach I’m overlooking?

I would be most interested in a solution that scales well to extreme cases, not just two branches – suppose I’ve got something more like 5 local branches, all chained on one another, and I want to rebase all of them together.

Solution

One-line:

git rebase --onto branch1 branch1tmp branch2

That supposes to make a branch1tmp on branch1 before rebasing branch1.

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

That being said, check what ORIG_HEAD references.
From git rebase man page:

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

So check if this would work (and scale better):

git checkout branch1
git rebase master
git rebase --onto branch1 ORIG_HEAD branch2
git rebase --onto branch2 ORIG_HEAD branch3
...

Answered By – VonC

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave A Reply

Your email address will not be published.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More