Git无“树冲突”官方术语,实为文件路径与存在状态冲突,如modify/delete、rename/delete等,需依类型手动处理,预防重在规范协作与重命名操作。

Git 本身没有“树冲突(Tree Conflict)”这个官方术语。你遇到的,其实是 文件层级结构冲突,比如一个分支删了某个文件或目录,另一个分支改了它;或者两个分支对同一目录做了不同重命名、移动或拆分操作。这类冲突在 Git 中归类为 CONFLICT (modify/delete)、CONFLICT (rename/delete)、CONFLICT (add/add) 或 CONFLICT (rename/rename),它们都属于“内容冲突”的扩展形态,但根源在文件路径和存在状态,而非纯文本行。
先确认是不是真树级冲突
运行 git status,重点看输出中是否出现以下提示:
-
deleted by us:当前分支删了文件,对方分支改了它 -
deleted by them:对方分支删了文件,当前分支改了它 -
added by them和added by us同时存在同一路径:两个分支各自新增了同名文件 -
renamed+modified交叉出现:比如 A 分支把utils.js改名为helpers.js并修改内容,B 分支在原位置继续改utils.js
这些不是“三方交织”的错觉,而是 Git 明确识别出的路径操作不一致——它无法自动推断你想要保留目录结构还是代码逻辑。
按冲突类型逐个处理
不要试图用 --ours 或 --theirs 一键覆盖,它们对路径类冲突无效,甚至会破坏工作区状态。
-
modify/delete 类型:先决定语义意图。如果该文件本应保留,就恢复它:
git restore --source=HEAD --staged --worktree <file>(还原删除动作),再手动合并内容;如果确实该删,就执行git rm <file> -
add/add 类型:两个分支都新建了同名文件,说明有重复开发。检查内容差异:
git show :2:<file>( ours 版本)、git show :3:<file>( theirs 版本),选一个重命名保留,另一个git rm -
rename/rename 或 rename/modify:Git 会生成多个临时文件(如
file~HEAD、file~branch-name)。用git diff对比它们,手工整合逻辑后,用git add <final-name>告知 Git 最终路径,并git rm掉临时文件
借助 git ls-files -u 看清底层状态
当 git status 不够直观时,运行:
git ls-files -u
它会列出所有未合并条目,并标注 stage 编号:
1 = 共同祖先(base)
2 = 当前分支(ours)
3 = 待合并分支(theirs)
这对理解 rename 冲突特别有用——你能看到 Git 实际识别出的三个“版本”分别对应哪个路径。
预防胜于修复
树级冲突高发,往往暴露协作流程问题:
- 避免多人同时大规模重构目录结构;重大重命名前,先同步通知并冻结相关路径
- 用
git mv而非系统命令重命名,确保 Git 能追踪 rename 意图 - 在 PR 描述中明确写清“本次提交涉及以下文件移动/删除”,方便 Reviewer 预判冲突点
- 对长期存在的 feature 分支,定期
git rebase main(或git merge main)同步上游变更,把结构冲突分散到小步迭代中解决
不复杂但容易忽略


















