冲突并不是单纯看“是不是同一行”,而是 Git 在尝试三方合并(three-way merge)时,无法自动决定最终内容时就会触发冲突。我们具体拆开看:

1. Git 的三方合并原理

当你合并两个分支时,Git 会找出三份文件进行比较:
  • 共同祖先(Base):两个分支分开前的版本。
  • 当前分支(Local / HEAD):你现在所在分支的内容。
  • 合并来源分支(Remote / MERGE_HEAD):你要合并进来的分支内容。
Git 会把 Base → LocalBase → Remote 的差异应用到一起。如果某个地方的改动能自动合并(比如 A 改了一行,B 改了另一行),就不会冲突;如果 Git 无法确定要保留哪一个结果,就会冲突。

2. 删除操作的特殊性

删除并不像“修改文本”那么直观。举个例子:
Base(共同祖先):
分支 A:
(删除了第二行)
分支 B:
(删除了第一行)

3. 为什么会冲突?

  • 对于 分支 A 来说:它告诉 Git“第二行已经被删除”。
  • 对于 分支 B 来说:它告诉 Git“第一行已经被删除”。
这两个改动看似“互不干扰”,但是从 Git 的角度,合并结果应该是什么?
  • 结果可能是“两个都删除”(得到一个空文件)。
  • 也可能是“只保留第一行”。
  • 也可能是“只保留第二行”。
Git 没法自动判断你的真实意图。它不知道你是不是希望两个删除叠加,还是希望保留其中之一。为了避免出错,Git 会触发冲突,把选择权交给你。

4. 实际冲突文件会长这样

这就表示:
  • 上半部分是你当前分支(HEAD)的结果。
  • 下半部分是你合并进来的分支(branchB)的结果。
  • 你需要手动决定最终要保留哪一部分,还是都删掉。

5. 规律总结

  • 不同文件 → 永远不会冲突。
  • 同一文件不同区域(完全不重叠) → 一般不会冲突,Git 会自动合并。
  • 同一文件同一区域(包括删除、修改重叠) → 有可能冲突,需要你手动解决。
删除和修改都是对“同一区域的不同处理”,Git 无法自动合并,就会触发冲突。
 

6.删除修改冲突

文件 intro.txt 内容如下(共同祖先版本):
分支 A:修改
(修改了第一行为My name is Xiao Hong.)
分支 B:删除
(删除了第一行)
  • 合并时 Git 怎么看?
    • 共同祖先My name is Xiao Ming.
    • 分支 A:这一行被修改为 "My name is Xiao Hong."
    • 分支 B:这一行被删除了。
  • Git 面临的问题:
    • 按照分支 A 的意图:应该保留 "My name is Xiao Hong."
    • 按照分支 B 的意图:这一行不应该存在。
  • Git 没法自动判断
    • 是不是 B 删除之前,A 也觉得这行没必要?
    • 还是 A 改完之后,这行其实很重要,不能删?
结果:产生冲突。

  • 合并冲突文件长什么样?
Git 会生成这样的冲突标记:
你需要手动决定:
  • 保留修改(留下 "My name is Xiao Hong."),
  • 还是按删除来处理(删除整行),
  • 或者做新的编辑(比如换成 "My name is ...", 你重新写)。

 
Loading...