Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rebase a branch off a rebased branch?

So my history looks like this:

o---o---o---o master \ o---o---o A \ o B

So, to explain:

  • I have branch A which was started from master
  • I have branch B (with only 1 commit) which was started from A

What I want is this:

o---o---o---o master \ o---o---o A \ o B


What I did was:

1).

git checkout A git rebase master

This resulted in a lot of conflicts which, after some significant time spent fixing, the following history emerged:

o---o---o---o master \ o---o---o A

Which is exactly what I wanted.

(I don't know where B is right now)


2).

After this I did a lot of squashes and changed the order of commits on A, to make the history look like I want.


3).

Now, what I also want to do is:

git checkout B git rebase A

However this doesn't seem to work and I don't know why. If I do git log I see the commits which were there before I did step 1.

Also, I get the same huge number of conflicts which I already solved at step 1. I spent significant time doing it, don't want to do it again.

This example suggested to use --onto, which I did:

git checkout B git rebase --onto A

But this deletes the commit on B entirely and makes A and B point to the same commit i.e. the last one on A.


My question is: How can I effectively rebase B off A so that it looks like B started from A ? (which was actually true in the beginning).

My best guess is that I'm using --onto wrong. Or that I should use something else (like cherry-pick).

like image 464
Radu Murzea Avatar asked Aug 07 '15 15:08

Radu Murzea


People also ask

How do you rebase a child branch with the parent branch?

The solution is to use git rebase --onto after rebasing the first branch. This will rebase all commits of feature2 that follow the old head of feature1 (i.e. F ) onto the new head of feature1 (i.e. F' ).


1 Answers

Short answer to How can I effectively rebase B off A so that it looks like B started from A? Assuming you want to move exactly one commit:

git rebase --onto A B~ B 

If you want to move more then one commit use:

git rebase --onto A old_A B 

The rest of the answer.

Your branch of B is still around (you can check it out), but its parent is still the exact commit object that A was before.
to see a graphical representation of this I use:

git log --graph --decorate --all 

to see all branches and where they are with respect to each other.

What you originally had:

o---o---o---o  master      \       o---o---o  A                \                 o B 

What you have now:

o---o---o-----------o  master      \               \       o---o---o(B~)   o---o---o A                \                 o B 

In terms of using --onto, you need to have a starting point and an ending point. use:

git rebase --onto [target] [rebasing stops] [rebasing head] git rebase --onto A B~ B 

And what you get:

o---o---o----------o  master      \              \       o---o---o      o---o---o A             (old_A)           \                                o B 

[branch_name]~ indicates the parent commit of the branch.

The B~ is the branch that you do not want to change. (It happens to be the old A)

Alternatively, if B was the only commit that had A as a parent, (i.e., B is the end of a chain of commits that branch off master) you could do

git checkout B git rebase master git checkout B~   # this is the commit before B (the A commit) git branch -d A   # remove the old A branch (it was rebased, and so is now invalid git branch A      # recreate the A branch on the commit that is based on the original A 
like image 198
Thomas F Avatar answered Sep 24 '22 10:09

Thomas F