diff3 样式解决什么问题
默认的 merge 冲突样式只给出 ours 与 theirs 两段内容,看不出双方相对共同祖先各改了什么,改动一复杂就只剩靠猜。diff3 样式会在冲突块里额外插入一段以六个竖线标记的共同祖先(base)内容,让你直接对照基线判断双方意图,从而更准确地取舍。它由 merge.conflictStyle 配置控制,对 git merge 与 git rebase 产生的冲突同样生效;这属于客户端呈现设置,不改变仓库里的历史与数据,任何平台、任何 Git 客户端都能用。
基本信息
| 配置键 | merge.conflictStyle |
|---|---|
| 取值 | merge(默认)/ diff3 / zdiff3(Git 2.35+) |
| 作用范围 | 全局 / 单仓库 / 单次 -c 覆盖 |
| 生效时机 | 合并或变基写入冲突文件时 |
| 平台 | 任意 Git 客户端,与操作系统无关 |
典型使用场景
- 同一函数被双方分别改动,需要判断各自改动的语义差异
- 变基时同一处冲突反复出现,用 base 段快速确认原始实现
- 合并长期分叉的配置文件或锁文件,避免把基线内容当成结果
- 向新人讲解三方合并原理,冲突文件本身就是最直观的教材
- 复现评审中提到的冲突场景,用 base 段核对对方的结论是否站得住
- 排查「谁把这段代码改成这样」时,用 base 段把两边改动的先后关系理顺
配置与冲突块形态
配置与冲突块形态
git config --global merge.conflictStyle diff3 # 全局启用 diff3 样式
git config merge.conflictStyle zdiff3 # 本仓库改用 zdiff3
git -c merge.conflictStyle=diff3 merge origin/main # 单次生效
# 冲突文件里的段落顺序:
# <<<<<<< HEAD ... ours ...
# ||||||| base ... 共同祖先 ...
# ======= ... theirs ...
# >>>>>>> 分支名冲突标记逐段读法
| 标记 | 含义 |
|---|---|
| <<<<<<< HEAD | 当前分支(ours)一侧内容,直到下一个标记为止 |
| ||||||| base | diff3 独有,共同祖先中的原始内容 |
| ======= | 分隔线,之后为对方版本 |
| >>>>>>> 分支名 | 被合并或重放的对方(theirs)一侧内容 |
三种取值各有取舍:merge 冲突段最短,适合简单冲突;diff3 信息最全但段落更长,复杂冲突才划得来;zdiff3 会把两方相同的行收进 base 段,冲突块更紧凑,Git 2.35 起可用。
可与 rerere 配合:开启 rerere.enabled 后 Git 会记录你解决过的冲突,同一冲突再次出现时自动套用旧方案。diff3 帮你看清楚,rerere 帮你少重复,两者互补,适合长期维护同一分支的场景。
解决冲突的推荐顺序
- 先 git status 确认冲突文件清单与当前所处状态(合并还是变基)
- 逐个文件读 ours、base、theirs 三段,判断每处该保留哪一方
- 处理完删净所有标记,git add 标记为已解决
- 全部解决后提交或 git rebase --continue,再跑一次测试确认行为