分支合并与冲突处理
本节目标
学会判断 fast-forward 与三方合并,安全开始或中止一次 merge,并把“冲突文件可提交”与“业务语义正确”区分开。所有写操作只在 隔离实验仓库 中练习。
合并解决什么问题
分支让两条工作线独立前进,合并(merge)则把它们重新汇合。假设 main 和 feature/summary 都从提交 B 开始:
C ← D feature/summary
/
A ← B ← E main, HEADGit 会找到共同祖先 B,比较 B→D 与 B→E 的变化,再尝试生成共同结果。这叫三方合并。若当前分支没有自己的新提交,只需把分支引用向前移动,则是 fast-forward,不需要新的 merge commit。
开始合并前的证据
git status --short --branch
git branch --show-current
git log --graph --oneline --decorate --all
git diff
git diff --staged确认工作区没有未理解的改动,并确认“把谁合进谁”:先切到接收结果的分支,再把来源分支交给 git merge。
git switch main
git merge feature/summary不要把方向说反。上述命令改变的是 main:它接收 feature/summary 的可达历史。
三种常见结果
1. Already up to date
来源分支没有当前分支尚未包含的提交,不会产生新变化。
2. Fast-forward
当前分支没有分叉,引用直接前移。历史仍是单线。
3. 自动或冲突的三方合并
两边都前进时,Git 尝试自动合并。若改动不冲突,可直接生成 merge commit;若同一内容无法自动决定,仓库进入 merging 状态,等待人工处理。
冲突不是随机报错
冲突表示 Git 缺少足够语义来选择最终内容。文本文件可能出现:
<<<<<<< HEAD
主分支的规则
=======
功能分支的规则
>>>>>>> feature/summaryHEAD 一侧来自当前接收分支,另一侧来自被合入分支。解决不是机械删除三类标记,而是读取需求、测试和两边意图,写出应当长期保留的最终文本。
先查看未解决路径:
git status
git diff --name-only --diff-filter=U
git diff编辑并验证后,把已经解决的路径加入 index:
git add -- prompts/summary.md
git diff --staged --check
git diff --staged
git merge --continuegit merge --continue 可能打开提交信息编辑器;也可以在所有冲突解决并暂存后使用 git commit。提交前运行项目测试,确保“Git 已无冲突标记”与“程序行为正确”同时成立。
放弃本次合并
如果发现方向错了、缺少需求或当前状态不适合继续:
git merge --abort
git status --short --branch--abort 试图恢复到 merge 开始前。若开始前已有复杂未提交修改,恢复可能不完整;这也是为什么合并前应先让工作区可解释。不要用 reset --hard 代替思考。
Merge、rebase 与 cherry-pick
| 操作 | 主要效果 | 提交 ID 行为 | 典型用途 |
|---|---|---|---|
merge | 汇合两条历史,必要时创建多父提交 | 既有提交不变;可能新增 merge commit | 保留分支形成过程 |
rebase | 把一串提交重新生成到新基线 | 被重放的提交获得新 ID | 清理尚未共享的功能分支 |
cherry-pick | 把选定提交的变化生成到当前分支 | 来源提交保留;当前分支新增不同 ID | 有选择地移植修复 |
初学主线先掌握 merge。不要为了“历史好看”在共享分支随意 rebase,也不要把 cherry-pick 当作长期分支同步方式。
常见错误与排查
- 在错误分支上合并:用
git branch --show-current与图形日志确认方向;尚未完成时可git merge --abort。 - 只删标记不读语义:运行测试、检查文档与评测样例,再暂存。
- 仍有未解决文件:
git diff --name-only --diff-filter=U应为空。 - 合并后找不到“新提交”:可能发生 fast-forward;用
git log --graph --oneline --decorate --all解释。 - 把 merge 与 pull 混为一谈:pull 先 fetch,再按显式选项或配置整合;见远程课程。
练习与掌握检查
在综合项目中让 main 与 experiment/short-output 修改同一行,完成一次确定的冲突。验收证据:
- 合并前分叉图;
- merging 状态与未解决路径清单;
- 最终文件不含冲突标记,且语义说明完整;
git diff --staged --check与项目检查结果;- 合并后的图及 merge commit ID。
你应能回答:fast-forward 为什么没有多父提交?git add 在冲突流程中表达什么?什么时候应继续,什么时候应 abort?
下一步
参考资料
按 Git 2.55.0 官方文档核验,获取日期:2026-07-14。