Git 冲突解决完全指南:merge 冲突场景与解决方法
Introduction
Git 冲突是团队协作中不可避免的问题。当两个分支对同一文件的同一位置进行了不同的修改,Git 无法自动合并时,就会产生冲突。正确处理冲突是每个开发者必须掌握的技能。本文全面介绍 Git 冲突的成因、检测方法以及多种场景下的解决方案。
基础语法
# 触发合并操作(可能产生冲突)
git merge <分支名>
git pull # pull = fetch + merge
git pull --rebase # pull + rebase
冲突发生后的处理
git status # 查看冲突文件(红色 Unmerged)
git diff # 查看冲突详情
git diff --name-only --diff-filter=U # 只列出冲突文件
解决冲突
git add <文件> # 标记为已解决
git commit # 完成合并提交
放弃合并
git merge --abort # 取消合并,恢复合并前状态
rebase 冲突处理
git rebase --continue # 解决冲突后继续变基
git rebase --abort # 取消变基,恢复原状态
使用工具解决冲突
git mergetool # 调用可视化合并工具
常见工具:kdiff3, meld, beyond compare, vscode 等</code></pre>
完整代码示例
# ===== Git 冲突解决实战 =====
1. 准备:创建两个分支,制造冲突场景
git init conflict-demo && cd conflict-demo
echo "第一行代码" > main.py
git add . && git commit -m "init main.py"
2. 创建分支 A,修改第三行
git checkout -b feature-a
echo "功能A:添加日志" >> main.py
echo "功能A:记录时间" >> main.py
git add . && git commit -m "feat: add logging"
3. 切回主分支,创建分支 B,修改第三行(同一位置不同修改)
git checkout master
echo "功能B:添加缓存" >> main.py
echo "功能B:清除缓存" >> main.py
git add . && git commit -m "feat: add cache"
4. 将分支 A 合并到主分支(正常合并,无冲突)
git merge feature-a
输出:Merge made by the ort strategy.
5. 现在将分支 B 合并到主分支(将产生冲突)
git merge feature-b
输出:Auto-merging main.py
CONFLICT (content): Merge conflict in main.py
Automatic merge failed; fix conflicts and then commit the result.
6. 查看冲突状态
git status
输出:both modified: main.py
7. 查看冲突文件的完整内容
cat main.py
输出:
第一行代码
功能A:添加日志
功能A:记录时间
<<<<<<< HEAD
功能B:添加缓存
功能B:清除缓存
=======
功能A:添加日志
功能A:记录时间
>>>>>>> feature-b
8. 手动解决冲突:保留需要的部分
假设我们要保留 A 的日志和 B 的缓存,编辑后:
cat > main.py << 'ENDOFFILE'
第一行代码
功能A:添加日志
功能A:记录时间
功能B:添加缓存
功能B:清除缓存
ENDOFFILE
9. 标记冲突已解决并提交
git add main.py
git commit -m "merge: resolve conflict, keep both features"
10. 删除功能分支
git branch -d feature-a
git branch -d feature-b
===== 另一种场景:rebase 冲突 =====
重新创建场景
git checkout -b feature-x
echo "X功能第一部分" >> feature.txt
git add . && git commit -m "feat: part 1"
git checkout master
echo "主分支修改" >> feature.txt
git add . && git commit -m "chore: main update"
切回 feature-x 并变基到 master
git checkout feature-x
git rebase master
可能产生冲突:CONFLICT (content) in feature.txt
解决冲突后继续
git add feature.txt
git rebase --continue
如果提交信息不需要修改,保存退出即可
===== 使用 mergetool 可视化解决 =====
git mergetool
会打开配置的合并工具,逐个文件解决冲突
echo "冲突解决完成!"
常见问题
Q1: 冲突标记是什么?
这些是 Git 自动插入的冲突标记。<<<<<<< HEAD 和 ====== 之间是当前分支(你所在的分支)的内容;======= 和 >>>>>>> 之间是待合并分支的内容。解决冲突就是删除这些标记,保留你想要的代码。
Q2: 多人协作时如何减少冲突?
几个最佳实践:1)频繁 git pull --rebase 同步远程更新,尽早发现冲突;2)团队约定不同模块由不同人负责,减少同时修改同一文件的情况;3)使用短分支工作流,功能完成后尽快合并;4)提交前用 git diff 检查自己的修改。
Q3: 放弃当前合并如何操作?
在 merge 过程中:git merge --abort 可以完全取消合并,恢复到合并前的状态。
在 rebase 过程中:git rebase --abort 可以取消变基,恢复到变基前的状态。
注意:如果冲突已经解决并 add 之后,abort 可能无法完全恢复,需要用 git reset --hard HEAD。
Q4: 冲突文件太多,如何批量处理?
可以用 git diff --name-only --diff-filter=U 列出所有冲突文件。然后逐个或并行处理。对于同类冲突(如都需要保留某一方的修改),可以写脚本批量处理:git checkout --ours/--theirs <文件> 快速选择某一方的版本,再用 git add 标记解决。
延伸阅读
- 分支的合并 - 官方文档
- 高级合并技巧 - 包括 subtree、ort 算法等
- VSCode GitLens - 可视化冲突解决工具