冲突标记能够指出文本重叠,却不能告诉我们两个人原本想实现什么。
本文使用Git 2.x 与独立演示仓库。Git(分布式版本管理)保存提交对象和引用,工作区、暂存区与提交历史不是同一份状态。每次操作先判断它改变哪个区域,再决定是否适合当前协作情境。
1. 从现象推到机制
三方合并参考共同祖先和两端修改。自动合并成功也可能产生语义冲突,例如一边改变返回单位,另一边增加基于旧单位的判断。真正完成合并,需要恢复双方合理意图并验证相关行为。
图中的四个节点分别表示共同祖先、两端变化、组合实现、行为验证。顺着实线检查输入如何变成输出,再沿虚线核对反馈条件。图示表达的是本文讨论的关系,不是实测曲线或现场截图。
2. 最小实现与输入条件
先查看冲突路径和双方提交说明,再对照共同祖先。完成编辑后检查差异,确认没有残留标记与被意外删除的业务分支。
1
2
3
4
5
6
git status
git diff --cc
git log --oneline --all -8
# 人工理解并合并后
git add src/Demo.java
git diff --cached
示例在没有私人资料的临时仓库执行。先看 status、diff 与 log,再运行改变状态的命令;共享历史优先新增提交表达修复,不用改写历史掩盖已经发生的变化。
3. 用对照区分原因
下表列出需要主动改变的条件。预期行为来自机制分析,复现时还需记录运行环境和原始输出,不能将预期当作已经测得的结果。
| 改变的条件 | 需要验证的行为 |
|---|---|
| 两边修改不同文本 | 仍可能存在契约不兼容 |
| 同一判断条件被同时修改 | 需要解释双方业务目的 |
| 删除标记后代码能编译 | 仍应验证组合后的行为 |
对照 1:两边修改不同文本
仍可能存在契约不兼容。观察时记录调用方与被调方的共同假设。把这个条件与基准情形分开,有助于判断变化来自哪一层;若得到相反结果,应先核对前提,再修改实现。
对照 2:同一判断条件被同时修改
需要解释双方业务目的。观察时记录共同祖先与两端变化。把这个条件与基准情形分开,有助于判断变化来自哪一层;若得到相反结果,应先核对前提,再修改实现。
对照 3:删除标记后代码能编译
仍应验证组合后的行为。观察时记录原有两组场景是否都通过。把这个条件与基准情形分开,有助于判断变化来自哪一层;若得到相反结果,应先核对前提,再修改实现。
4. 适用条件与取舍
不要把整文件选择某一边作为默认解决办法。确实放弃一方改动时,应在提交说明中交代被替代的规则和原因。
一次正常运行只覆盖了这组输入。继续扩展前,应把上面的异常对照保留下来,尤其关注“删除标记后代码能编译”这一分支。后续方案若改变了图中任意一处依赖,原来的判断就要重新验证,不能仅凭界面相似或返回值相同沿用结论。