This is the current state of my git repository history:
--o--o--o--o--o--o--o master
\
o--o--o--o--o topic2
|
topic1
I want to rebase topic1 and topic2 onto master, and make it like:
--o--o--o--o--o--o--o master
\
o--o--o--o--o topic2
|
topic1
What is the best method to achieve this?
git rebase master topic2
git branch -f topic1 HEAD~2 # On (rebased) topic2, set topic1 pointer
Note that this assumes topic1
is simply a pointer to the past of topic2
, ie, there should not be any commits on topic1
that are not on topic2
. (The HEAD~2
assumes commit history as shown, in reality you would probably want to use a specific commit id. Note how this would also work if topic1
didn't even exist: as it has no commits of its “own”, the pointer can just be set arbitrarily.)
Edit : In this situation, you can alternatively do:
git rebase master topic1
git rebase topic1 topic2
The end result should be the same as the first option (iff topic2
contains all of topic1
's commits!). This syntax may be easier to understand, but the solutions will differ if topic1
does contain commits that are not in topic2
. If that is the case the former solution will simply discard any commits in topic1
that are not in topic2
, while the latter will merge them into topic2
. Both outcomes are probably undesirable, but in my opinion it is more clear from the first solution what will happen, which is why I put it first.
To illustrate, if your commit history looks like:
a1 - a2 - a3 - a4 - a5 - a6 - a7 master
\
b1 - b2 - b3 - b4 - b5 topic2
\
c1 topic1
Then the first solution ( rebase
, branch
) will give you:
a1 - a2 - a3 - a4 - a5 - a6 - a7 - b1' - b2' - b3' - b4' - b5' topic2
\ master \ topic1
And the second ( rebase
, rebase
):
a1 - a2 - a3 - a4 - a5 - a6 - a7 - b1' - b2' - b3' - c1' - b4' - b5' topic2
\ master \ topic1
However, in this case what you probably wanted to get was:
a1 - a2 - a3 - a4 - a5 - a6 - a7 - b1' - b2' - b3' - b4' - b5' topic2
\ master \
c1' topic1
The solution for this outcome would be:
git branch tmp id_of_b3_commit # In this case id_of_b3_commit == topic1^
git rebase master tmp
git rebase tmp topic1
git rebase tmp topic2
git branch -d tmp
(If you made this into a script, you could use git merge-base topic1 topic2
to find the id of the commit to put into the tmp
branch.)
If topic 2 is in fact a branch with at least one of it's own commits, then you can do some grafting. But an easier way to do this is to merge topic 1 and topic 2. Now 'rebase --onto' the new place this merged branch with --preserve-merges. Reset topic 1 and topic 2 to where they are supposed to sit.
You may rebase topic1
and topic2
branches one-by-one.
Rebase first one
git checkout topic1
git rebase master
Then rebase second one
git checkout topic2
git rebase master
But i'm not sure what will be with the topic1^
point.
I suggest to do it in a little bit more complicated way that will preserve branches merge history.
First make new branch with all commits shared by both topics (you may use commitish or tag instead)
git checkout -b topics topic1^
Then rebase it on master
git rebase master
Then rebase both topics on shared branch.
git checkout topic1
git rebase topics
git checkout topic2
git rebase topics
This should work. Now you may to drop temporary branch.
git branch -d topics
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.