cherry-pick 是从你的cherry-pick 的父级到cherry-pick 的差异以及从你的cherry-pick 的父级到你的签出提示的差异的合并。就是这样。 Git 不需要知道更多的事情。它不关心任何提交在“哪里”,它关心合并这两组差异。
还原是还原到其父级的差异与还原到签出提示的差异的合并。就是这样。 Git 不需要再知道了。
在这里:试试这个:
git init test; cd $_
printf %s\\n 1 2 3 4 5 >file; git add .; git commit -m1
sed -si 2s,$,x, file; git commit -am2
sed -si 4s,$,x, file; git commit -am3
Run git diff :/1 :/2
and git diff :/1 :/3
。这些是当你说时 git 运行的差异git cherry-pick :/2
这里。第一个 diff 更改了第 2 行,第二个 commit 更改了第 2 行和第 4 行;第 4 行的更改不与第一个 diff 中的任何更改相邻,并且第 2 行的更改在两者中是相同的。一切都已无事可做:/1
-:/2
变化也在:/1
-:/3
.
现在,在您开始以下内容之前,让我这样说:用散文来解释这比仅仅看到更难。执行上面的示例序列并查看输出。这是much, much通过查看它比阅读任何描述更容易了解正在发生的情况。每个人都会经历一段时间,这太新了,也许一点指导会有所帮助,这就是下面段落的目的,但同样:散文本身比差异更难理解。运行差异,尝试理解您正在查看的内容,如果您需要一些帮助来解决我承诺的一个非常小的驼峰,请按照下面的文本进行操作。当它突然聚焦时,看看你是否至少在精神上拍拍你的额头并想“哇,为什么这么难看?”,就像,好吧,几乎每个人一样。
Git 的合并规则非常简单:对重叠或相邻行的相同更改将按原样接受。对已更改行的一个差异中没有更改的行的更改,或在另一行中与已更改行相邻的行,将按原样接受。不同的对任何重叠或邻接线的更改,嗯,有大量的历史需要查看,而且没有人找到一条规则可以预测每次的结果应该是什么,因此 git 声明更改冲突,转储两组结果进入文件并让您决定结果应该是什么。
那么如果现在更改第 3 行会发生什么呢?
sed -si 3s,$,x, file; git commit -amx
run git diff :/1 :/2
and git diff :/1 :/x
,你会看到,相对于cherry-pick的父级,:/2
更改了第 2 行,您的提示更改了第 2,3 和 4 行。2 和 3 相邻,从历史上看,这对于自动精灵来说太接近了,无法正确处理,所以是的,您可以这样做:git cherry-pick :/2
现在将声明冲突,向您显示对第 2 行的更改以及第 3 行和第 4 行的两个不同版本(:/2 都没有更改,您的提示都更改了,在此处的上下文中,很明显第 3 行和第 4 行的更改很好,因为-再次强调:没有人想出一个自动规则来可靠地识别此类上下文)。
您可以对此设置进行更改以测试恢复的工作原理。还隐藏弹出、合并和git checkout -m
它与您的索引运行快速临时合并。
Your git cherry-pick B^..C
是两次提交的精选,B
and C
。它会一个接一个地执行这些操作,正如上面所描述的那样。既然你已经恢复了B
and C
,然后再次挑选它们,这与应用完全相同的效果B
and C
然后挑选樱桃B
(目的是然后挑选C
)。我的结论是B
and C
触摸重叠或邻接的线,所以git diff B^ B
将显示与以下内容重叠或毗邻的变化git diff B^ C'
,这就是 Git 不会只为你选择的,因为无论这里看起来正确,在其他情况下没有人可以编写识别规则,看起来相同的选择将是错误的。所以 git 说两组更改发生冲突,你需要解决它。