在完成https://learngitbranching.js.org之后,我认为我有了樱桃挑选的想法,但结果证明我根本没有。
我创建了一个文件undefined
并进行了如下提交:
abc.txt
由(write a) ← (write b) ← (write c)[master][HEAD]
成为:
abc.txt
现在,在a
b
c
上创建分支from-a
:
(write a)
和樱桃采摘(write a)[from-a][HEAD] ← (write b) ← (write c)[master]
,我认为它会使(write c)[master]
只包含一行和一行,即
abc.txt
但实际上是因为:
a
c
这里我的困惑是两折的。为什么它会冲突而不只是添加线?为什么它包含b-line,尽管我只挑选了a
<<<<<<< HEAD
=======
b
c
>>>>>>> 3a0882d... write c
?
答案 0 :(得分:6)
Git具有上下文感知功能,可以查找周围的行以及添加/删除的行。
这是有道理的,因为git需要知道应该从提交更改的位置。
在您的情况下,分支from-a
具有内容
a
周围的行是空的。
您尝试挑选的提交具有以下内容:
diff --git a/abc.txt b/abc.txt
index 422c2b7..de98044 100644
--- a/abc.txt
+++ b/abc.txt
@@ -1,2 +1,3 @@
a
b
+c
即使提交消息在添加/删除的行周围显示更宽的上下文,git也只会尝试匹配上面的一行和修改下面的一行。 (谢谢das-g)
这意味着git会尝试找到这一行:
b
在文件末尾并插入行
c
之后。
由于您的分支from-a
(当前HEAD
),git无法找到该行
b
在文件的末尾,因此无法干净地应用您的补丁,从而导致冲突。
文字
<<<<<<< HEAD
=======
b
c
>>>>>>> 3a0882d... write c
表示git看到文件末尾的实际内容为空的冲突,由
表示<<<<<<< HEAD
=======
但是git希望找到这一行
b
为了添加行
c
之后表示
=======
b
c
>>>>>>> 3a0882d... write c
这样就可以解决冲突并决定如何加入这两种状态。
如果您遇到冲突,请始终在<<<<<<< HEAD
和>>>>>>>
的对之间查找代码。
在它们之间,你将=======
分隔当前HEAD
的状态和应用补丁后git预期的状态。
答案 1 :(得分:1)
cherry-pick是一个合并。
提交c
与c
基本提交不同,它添加了行c
。
提交a
也与c
的基本提交不同,它会删除行b
。
file [b]
----
a
b
file [a] file [c]
---- ----
a a
b
c
由于两个变化重叠,Git假定受影响的行可能是相关的,因为源代码中的语义实体通常占用多个行,您可能在一个更改中添加到实体并在另一个行中删除整个实体,行{ {1}}可能以某种方式与行c
相关,如果您要删除b
,则可能也不想添加b
。