我知道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这样的冲突?在这种情况下,樱桃挑选工作的细节是什么?
答案 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(b
和c
)表示的补丁时,Git不知道共同的祖先;它推迟到:
c
&#39;)之后添加一行&#39; b
&#39; / LI>
b
,可以应用添加的更改&#39; c
&#39;)因此发生冲突。
Cherry-picking与merge不同(寻找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(+)
然后,您会看到b
和c
添加到原始提交中,没有任何冲突(因为您已指明如何使用选项&#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;。