Skip to content
Chapter 06

冲突处理

合并冲突是协作开发中不可避免的挑战。本章将带你理解冲突的本质,掌握手动解决冲突的完整流程,以及进阶工具与最佳实践。

理解冲突

什么是合并冲突?为什么会发生?
当两个分支修改了同一文件的同一位置时,Git 无法自动决定保留哪个版本,就会产生合并冲突(Merge Conflict)。Git 会暂停合并过程,将冲突标记写入文件,等待你手动裁决。

常见触发场景:
  • 两人同时修改了同一函数的实现
  • 一个分支新增了代码,另一个分支在同一行删除了代码
  • 两个分支对同一行做了不同的修改
冲突标记 <<<<<<<、=======、>>>>>>> 分别代表什么?
Git 在冲突文件中插入三种标记来划分冲突区域:
<<<<<<< HEAD
当前分支的内容(你所在的分支)
=======
被合并分支的内容
>>>>>>> feature
  • <<<<<<< HEAD 到 ======= 之间 —— 当前分支(HEAD)的内容
  • ======= 到 >>>>>>> branch-name 之间 —— 被合并分支的内容
你需要决定保留哪一侧,或者将两侧内容合并为新的正确版本。
如何手动解决冲突?
手动解决冲突的步骤:
  1. 打开冲突文件,找到 <<<<<<< / ======= / >>>>>>> 标记
  2. 删除这些标记,保留正确的内容(可以选择保留一侧、两侧合并、或完全重写)
  3. 保存文件后,使用 git add <file> 标记该冲突已解决
  4. 使用 git commit 完成合并提交
解决冲突后应该做什么?
解决所有冲突后:
  1. git add <已解决的文件> —— 告诉 Git 该文件的冲突已处理完毕
  2. git commit —— 完成合并提交。Git 会自动生成合并提交信息(Merge commit message),通常无需手动编辑
提示
如果所有冲突文件都已 add,直接 git commit 即可,无需加 -m 参数。Git 会打开编辑器让你确认自动生成的合并消息,保存退出即可。

冲突进阶

如何取消正在进行的合并?
如果合并冲突过于复杂,你想放弃这次合并回到合并前的状态,可以使用:
git merge --abort
该命令会将工作区和暂存区恢复到合并开始前的状态,就像合并从未发生过一样。

注意
git merge --abort 只能在合并冲突期间使用(即合并尚未完成时)。如果你已经执行了 git add 并 git commit,合并已完成,此时需要用 git reset 来回退。
如何使用可视化合并工具?
git mergetool 可以启动可视化的三方合并工具来帮助你解决冲突。常见的工具有 vimdiff、VS Code、Beyond Compare 等。

配置合并工具:
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
配置完成后,遇到冲突时运行 git mergetool,Git 会自动打开你配置的工具,以分栏方式展示本地版本、基础版本和远程版本,让你直观地选择保留哪些内容。
二进制文件(图片、字体等)冲突怎么处理?
二进制文件无法像文本一样手动编辑冲突标记,你必须选择保留某个版本:
# 保留当前分支(HEAD)的版本
git checkout --ours image.png

# 保留被合并分支的版本
git checkout --theirs image.png

# 标记冲突已解决
git add image.png
选择后 git add 即可标记该冲突已解决。
理解 --ours 与 --theirs
在合并场景中:--ours 指的是你当前所在的分支(HEAD),--theirs 指的是被合并进来的分支。注意在 rebase 场景下含义会反转。
如何减少冲突发生的频率?
冲突无法完全避免,但可以通过以下实践显著降低频率:
  1. 频繁 pull —— 经常从远程拉取最新代码,保持本地分支与团队同步
  2. 小粒度 commit —— 每次提交只做一件事,减少修改范围
  3. 团队约定文件所有权 —— 不同开发者负责不同模块,避免多人修改同一文件
  4. 充分沟通 —— 在动手修改公共代码前,与团队成员确认意图
  5. 拆分大功能 —— 将大功能拆为多个小分支逐步合并,而非一次性合并大量改动
冲突解决练习
欢迎来到冲突解决练习!按步骤操作解决合并冲突。
$