当`rebase --onto`没有时,为什么`cherry-pick begin..end`会返回冲突?

时间:2017-05-02 17:29:46

标签: git

我最近在运行git cherry-pick时遇到意外冲突:

git checkout myBranch
git cherry-pick begin..end

我认为“这毫无意义”,已经中止,并尝试了我理解为等同的git rebase --onto

git rebase --onto myBranch begin end

瞧!一个干净的rebase,没有意外的冲突。

我对此感到惊讶吗?您是否认为某处存在用户错误,或者rebase --ontocherry-pick背后的流程是否会产生根本差异?

修改:在cherry-pick中,beginend是SHA。在rebase中,begin与用于cherry-pick begin的SHA相同,end是分支的名称,其中的一个是在cherry-pick的{​​{1}}提交。

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-listgit log生成的提交{{1 }}:

  

当前分支中的提交所做的所有更改,但不在&lt; upstream&gt;中被保存到临时区域。这是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-onlyHEAD..begin中的三个点)来查看我们可以采取的提交,但是决定不这样做,因为它们已经被采用(begin...HEAD)。从生成的提交列表中,我们也抛弃任何合并提交 1 --cherry-pick)。

鉴于两个双点 --no-merges 公式(X..Ybegin..HEAD生成相同的列表,并且我们开始复制提交的时间点(begin..end)也是一样的,因此行为的任何变化必须是由于省略了步骤。如果您要查看newBranch的原始提示提交并运行:

myBranch

(其中git rev-list ... | git cherry-pick --stdin 使用...三点式公式,并在所有这些之前指定--cherry-pick --right-only --no-mergesbegin 用于识别的提交它也应该正常工作,就像end所做的那样。

1 合并提交不是问题。要挑选合并,git rebase 要求您提供git cherry-pick参数。但是,如果存在任何非合并提交,-m 禁止 git cherry-pick参数。由于显然有一些非合并且没有关于-m的投诉,我们没有达成合并提交。