为什么这个樱桃挑选有冲突?

时间:2016-08-10 05:25:19

标签: git cherry-pick git-cherry-pick

我知道git cherry-pick是一个用于应用指定提交更改的命令,但我想我真的不了解它的工作方式。

让我们说一个像这样的回购:

git init

echo a>a
git add .; git commit -am 'master add line a'

git checkout -b dev
echo b>>a
git commit -am 'dev add line b'
echo c>>a
git commit -am 'dev add line c'

git checkout master

git cherry-pick dev

我认为cherry-pick命令可以正常运行并将文件a更改为:

a

c

但实际上我得到了以下信息:

error: could not apply 08e8d3e... dev add line c
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

然后我跑:

git diff

输出:

diff --cc a
index 7898192,de98044..0000000
--- a/a
+++ b/a
@@@ -1,1 -1,3 +1,6 @@@
  a
++<<<<<<< HEAD
++=======
+ b
+ c
++>>>>>>> 11fff29... abc

所以我的问题是:为什么会出现像git-diff这样的冲突?在这种情况下,樱桃挑选工作的细节是什么?

2 个答案:

答案 0 :(得分:21)

在之后再次尝试

git config merge.conflictstyle diff3

您将获得更详细的差异:

<<<<<<< HEAD
||||||| parent of 5b2a14c... dev add line c
b
=======
b
c
>>>>>>> 5b2a14c... dev add line c

它表明,当应用由dev的HEAD(bc)表示的补丁时,Git不知道共同的祖先;它推迟到:

  • 挑选出来的提交的直接父级(显示它在一行&#39; c&#39;)之后添加一行&#39; b&#39; / LI>
  • 目标提交(根本没有显示行b,可以应用添加的更改&#39; c&#39;)

因此发生冲突。

Cherry-pickingmerge不同(寻找merge-base)。

Cherry-picking接受提交,应用它引入的更改

此处引入的更改是:在c之上添加b 并且目标提交根本没有b,因此对于Git:

  • 上游(目的地)提交已删除b&#34; (或者从来没有把它放在首位,这就是这种情况,但Git不知道),
  • 源代码提交有一个b,其中添加了c

Git知道什么时候尝试应用该补丁(这就是所有git cherry-pick所做的:应用补丁。它根本不会查找樱桃挑选提交的历史记录),这是一个冲突:并发修改。

如果你确定分辨率的方式,你可以这样做:

> git cherry-pick -Xtheirs dev
[master 7849e0c] dev add line c
 Date: Wed Aug 17 08:25:48 2016 +0200
 1 file changed, 2 insertions(+)

然后,您会看到bc添加到原始提交中,没有任何冲突(因为您已指明如何使用选项&#39; -Xtheirs&#解决此问题39;传递给default merge strategy recursive

答案 1 :(得分:-1)

从技术上讲,由于您在不同分支上编辑同一文件的同一行,因此Git将此视为冲突。 Cherrypicking虽然在技术上不是“合并”操作,但仍会查找相同类型的冲突并要求您解决它们。

  

对于冲突路径,索引文件最多可记录三个版本,如git-merge [1]的“TRUE MERGE”部分所述。工作树文件将包括由通常的冲突标记&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;和&gt;&gt;&gt;&gt;&gt;&gt;&gt;。

来自git-scm documentation