Reputation: 159
I am trying to rebase a feature branch (branched off of master) onto a specific commit of another branch. My initial status was the following
C -- D branch1
/
A -- B -- E -- F master
\
branch2 (zero commits after creating the branch)
I first rebased branch2 onto A in master which worked fine. My current status should (according to my understanding) be the following
C -- D branch1
/
A -- B -- E -- F master
\
B -- E -- F branch2
I verified that branch2 branches off of master at commit A and is even with the master branch. What I now want to get is this
A -- B -- E -- F master
\
B -- E -- F branch2
\
C -- D branch1
I tried
git checkout branch1
git rebase --onto B branch2
But this resulted in a whole bunch of conflicts and I don't understand at all how these arise. Maybe I am misunderstanding entirely what rebase does?
Note: After successfully rebasing branch1 onto B of branch2, I intend to reset master to A, so the final version is supposed to look the following way.
A master
\
B -- E -- F branch2
\
C -- D branch1
Upvotes: 3
Views: 1105
Reputation: 164659
There's some problems with your assumptions. First, branches are just pointers to commits. You start with this, and master
is checked out.
C -- D branch1
/
A -- B -- E -- F master
After git branch branch2
you have this.
C -- D branch1
/
A -- B -- E -- F master & branch2
Note there is no stub branch, master
and branch2
both point at F. Aside from their names, they are indistinguishable.
Once you checkout branch2
and git rebase A
nothing changes. branch2
already has A
in its ancestry, it remains pointing at F
. You should have gotten a message like Current branch branch2 is up to date
.
When you did git checkout branch1
and git rebase --onto B branch2
this confused things. There's an assumed third argument, the currently checked out branch. What you actually ran is git rebase --onto B branch2 branch1
. That says "take the commits reachable by branch1 but not by branch 2 (the same as git log branch2..branch1
or C and D) and put them onto B". This should be a no-op, but if branch1 and branch2 have any changes in common the rebase will throw them out.
If C and E made the same changes you'd wind up with this, and probably a conflict.
C -- D original branch1
/
A -- B -- E -- F master & branch2
\
D1 branch1
This doesn't make much sense, but that's what happens when you try to rebase between two cousins.
Also note that the rebased branch has the id D1, not D. Commit IDs incorporate the ID of their parents, so the ID must change. rebase
does not rewrite history, it creates new history and tells you that's how it always was. A subtle but important distinction. Your original commit is still there... for a while.
If you want to go from this:
C -- D branch1
/
A -- B -- E -- F master & branch2
To this.
A master
\
B -- E -- F branch2
\
C -- D branch1
That can be flipped over so it aligns with what you have better.
C -- D branch1
/
B -- E -- F branch2
/
A master
All you need to do is move master
to A. There's several ways to do this, one is git branch -f master A
. This forces master
to move to A
.
Upvotes: 4