Appearance
Git 冲突解决
冲突解决是Git协作开发中的重要技能。本章详细介绍冲突的产生原因、解决方法和最佳实践。
冲突基础概念
什么是冲突
当Git无法自动合并两个分支的更改时,就会产生冲突。冲突通常发生在两个分支修改了同一文件的同一部分。
冲突产生的场景
- 合并分支时:两个分支修改了同一文件的同一部分
- 变基操作时:变基过程中遇到冲突
- 拉取代码时:本地更改与远程更改冲突
- 樱桃拣选时:拣选的提交与当前分支冲突
bash
# 演示冲突产生
# 分支A修改了文件的第10行
# 分支B也修改了文件的第10行
# 合并时会产生冲突
识别冲突
查看冲突状态
bash
# 查看冲突文件
git status
# 查看冲突文件内容
git diff
# 查看冲突的详细信息
git log --merge
冲突标记
冲突文件中会包含特殊的标记:
text
<<<<<<< HEAD
当前分支的内容
=======
要合并分支的内容
>>>>>>> branch-name
手动解决冲突
基本解决步骤
bash
# 1. 查看冲突文件
git status
# 2. 编辑冲突文件,移除冲突标记
# 保留需要的内容,删除冲突标记
# 3. 添加解决后的文件
git add conflicted-file.txt
# 4. 完成合并
git commit
冲突解决策略
bash
# 保留当前分支的内容(HEAD)
git checkout --ours conflicted-file.txt
# 保留合并分支的内容
git checkout --theirs conflicted-file.txt
# 重置到合并前状态
git merge --abort
# 使用特定版本的内容
git show HEAD:conflicted-file.txt > conflicted-file.txt
使用工具解决冲突
配置合并工具
bash
# 配置Vim作为合并工具
git config --global merge.tool vimdiff
git config --global mergetool.vimdiff.cmd 'vim -d -c "set diffopt=filler,iwhite" "$LOCAL" "$REMOTE" "$MERGED" -c "wincmd w" -c "wincmd J"'
# 配置Meld作为合并工具
git config --global merge.tool meld
# 配置Beyond Compare
git config --global merge.tool bc3
# 配置VS Code
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
使用合并工具
bash
# 启动配置的合并工具
git mergetool
# 使用特定工具
git mergetool --tool=vimdiff
# 一次解决所有冲突
git mergetool --no-prompt
图形化工具
bash
# 使用git gui
git gui
# 使用gitk查看历史
gitk --merge
# 使用第三方工具
# - SourceTree
# - GitKraken
# - Sublime Merge
# - VS Code内置合并工具
高级冲突解决
三方合并
bash
# 查看三方合并的三个版本
# HEAD:当前分支的版本
# REMOTE:要合并分支的版本
# BASE:共同祖先的版本
# 查看共同祖先版本
git show :1:filename.txt
# 查看当前分支版本
git show :2:filename.txt
# 查看合并分支版本
git show :3:filename.txt
# 查看合并结果
git show :0:filename.txt
部分冲突解决
bash
# 只解决特定部分的冲突
# 在编辑器中保留以下标记:
# <<<<<<< HEAD
# 部分内容
# ||||||| merged common ancestors
# 共同祖先内容
# =======
# 合并分支内容
# >>>>>>> branch-name
合并策略
选择合并策略
bash
# 使用递归策略(默认)
git merge -s recursive feature-branch
# 使用递归策略的选项
# 优先选择当前分支的更改
git merge -s recursive -X ours feature-branch
# 优先选择合并分支的更改
git merge -s recursive -X theirs feature-branch
# 使用耐心算法
git merge -s recursive -X patience feature-branch
# 忽略空白字符差异
git merge -s recursive -X ignore-space-change feature-branch
取消合并
bash
# 在解决冲突前取消合并
git merge --abort
# 在解决冲突后取消合并
git reset --hard HEAD
变基冲突解决
变基冲突处理
bash
# 开始变基
git rebase main
# 如果出现冲突
# 1. 编辑冲突文件
# 2. 添加解决后的文件
git add conflicted-file.txt
# 3. 继续变基
git rebase --continue
# 4. 如果解决不满意,可以中止
git rebase --abort
# 5. 或者跳过当前提交
git rebase --skip
变基冲突最佳实践
bash
# 在变基前备份当前分支
git branch backup-branch
# 检出变基前的状态
git checkout backup-branch
# 重新开始变基
git checkout feature-branch
git rebase main
冲突预防
频繁同步
bash
# 在开始工作前同步主分支
git checkout main
git pull origin main
git checkout feature-branch
git rebase main
# 定期同步主分支到功能分支
git checkout feature-branch
git fetch origin
git rebase origin/main
小步提交
bash
# 做小的、专注的提交
git add specific-file.txt
git commit -m "Add specific functionality"
# 避免大的提交,减少冲突可能性
分支策略
bash
# 使用短期功能分支
git checkout -b feature-short-lived
# 开发...
git checkout main
git pull origin main
git merge --no-ff feature-short-lived
git branch -d feature-short-lived
冲突解决工具脚本
自动冲突解决脚本
bash
#!/bin/bash
# resolve-conflicts.sh
echo "开始解决冲突..."
# 查找所有冲突文件
conflict_files=$(git diff --name-only --diff-filter=U)
for file in $conflict_files; do
echo "解决冲突文件: $file"
# 可以添加自定义解决逻辑
# 例如:自动选择最新的更改
git checkout --theirs "$file"
git add "$file"
done
echo "冲突解决完成,准备提交..."
git commit
冲突检测脚本
bash
#!/bin/bash
# check-conflicts.sh
# 检查合并是否会产冲突
git merge --no-commit --no-ff feature-branch
if [ $? -ne 0 ]; then
echo "检测到冲突,中止合并"
git merge --abort
echo "请手动解决冲突"
else
echo "无冲突,可以安全合并"
git merge --abort # 只是检测,不真正合并
fi
冲突解决最佳实践
解决冲突前的准备
bash
# 1. 确保工作区干净
git status
# 2. 备份当前状态
git commit -m "WIP: backup before merge"
# 3. 拉取最新代码
git fetch origin
# 4. 开始合并
git merge origin/main
解决冲突时的注意事项
bash
# 仔细阅读冲突内容
# 理解每一方的修改意图
# 保留必要的功能
# 测试解决后的代码
解决冲突后的验证
bash
# 测试解决后的代码
npm test # 或其他测试命令
# 运行集成测试
npm run test:integration
# 验证功能是否正常
npm run dev # 本地运行验证
团队协作中的冲突处理
代码审查与冲突
bash
# 在Pull Request中讨论潜在冲突
# 使用代码审查工具标记可能的冲突点
# 在合并前进行充分测试
冲突解决流程
bash
# 1. 通知团队成员
# 2. 暂停相关功能开发
# 3. 集中解决冲突
# 4. 通知团队冲突已解决
# 5. 其他成员同步最新代码
特殊情况处理
二进制文件冲突
bash
# 对于二进制文件冲突,通常需要手动解决
# 保留一个版本,或重新生成文件
# 查看二进制文件冲突
git show :2:binary-file.bin # 当前分支版本
git show :3:binary-file.bin # 合并分支版本
大规模冲突
bash
# 对于大规模冲突,可以分步解决
# 1. 解决关键文件
# 2. 测试关键功能
# 3. 逐步解决其他文件
# 4. 完整测试
# 使用子树合并处理大规模重构
git subtree merge -P path/to/subtree branch-name
冲突解决工具推荐
GUI工具
- VS Code:内置合并编辑器
- Sublime Merge:专业的Git合并工具
- GitKraken:图形化Git客户端
- SourceTree:Atlassian的Git客户端
- Beyond Compare:强大的文件比较工具
命令行工具
- vimdiff:Vim内置的差异比较
- meld:图形化的差异比较工具
- diff:标准的差异比较工具
通过掌握这些冲突解决技巧,你可以更有效地处理Git协作中的各种冲突情况。