说,我的git repo中有这种情况
A--B--C--D master
|\
| E--F topic
|
\
G--H other
我希望将topic
重新绑定到other
分支。这适用于:
git rebase --onto other master topic
给了我
A--B--C--D master
|
\
G--H other
\
E--F topic
但如果topic
已合并为主(git merge topic
),则上述rebase
命令不再有效。如果我尝试,我似乎得到这样的东西:
A--B--C--D--M master
|\ /
| E--F----
|
\
G--H other / topic
虽然我想要这个:
A--B--C--D--M master
|\ /
| E--F----
|
\
G--H other
\
E'--F' topic
为什么会这样,即使已将topic
合并到other
,又如何将master
重新定位到E
?
编辑:更新了底部图表以明确,F
和topic
不是相同的提交 - 但引入了相同的变更集。
编辑2:我真正想要的是,好像我首先创建了topic-rebased
(说other
)的副本,我在之前变为topic
然后我将other
合并到git checkout topic
git checkout -b topic-rebased
git rebase --onto other master topic-rebased
git checkout master
git merge topic
:
master
这很好用。但是如果主题已经合并到{{1}}中,则rebase不再起作用。
答案 0 :(得分:3)
您不能指望每个E
和F
提交中有两个存在于您的存储库中。如果他们有不同的父母(他们这样做:一组有A
为父母,另一组有H
为父母),那么一个E
将是E
另一个。
在您的情况下,如果您想要此结果,则应查看cherry-picking:
git checkout topic # puts you on `H`
git cherry-pick E
git cherry-pick F
这会将提交E
和F
应用到您当前的分支中,并基本上创建它的副本。所以你应该得到理想的结果。
答案 1 :(得分:0)
如果您的历史记录与您的示例相同,则可以执行此操作:
git checkout topic
git rebase --onto other --root
我试了一下确认:
% git init .
(add commit a)
% touch a; git add a ; git commit -m "a"
% git checkout -b topic
(add commits e and f, elided for brevity)
% ls
a e f
% git checkout master
% git checkout -b other
(add commits g and h)
% ls
a g h
% git checkout master
(add commits b, c, and d)
% ls
a b c d
% git merge topic
Merge made by the 'recursive' strategy.
e | 0
f | 0
2 files changed, 0 insertions(+), 0 deletions(-)
% ls
a b c d e f
% git checkout topic
% ls
a e f
% git rebase --onto other --root
First, rewinding head to replay your work on top of it...
Applying: e
Applying: f
% ls
a e f g h
它会自动找到共享父级,并且只添加(实际上)来自主题分支的提交,即使它已经合并到master中。