什么时候出现git合并冲突

时间:2017-03-09 11:01:40

标签: git merge merge-conflict-resolution

我正在使用git来跟踪我的LaTeX文档的更改。我倾向于将共同作者的反馈保留在一个单独的分支中,并在以后合并。到目前为止,事情似乎神奇地合并,但我想知道何时发生合并冲突,以便我可以在合并过程中获得一些真正的信任(我当然不希望文本出来时髦)。

StackOverflow上有很多问题似乎都提出同样的问题,但没有一个问题得到非常具体的解释。例如this answer指定如果对同一区域进行了更改就会发生冲突,但这让我想知道这些区域到底是什么。是仅仅对同一行进行了更改,还是考虑了某些上下文?

1 个答案:

答案 0 :(得分:5)

它是逐行的,答案是肯定的和是的:上下文确实很重要,但重要的数量是棘手的。它比你最初想象的要多得多。

您可能希望首先浏览this answer至相关问题,以获取背景信息。我现在假设我们有base作为(单个)合并基础(也许我们通过标记特定提交来设置名称base,例如git tag base $(git merge-base HEAD other))和HEAD作为我们的提交,使用其他一些分支名称​​ other 命名另一个提交。

接下来,我们来看两个差异:

git diff base HEAD
git diff base <other>

如果我们看到文件 F 的所有三个版本都不同(因此 F 出现在两个输出中,并且更改不同),那么我们必须在本质上,diff-hunk-by-diff-hunk。如果差异重叠,但做出不同的改变,Git宣布冲突。但是 - 这似乎是你的问题 - 究竟是什么,做出了不同的改变&#34; 意思?

我认为这是最好的例子。例如:

$ git diff base HEAD
diff --git a/basefile b/basefile
index df781c1..e4f9e4b 100644
--- a/basefile
+++ b/basefile
@@ -4,6 +4,7 @@
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
 # are met:
+# added line in b1
 # 1. Redistributions of source code must retain the above copyright
 #    notice, this list of conditions and the following disclaimer.
 # 2. Redistributions in binary form must reproduce the above copyright

$ git diff base b2
diff --git a/basefile b/basefile
index df781c1..c96620e 100644
--- a/basefile
+++ b/basefile
@@ -4,7 +4,6 @@
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
 # are met:
-# 1. Redistributions of source code must retain the above copyright
 #    notice, this list of conditions and the following disclaimer.
 # 2. Redistributions in binary form must reproduce the above copyright
 #    notice, this list of conditions and the following disclaimer in the

请注意,虽然这些更改不会触及相同的行,但从某种意义上说,他们也触摸同一行。我添加了第7行(将第7行推到第8行),然后我删除了旧行7.这些显然是&#34;相同&#34;线。所以:

$ git merge b2
Auto-merging basefile
CONFLICT (content): Merge conflict in basefile
Automatic merge failed; fix conflicts and then commit the result.

让我们中止此合并并考虑分支b3的提示(b1b3的合并基础与{{1}的合并基础相同在我的设置中)和b1

b2

这次没有冲突,即使两个 diff hunks 都触及了相同的一般区域。第二个差异删除了一条不是&#34;触及&#34;添加的行,所以Git认为这是安全的。

如果您以同样的方式进行更多实验,您会发现哪些看似重叠的变化成功合并,哪些会导致冲突。显然,直接重叠的变化(例如,在删除原始行42和插入不同的新行42的情况下)将发生冲突。但是所有的变化总是表示为&#34;删除一些现有的行,尽管可能是零&#34;接下来是&#34;添加一些新的行,但可能是零&#34;。 更改 - 即使更改,添加或删除一行中的一个单词 - 删除非零数量的现有行并添加非零数量的新行。纯删除(一个或多个完整行)添加零行,纯插入删除零行。最后,它归结为:&#34;我们和他们的变化是否触及相同的行号?&#34;上下文变得几乎无关紧要,除了当删除零行或插入零行时,上下文本身&#34;是&#34;从某种意义上说,这些线条。 (我不确定这个说法有多大意义,所以如果它不可理解,那就是我的错。;-))

(还要记住,如果您正在修改&#34;合并到目前为止&#34;文件,则在查看时必须使用原始基本文件的行号在变化是否触及&#34;相同的&#34;行。由于&#34;我们的&#34;和#34;他们的&#34;具有相同的基本版本,那&# 39;这是我们可以在这里使用的简单捷径。)

三向合并不是补丁

请注意,这与应用修补程序不同,后者在没有通用基本版本的情况下启动。在补丁的情况下,上下文使用得更多:diff hunk头提供了搜索上下文的位置,但由于它可能应用于文件的不同版本,因此上下文允许我们(和Git)只要上下文仍然匹配,就可以在不同的行进行相同的更改。

$ git merge --abort $ git diff base b3 diff --git a/basefile b/basefile index df781c1..e2b8567 100644 --- a/basefile +++ b/basefile @@ -5,7 +5,6 @@ # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. $ git merge --no-edit b3 Auto-merging basefile Merge made by the 'recursive' strategy. basefile | 1 - 1 file changed, 1 deletion(-) 实用程序在此使用不同的算法(&#34;最大模糊&#34;因子,看+/-多行)。 Git不做模糊因素;它将一直搜索到文件的开头或结尾,如果必须的话。但是,在确定上下文无法匹配之前,它通常会调整空格。

(使用patch应用修补程序时,您可以添加git apply-3以允许Git读取--3way行,这些行提供部分或完整哈希ID左边的散列ID是文件的先前版本的散列:请注意,在上面的所有差异中,index的&#34; base&#34;版本具有ID {{1}如果Git可以从该ID中找到一个唯一的blob,它可以假装这是合并库,并且只针对basefile区分一个合并库,将补丁本身视为 other < / em> diff,并以这种方式进行三向合并。这有时允许df781c1HEAD失败的情况下成功。)