冲突并不是单纯看“是不是同一行”,而是 Git 在尝试三方合并(three-way merge)时,无法自动决定最终内容时就会触发冲突。我们具体拆开看:
1. Git 的三方合并原理
当你合并两个分支时,Git 会找出三份文件进行比较:
- 共同祖先(Base):两个分支分开前的版本。
- 当前分支(Local / HEAD):你现在所在分支的内容。
- 合并来源分支(Remote / MERGE_HEAD):你要合并进来的分支内容。
Git 会把
Base → Local 和 Base → 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 ...", 你重新写)。


