合并冲突解决指南:看懂标记、四步收尾
冲突不是错误,而是 Git 把决定权交给你。看懂那几行标记,按四步走一遍就能收尾;不确定就 --abort 重来,成本为零。
最后更新:2026-10-29
三句话理解冲突
- Git 无法自动决定两条历史对同一处的改动谁对,于是插入标记,把决定权交给你。
- 冲突只发生在把两条历史合到一起时:
merge、rebase、cherry-pick、pull。 - 冲突不是错误,而是 Git 在等你做一次「人工合并」。
下面先看冲突标记长什么样,再按四步收尾。
冲突标记长什么样
打开冲突文件,Git 会插入三段标记,把两边内容分开:
<<<<<<< HEAD
当前分支(ours)的内容
=======
要合进来的分支(theirs)的内容
>>>>>>> feature/login<<<<<<<到=======之间:你当前分支的内容(ours)=======到>>>>>>>之间:要合并进来的内容(theirs)- 解决 = 删掉这三行标记,只留下你想要的最终内容(可两边都留、改写,或只留一边)
注意:标记必须全部删除,否则会被当成普通文本提交上去。
为什么会冲突
- 同一文件的同一区域被两条历史分别修改
- 一方修改、另一方删除同一个文件
- 一方重命名、另一方继续编辑(Git 有时无法跟踪改名)
- 二进制文件(图片 / 压缩包)无法逐行合并,只能二选一
冲突数量和改动大小无关,只看两边的改动是否落在一起。
四步解决法
git status看清哪些文件处于both modified- 打开文件,定位
<<<<<<</=======/>>>>>>> - 编辑成最终内容,删掉所有标记行
git add <文件>标记已解决,再git commit(merge)或git rebase --continue(rebase)
git status # 1. 看冲突文件(both modified)
# 2-3. 编辑文件,删除 <<<<<<< ======= >>>>>>>
git add src/app.js # 4. 标记已解决
git commit # merge 收尾
# 或
git rebase --continue # rebase 收尾常用命令速查
| 命令 | 作用 |
|---|---|
| git status | 查看冲突文件(both modified) |
| git diff --name-only --diff-filter=U | 只列出尚未解决的冲突文件 |
| git checkout --ours <文件> | 整文件采用「当前分支」版本(不是只改冲突块,慎用) |
| git checkout --theirs <文件> | 整文件采用「合进来」版本(慎用) |
| git merge --abort | 放弃本次 merge,回到合并前 |
| git rebase --abort | 放弃本次 rebase |
| git merge --continue | 解决后继续 merge |
| git rebase --continue | 解决后继续 rebase |
| git mergetool | 调起图形化合并工具逐个解决 |
借助工具更快
- VS Code / JetBrains 内置三窗格冲突编辑器(Accept Current / Incoming / Both)
git mergetool调起已配置的图形合并工具git rerere记住你解决过的冲突,重复冲突自动复用git log --merge -p <文件>查看冲突双方的提交,理解各自意图
减少冲突的习惯
- 小步提交、频繁同步(早 pull 早发现)
- 功能分支短命,尽快合并回主干
- 团队统一格式化工具(Prettier / ESLint),避免纯空格差异
- 大重构提前沟通,避免多人同时改同一文件
- 用
.gitattributes统一换行符(* text=auto),避免 CRLF/LF 假冲突
常见问题
解决完冲突后怎么继续 merge / rebase?
merge:先 git add 标记已解决,再 git commit(Git 会预填合并信息)。rebase:先 git add,再 git rebase --continue。想放弃就 git merge --abort 或 git rebase --abort,回到操作前的状态。
怎么一次性列出所有冲突文件?
用 git diff --name-only --diff-filter=U(U 表示 unmerged)只列出尚未解决的冲突文件;git status 也能看到 both modified 的文件列表。
冲突解决错了怎么重来?
还在 merge / rebase 中:git merge --abort 或 git rebase --abort 直接回到操作前。已经提交了错误结果:未推送时用 git reset --hard ORIG_HEAD 退回;已推送时用 git revert 生成反向提交,别 force push 改写共享历史。