Git 在合并 Branch 时通常可以自动判断如何组合修改,但并不是所有情况都能自动处理。如果两个 Branch 修改了同一个文件中的同一部分内容,Git 可能无法判断应该使用哪个版本,这种情况叫做 合并冲突(Merge Conflict)。
Merge Conflict 听起来比较严重,但实际上它只是 Git 在告诉你:
“这里有两个不同的修改,我不知道你想保留哪一个,请你自己决定。”
一个简单的冲突例子
假设 main 中有这样一行代码:
const title = "Welcome";然后在 main 中,有人把它修改成:
const title = "Welcome to Git Demo";与此同时,feature/homepage 中另一个修改把同一行变成:
const title = "Welcome Back";当你尝试:
git switch main
git merge feature/homepageGit 就可能无法自动判断最终应该是:
const title = "Welcome to Git Demo";还是:
const title = "Welcome Back";于是就会停止 Merge,并提示发生 Conflict。
如何知道发生了冲突?
执行 Merge 后,如果出现冲突,Terminal 中可能看到类似:
CONFLICT (content): Merge conflict in app.js
Automatic merge failed; fix conflicts and then commit the result.这时可以先运行:
git statusGit 会列出发生冲突的文件。
例如:
both modified: app.js表示两个 Branch 都修改了 app.js,而 Git 无法自动完成合并。
冲突文件看起来是什么样?
如果直接打开发生冲突的文件,可能会看到类似:
<<<<<<< HEAD
const title = "Welcome to Git Demo";
=======
const title = "Welcome Back";
>>>>>>> feature/homepage这些符号是 Git 临时插入的冲突标记。
可以简单理解为:
<<<<<<< HEAD
当前 Branch 的代码
=======
另一个 Branch 的代码
>>>>>>> feature/homepage你的任务就是决定最终代码应该是什么。
例如你认为最终应该使用:
const title = "Welcome Back to Git Demo";那么就直接把冲突区域修改为:
const title = "Welcome Back to Git Demo";同时删除 Git 自动加入的:
<<<<<<<
=======
>>>>>>>这些冲突标记。
Conflict 决策编辑器
合并 feature/theme 触发冲突,在编辑器中删除冲突标记并保留最终样式,再 add 和 commit。
—
—
还没有 Commit
合并 feature/theme 触发冲突,在编辑器中删除冲突标记并保留最终样式,再 add 和 commit。推荐使用 VS Code 解决 Conflict
对于初学者来说,直接手动处理这些符号并不是最方便的方式。VS Code 对 Git Merge Conflict 有比较直观的可视化支持。
打开冲突文件后,VS Code 通常会帮助你区分不同版本,并提供类似这样的选择:
Accept Current Change
Accept Incoming Change
Accept Both Changes其中:
Current Change 一般表示当前所在 Branch 的版本,Incoming Change 表示正在 Merge 进来的 Branch 的版本。
如果两个版本都需要,也可以选择保留两边,然后再手动修改最终代码。
不过,不建议机械地看到按钮就直接点击。解决 Conflict 的真正目标并不是“让 Git 不再报错”,而是确认最终代码在逻辑上是正确的。
例如:
const timeout = 3000;和:
const timeout = 5000;发生冲突时,Git 不可能知道业务上应该使用 3000 还是 5000。这个决定必须由开发者来做。
解决冲突以后怎么完成 Merge?
假设已经修改好所有冲突文件,可以先查看:
git status确认哪些文件仍然处于冲突状态。
然后把已经解决的文件加入暂存区:
git add app.js如果有多个文件,也可以:
git add .完成后创建 Commit:
git commit -m "Resolve merge conflict"这时 Merge 就完成了。
整个流程可以概括成:
git merge → 发生 Conflict → 找到冲突文件 → 决定最终代码 → 删除冲突标记 → git add → git commit
知识测验
一个非常重要的习惯:解决后要测试
Conflict 解决完成,并不代表代码一定正确。
例如你可能成功合并了两个版本,但最终代码出现:
const timeout = 3000;
const timeout = 5000;Git 可能认为冲突已经解决,因为冲突标记已经被删除,但 JavaScript 本身可能已经出现逻辑或语法问题。
因此,处理完 Conflict 后应该运行项目或测试相关功能,确认代码可以正常工作。
如果不想继续这次 Merge 怎么办?
如果刚发生 Conflict,还没有解决,而你发现这次 Merge 做错了,可以取消本次 Merge:
git merge --abortGit 会尽量把 Repository 恢复到开始 Merge 之前的状态。
对于初学者来说,这个命令非常实用。如果你发现冲突太复杂,或者意识到 Merge 了错误的 Branch,可以先:
git merge --abort回到之前的状态,再重新确认应该怎么处理。
练习
合并时 app.js 同一行发生 Conflict。请写出从确认冲突文件、手动解决、检查标记、暂存到完成 Merge Commit 的具体步骤与命令。