Git篇(7):Git 检测差异的原理——为什么合并会出现冲突

Git 在检测差异时,不是像 Word 那样按"字节对比",也不是按"行号硬比对",而是用 最长公共子序列(LCS, Longest Common Subsequence)算法 来找出改动区域(diff hunk)。

流程可以这样理解:

  1. 找到两个版本的文件(来自不同 commit 的 blob)。
  2. 用 LCS 算法比对两份文本,定位哪些行相同、哪些行不同。
  3. 把不同的地方划分成"差异块 hunk" 。
  4. 输出成 diff 格式,再用于 merge 或显示。

👉 所以,Git 的差异检测是基于"行内容 + 相邻上下文",不是行号。


可视化:差异检测的例子

假设共同祖先版本(C2):

css 复制代码
A
B
C
D
E

远程提交(C3)改了 B → B':

css 复制代码
A
B'
C
D
E

本地提交(C4)改了 D → D':

css 复制代码
A
B
C
D'
E

第一步:找共同祖先

C2 就是共同祖先(A-B-C-D-E)。


第二步:算 diff

  • C2 → C3 的 diff:
css 复制代码
- B
+ B'
  • C2 → C4 的 diff:
diff 复制代码
- D
+ D'

第三步:定位差异块

Git 会生成两个差异块(hunk):

  • hunk1:涉及 B 的改动
  • hunk2:涉及 D 的改动

第四步:合并

Git 尝试把 hunk1 和 hunk2 应用到 C2:

  • hunk1 改 B → B'
  • hunk2 改 D → D'

结果合并后:

css 复制代码
A
B'
C
D'
E

👉 自动合并成功,因为两个 hunk 不重叠。


冲突的例子

共同祖先(C2):

css 复制代码
A
B
C

远程提交(C3):B → X

css 复制代码
A
X
C

本地提交(C4):B → Y

css 复制代码
A
Y
C

diff

  • C2 → C3 的 diff: - B + X
  • C2 → C4 的 diff: - B + Y

hunk 对比

Git 发现两个 diff 都作用在同一个位置(B),修改冲突,无法自动决定保留 X 还是 Y。

于是标记冲突:

markdown 复制代码
A
<<<<<<< HEAD
Y
=======
X
>>>>>>> origin/main
C

Git 的差异检测原理总结

  1. 基于 LCS 算法,找出文件两版本的最长公共子序列。

  2. 把"非公共部分"标记为差异块(hunk)。

  3. 合并时:

    • 如果 hunk 不重叠 → 自动合并
    • 如果 hunk 重叠 → 冲突

总结与比喻

Git 检测差异就像两个人修改一本书:

  • Git 会先找到书里大家都没改过的段落(LCS)("行"是比较的最小单位);
  • 把大家改动的部分标记出来(hunk)(连续的差异行);
  • 如果改动在不同段落,直接合并;
  • 如果改动在同一行文字,Git 没法替你做决定,就报冲突。

在此强调,从头到尾,都不涉及"行号"的比较,这是误解的根源。


相关推荐
Winlifes3 天前
我给 Codex 做了一个 Git 面板:分支树、提交历史和工作区操作
git
郑州光合科技余经理4 天前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
我命由我123454 天前
Git 推送报错:error: src refspec main does not match any
运维·git·gitee·github·运维开发·学习方法·版本控制
Lcr3s4 天前
Git基础之(0):如何在Ubuntu(Linux)上安装git
git
玄芯散人5 天前
【筑基·058】Git协作工作流:冲突解决和PR流程
git·版本控制·团队协作
寺中人5 天前
Git 版本控制完全入门指南:从安装到实战,提交 + 分支 + 协作 + 冲突解决全拆解
git·开发工具·版本控制·团队协作·代码管理
荔枝梅梅5 天前
新手程序员 SSH 第一课:从 Git 仓库连接失败理解 SSH 协议与密钥配置
git
玄芯散人5 天前
【筑基·057】Git代码时光机:版本控制入门到分支管理
git·版本控制·嵌入式开发
szephyr6 天前
Git 分支管理实战:feature/release/hotfix 怎么用才不乱
git·分支管理·团队协作·工作流·hotfix
一木 之林6 天前
手搓家庭服务器:二手装机、Docker部署、端口映射与frp内网穿透
服务器·人工智能·git·编辑器