我正在使用git来跟踪我的LaTeX文档的更改。我倾向于将共同作者的反馈保留在一个单独的分支中,并在以后合并。到目前为止,事情似乎神奇地合并,但我想知道何时发生合并冲突,以便我可以在合并过程中获得一些真正的信任(我当然不希望文本出来时髦)。
StackOverflow上有很多问题似乎都提出同样的问题,但没有一个问题得到非常具体的解释。例如this answer指定如果对同一区域进行了更改就会发生冲突,但这让我想知道这些区域到底是什么。是仅仅对同一行进行了更改,还是考虑了某些上下文?
答案 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
的提示(b1
和b3
的合并基础与{{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,并以这种方式进行三向合并。这有时允许df781c1
在HEAD
失败的情况下成功。)