首页 > 解决方案 > Git合并冲突-“以不同方式更改同一文件的同一部分”是什么意思?

问题描述

Git书的第3.2章指出:

…有时,这个过程并不顺利。如果您在要合并的两个分支中以不同方式更改了同一文件的同一部分,Git 将无法干净地合并它们。...

应如何解释模棱两可的“以不同方式更改同一文件的同一部分”表达式?Git 是否在跨分支的冲突文件中内部执行逐行比较?


示例

假设在分支L上,我在 README.md 的开头添加了一个额外的换行符。这是否意味着在与其他分支R上的 README.md 的第一行不同的任何行上的修改会在合并时触发冲突?

您会期望一个简单的逐行比较会失败,因为所有行都已在L中移动了一个位置,而R中的一些行保持不变。

标签: gitversion-control

解决方案


请记住,Git 做的不是一个,而是两个diff:

  • 有一个包含一些文件的合并基础提交B
  • 以及带有一些文件的左侧L提交,
  • 以及带有一些文件的右侧R提交。

两个命令中的合并基础B相同: git diff

git diff --find-renames <hash-of-B> <hash-of-L>    # what we changed
git diff --find-renames <hash-of-B> <hash-of-R>    # what they changed

所以,假设我们和他们都修改了 file F.ext。从第一个 diff 中可以清楚地看出我们F.ext 更改了哪些行:在关于 B 的 diff hunk 中列为已删除的行,加上在边缘的另一条“中间”行以确保安全 - 边缘向前,所以如果我们替换原来的第 3 行,我们“触及”了第 3 行和“3 和半”。如果我们没有删除任何行——如果我们在第 4 行之前的第 3 行之后插入了一行——那么我们触及了“3-and-a-half”行。

同时,从第二个差异中也可以清楚地看出F.ext 它们改变了哪些行。同样的规则适用:如果他们用替换的第 3 行替换了原来的第 3 行,那么他们触及了第 3 行(包括“3.5”行)。因此,如果我们触及第 3 行或第 3.5 行,就会发生冲突。否则,不存在冲突:Git 可以从对相关行进行更改的任何一方获取更改。

(请注意,git diff将差异表示为统一的上下文差异。合并代码使用原始的、非统一的差异。因此它有一个列表,上面写着“在原始的X行,删除D行并插入新的替换行”,其中至多DI中​​的一个可以为零。触摸跨度是X线到X线+ D+ 0.5,或多或少。以我奇怪的“加半”,我真的只是在这里大力挥手掩盖空跨度问题,这一个问题。您必须尝试使用​​ Git 才能准确了解它在每种情况下的作用。)


推荐阅读