代码冲突别慌:Git Conflict 实战指南

预计阅读时间:9 分钟

代码冲突别慌: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

这些按钮可以帮你快速选择保留哪一边。

但工具只是辅助。真正重要的是你要知道:

  • 当前分支是哪边
  • 合并进来的是哪边
  • 业务上应该保留什么逻辑

不要看到按钮就乱点。

尤其是涉及接口、权限、支付、数据结构时,一定要看懂再选。

代码冲突合并界面


冲突解决完,要做什么?

很多人解决完冲突就直接提交,这是不够的。

你还应该做三件事:

  1. 重新运行测试
npm test

或者:

pnpm test
  1. 检查关键功能

尤其是你刚才处理冲突的模块。

  1. 查看最终 diff
git diff --cached

确认没有误删代码,也没有把冲突标记留下来。

可以额外检查:

git grep "<<<<<<<"

如果还有输出,说明冲突标记没清干净。

这一步非常实用。


怎么减少冲突?

冲突无法完全避免,但可以明显减少。

几个习惯很有用:

  1. 开发前先同步最新主分支。
git pull origin main
  1. 分支不要拖太久。

一个 feature 分支放得越久,和主线差异越大。

  1. 一个分支只做一件事。

不要在登录分支里顺手改支付,又顺手重构用户中心。

  1. 少做无关格式化。

如果你格式化了整个文件,而同事也在改这个文件,冲突概率会暴涨。

  1. 提交前看 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 在告诉你:

这里两边都改了,我不能替你决定。

真正危险的不是冲突,而是不看懂就乱合并。

这篇文章可以总结成三个关键点:

  1. Git 冲突通常发生在两个分支修改了同一块代码时。
  2. 解决冲突的核心是删除冲突标记,并保留或重写正确代码。
  3. 解决后一定要看 diff、跑测试,确认没有把错误带进主分支。

本文由 楸木 原创,转载请注明出处。

相关推荐

发现更多