Git 为什么可以';我不能重新设置合并主题分支的基础吗?

Git 为什么可以';我不能重新设置合并主题分支的基础吗?,git,git-rebase,Git,Git Rebase,比如说,我的git回购中有这种情况 A--B--C--D master |\ | E--F topic | \ G--H other 我想将主题重设为其他分支。这适用于以下情况: git rebase --onto other master topic 这让我 A--B--C--D master | \ G--H other \ E--F topic 但是如果topic已经合并到master(git mer

比如说,我的git回购中有这种情况

A--B--C--D   master
|\
| E--F       topic
|
 \
  G--H       other
我想将
主题
重设为
其他
分支。这适用于以下情况:

git rebase --onto other master topic
这让我

A--B--C--D   master
|
 \
  G--H       other
      \
       E--F  topic
但是如果
topic
已经合并到master(
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
这是为什么?我如何将
主题
重设为
其他
,即使它已合并到

编辑:更新底部图表,以明确
E
F
不是相同的提交,而是引入相同的变更集

编辑2:我真正想要的是,就像我第一次创建了一个
主题
(比如
主题重定基址
)的副本,在我将
主题
合并到
其他
之前,我将其重定基址到
其他

git checkout topic
git checkout -b topic-rebased
git rebase --onto other master topic-rebased
git checkout master
git merge topic

这个很好用。但是,如果主题已经合并到
master

中,那么再基础就不再工作了。您不能期望存储库中存在
E
F
提交中的每个提交中的两个。如果它们有不同的父项(它们是这样做的:一组有
A
作为父项,另一组有
H
作为父项),那么一组
E
将与另一组不同
E

在你的情况下,如果你想得到这个结果,你应该研究:


这将把提交的
E
F
应用到当前分支中,并基本上创建它的副本。因此,您应该得到所需的结果。

如果您的历史记录与示例中的相同,则可以:

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 

它将自动找到共享的父级,并仅添加(实际上是樱桃选择)来自主题分支的提交,即使它已经合并到主级中。

好的,我已经稍微更新了这个问题。如果cherry picking不是一个选项,因为在
主题
上有100次提交,而我在
其他
上也需要提交,该怎么办?请参阅上面的编辑2,了解我真正想要的内容。我不太理解您的编辑,但是如果您需要选择多个提交(即e和F之间有更多提交),您也可以选择一个范围。例如,在
other
上,使用
git cherry pick A..topic
对topic引入的所有提交进行cherry pick。好的,但我需要手动找出从何处开始和从何处结束。不确定,我的编辑有什么不清楚的地方。下面的示例应该非常清楚:如果我在合并主题分支之前重新设置基址,它会起作用。如果我在合并主题后尝试重新设置基址,它将不再起作用。Cherry-pick和重新设置基址都通过创建新提交来重写历史。有时,cherry picking Range比重新定址更有意义,尽管我认为在这种情况下,重新定址是更好的选择(因为它不需要手动确定要复制的提交)。
% 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