我最近在运行git cherry-pick
时遇到意外冲突:
git checkout myBranch
git cherry-pick begin..end
我认为“这毫无意义”,已经中止,并尝试了我理解为等同的git rebase --onto
:
git rebase --onto myBranch begin end
瞧!一个干净的rebase,没有意外的冲突。
我对此感到惊讶吗?您是否认为某处存在用户错误,或者rebase --onto
和cherry-pick
背后的流程是否会产生根本差异?
修改:在cherry-pick
中,begin
和end
是SHA。在rebase
中,begin
与用于cherry-pick
begin
的SHA相同,end
是分支的名称,其中的一个是在cherry-pick
的{{1}}提交。
答案 0 :(得分:1)
TL; DR一行摘要:git rebase
省略了任何已经选择过的提交。
git rebase
份副本并不是您的想法。 (我承认我猜测你在这里的想法......但如果结果出人意料,那一定是真的。)
根据the documentation [--onto newbase] upstream [branch]
,正式论证是正确的。那就是:
git rebase --onto myBranch begin end
表示end
被视为分支名称:
git checkout end
之后,根据文档(但它位于),提交的提交是由git rev-list
或git log
生成的提交{{1 }}:
当前分支中的提交所做的所有更改,但不在< upstream>中被保存到临时区域。这是
upstream..HEAD
所显示的同一组提交;或git log <upstream>..HEAD
,如果git log 'fork_point'..HEAD
有效(请参阅下面--fork-point
的说明);如果指定了--fork-point
选项,则按git log HEAD
。
--root
或--fork-point
选项都不适用,所以我们留下:
--root
由于git log begin..HEAD
现在引用HEAD
,因此 与end
相同。但是,正如我刚才所说,文档存在!好吧,至少一点点。然后纠正要说的话:
请注意,HEAD中的任何提交都会引入与HEAD中的提交相同的文本更改。&lt; upstream&gt;被省略......
此处还应提及begin..end
也省略了合并提交。我们实际需要的是更复杂的:
git rebase
(注意三个点而不是两个点)。也就是说,我们检查git rev-list --cherry-pick --right-only --no-merges begin...HEAD
,以查找可能采用的提交(begin..HEAD
);但是我们会查看--right-only
(HEAD..begin
中的三个点)来查看我们可以采取的提交,但是决定不这样做,因为它们已经被采用(begin...HEAD
)。从生成的提交列表中,我们也抛弃任何合并提交 1 (--cherry-pick
)。
鉴于两个双点 --no-merges
公式(X..Y
和begin..HEAD
)将生成相同的列表,并且我们开始复制提交的时间点(begin..end
)也是一样的,因此行为的任何变化必须是由于省略了步骤。如果您要查看newBranch
的原始提示提交并运行:
myBranch
(其中git rev-list ... | git cherry-pick --stdin
使用...
三点式公式,并在所有这些之前指定--cherry-pick --right-only --no-merges
和begin
用于识别的提交它也应该正常工作,就像end
所做的那样。
1 合并提交不是问题。要挑选合并,git rebase
要求您提供git cherry-pick
参数。但是,如果存在任何非合并提交,-m
禁止 git cherry-pick
参数。由于显然有一些非合并且没有关于-m
的投诉,我们没有达成合并提交。