2

Suppose I've got two local git branches I'm working on.

Branch 1 is branched off of "master", and branch 2 is branched off of branch 1 (and depends on it).

Both are works in progress, I'm not ready to push either of them yet.

While working on branch 2, I see a change I want to make, so I switch back to branch 1 and refactor it a bit, adding a new commit.

Now I want to go back to branch 2 and rebase it.

If I run git rebase branch_1 branch_2, I get a ton of conflicts, because branch_2's history currently includes the old branch_1 commits before the refactoring, and the new refactoring in branch_1 conflicts.

Let's assume for the moment that there are no actual conflicts. If I were to create a new branch 2b, and cherry-pick all of the commits unique to branch 2 in order, they'd patch cleanly.

Is there an easy way to rebase all of the commits unique to branch_2 onto the new branch_1?

michas
  • 25,361
  • 15
  • 76
  • 121
dmazzoni
  • 12,866
  • 4
  • 38
  • 34
  • Note: in simple cases, `git rebase branch_1 branch_2` will work - so assume that I amended a commit or did an interactive rebase to branch_1, that guarantees there will be a conflict. – dmazzoni Dec 30 '13 at 00:15
  • Your rebase tries to rebase all the commits listed by `git log branch_1..branch_2`. Are those the same commits you are trying to cherry-pick? (Maybe you should add a small commit graph to make your situation a bit more clear.) – michas Dec 30 '13 at 00:31

2 Answers2

1

Your commits on branch2 are based on a unrefactored commit and then changes the unrefactored code. Now you try to rebase those changes on a refactored commit, but your changes still try to change the unrefactored lines of code which are no longer contained in your refactored code. - Sorry, this kind of rebase is just not possible.


Let's see if I got things right. This is your starting situation:

  master     branch_1     branch_2
    ↓           ↓           ↓
o---o---o---o---x---a---b---c

You add your refactoring:

              branch_1
                  ↓           
  master          r       branch_2
    ↓            /          ↓
o---o---o---o---x---a---b---c

Now your rebase should do this:

              branch_1    branch_2
                  ↓           ↓
  master          r---a---b---c
    ↓            / 
o---o---o---o---x

But commit a is changing lines of x which are no longer contained in r. Therefore the rebase should not be able to work without conflicts.

Even if you create a new branch a r and try to cherry-pick a you should run into exactly the same problem. - Please clarify your question if I understood something completely wrong.

michas
  • 25,361
  • 15
  • 76
  • 121
  • No, you're misunderstanding. I specifically said that if you cherry-picked the commits that were part of branch_2, they'd patch cleanly on top of the refactored code. Also, it looks like "git rebase --onto" does exactly what I want, I just haven't figured out how to turn it into a one-liner yet. – dmazzoni Dec 30 '13 at 00:25
  • `git rebase branch_1 branch_2` should be exactly the same as `git rebase --onto branch_1 branch_1 branch_2`. The `branch_1 branch_2` specifies which commits to move. The `--onto branch_1` specifies where to move them to. But the situation above still remains. – michas Dec 30 '13 at 00:54
  • This was my fault for asking a poor question. I made an attempt at a better question here: http://stackoverflow.com/questions/20834648/chain-of-local-git-branches – dmazzoni Dec 30 '13 at 06:46
0

OK, if I know that branch_2 has 3 commits from when it diverged from branch_1, I can do this:

git rebase --onto branch_1 branch_2^^^ branch_2

Is that reasonable? Is there a shorthand way I can specify the point where branch_2 diverged? I tried branch_2@{u}, but that didn't work.

dmazzoni
  • 12,866
  • 4
  • 38
  • 34