代码冲突别慌:Git Conflict 实战指南
很多程序员第一次遇到 Git 冲突,心里都会一紧。
终端里突然出现:
CONFLICT
Automatic merge failed; fix conflicts and then commit the result.
再打开文件,看到一堆奇怪标记:
<<<<<<< HEAD
=======
>>>>>>> feature/login
一瞬间,仿佛项目已经失控。
但其实,Git 冲突并不是灾难。它只是在提醒你:
同一块代码,两边都改了,Git 不知道该听谁的,需要你来决定。
这篇文章我们不讲复杂理论,直接用实战方式讲清楚:冲突为什么发生、怎么解决、如何减少冲突。
冲突为什么会发生?
假设你和同事都在改同一个文件。
原来的代码是:
const timeout = 3000;
你在 feature/login 分支里改成:
const timeout = 5000;
同事在 main 分支里改成:
const timeout = 2000;
当你把 main 合并进来,Git 就懵了。
因为它看到同一行代码被改成了两个不同结果。
这时候它不会自作主张,而是停下来让你人工判断。
常见冲突场景有:
- 两个人改了同一行
- 一个人改文件,另一个人删除文件
- 两个分支都改了同一个函数
- 重构目录结构时,别人也在改里面的文件
- 长时间不合并主分支,分支差异越来越大
冲突不是 Git 出错,而是协作过程中的正常现象。
冲突标记怎么看?
冲突发生后,Git 会在文件里插入标记:
<<<<<<< HEAD
const timeout = 3000;
=======
const timeout = 5000;
>>>>>>> feature/login
这几段分别表示:
<<<<<<< HEAD
当前分支的内容
=======
要合并进来的内容
>>>>>>> feature/login
如果你现在在 main 分支执行:
git merge feature/login
那么:
HEAD是当前main的内容feature/login是要合并进来的内容
如果你在 rebase 场景下,含义有时会让新手有点绕,但核心判断不变:
两边都是候选答案,你要选一个,或者重新写一个更正确的版本。
比如最后你决定使用 5000:
const timeout = 5000;
注意:冲突标记本身必须删除。
最终文件里不能留下:
<<<<<<<
=======
>>>>>>>
否则代码很可能直接报错。
解决冲突的标准流程
遇到冲突时,可以按这个流程来:
git status
先查看哪些文件冲突了。
然后打开冲突文件,找到 <<<<<<< 标记,人工处理。
处理完成后:
git add .
如果你是在 merge:
git commit
如果你是在 rebase:
git rebase --continue
完整流程可以记成:
看状态 -> 改冲突 -> add -> continue/commit
如果你发现冲突太乱,不想继续,也可以撤销。
Merge 场景:
git merge --abort
Rebase 场景:
git rebase --abort
这两条命令很重要。
它们能让你回到操作开始前的状态。
所以遇到冲突不用慌,Git 通常给你留了退路。
三种常见处理方式
1. 保留当前分支
如果你确认当前分支是对的,就保留 HEAD 部分。
<<<<<<< HEAD
const timeout = 3000;
=======
const timeout = 5000;
>>>>>>> feature/login
最终变成:
const timeout = 3000;
2. 保留对方分支
如果你确认对方修改更合理,就保留下面部分。
最终变成:
const timeout = 5000;
3. 两边都不要,重新写
这是最常见、也最推荐认真思考的方式。
比如你发现 3000 太短,5000 太长,可以改成:
const timeout = 4000;
解决冲突不是机械二选一,而是理解业务后给出正确代码。
用工具解决冲突会更轻松
你不一定非要在文本里手动删标记。
很多 IDE 都提供可视化冲突解决工具,比如 VS Code、IntelliJ IDEA、WebStorm。
在 VS Code 里,你通常会看到:
- Accept Current Change
- Accept Incoming Change
- Accept Both Changes
- Compare Changes
这些按钮可以帮你快速选择保留哪一边。
但工具只是辅助。真正重要的是你要知道:
- 当前分支是哪边
- 合并进来的是哪边
- 业务上应该保留什么逻辑
不要看到按钮就乱点。
尤其是涉及接口、权限、支付、数据结构时,一定要看懂再选。

冲突解决完,要做什么?
很多人解决完冲突就直接提交,这是不够的。
你还应该做三件事:
- 重新运行测试
npm test
或者:
pnpm test
- 检查关键功能
尤其是你刚才处理冲突的模块。
- 查看最终 diff
git diff --cached
确认没有误删代码,也没有把冲突标记留下来。
可以额外检查:
git grep "<<<<<<<"
如果还有输出,说明冲突标记没清干净。
这一步非常实用。
怎么减少冲突?
冲突无法完全避免,但可以明显减少。
几个习惯很有用:
- 开发前先同步最新主分支。
git pull origin main
- 分支不要拖太久。
一个 feature 分支放得越久,和主线差异越大。
- 一个分支只做一件事。
不要在登录分支里顺手改支付,又顺手重构用户中心。
- 少做无关格式化。
如果你格式化了整个文件,而同事也在改这个文件,冲突概率会暴涨。
- 提交前看 diff。
git diff
先确认自己到底改了什么。
很多冲突其实不是业务冲突,而是“顺手改太多”造成的。
命令速查表
git status
# 查看当前冲突文件
git diff
# 查看未暂存的冲突内容
git add .
# 标记冲突已解决
git commit
# merge 场景下提交合并结果
git rebase --continue
# rebase 场景下继续应用后续提交
git merge --abort
# 放弃本次 merge
git rebase --abort
# 放弃本次 rebase
git grep "<<<<<<<"
# 检查是否还有残留冲突标记
结尾:冲突不是事故,而是提醒
Git Conflict 看起来吓人,但它本质上只是 Git 在告诉你:
这里两边都改了,我不能替你决定。
真正危险的不是冲突,而是不看懂就乱合并。
这篇文章可以总结成三个关键点:
- Git 冲突通常发生在两个分支修改了同一块代码时。
- 解决冲突的核心是删除冲突标记,并保留或重写正确代码。
- 解决后一定要看 diff、跑测试,确认没有把错误带进主分支。
本文由 楸木 原创,转载请注明出处。