创建分支很快,因为它不需要复制整个工作目录。真正被共享的是提交对象及其父子关系。
本文使用Git 2.x 与独立演示仓库。Git(分布式版本管理)保存提交对象和引用,工作区、暂存区与提交历史不是同一份状态。每次操作先判断它改变哪个区域,再决定是否适合当前协作情境。
1. 从现象推到机制
提交保存树对象、父提交和元信息。分支名指向一个提交,新提交使当前分支引用前进。两个分支共同指向的历史不会因此复制成两份,删除分支名也不等同立即删除所有对象。
图中的四个节点分别表示提交对象、共同祖先、分支引用、引用移动。顺着实线检查输入如何变成输出,再沿虚线核对反馈条件。图示表达的是本文讨论的关系,不是实测曲线或现场截图。
2. 最小实现与输入条件
在临时仓库建立两条开发线,用图形日志观察共同祖先与分叉位置。提交内容与引用名称分开记,避免把某个分支名当成固定版本。
1
2
3
4
git branch demo-feature
git log --graph --oneline --all
git show --stat HEAD
git branch -v
示例在没有私人资料的临时仓库执行。先看 status、diff 与 log,再运行改变状态的命令;共享历史优先新增提交表达修复,不用改写历史掩盖已经发生的变化。
3. 用对照区分原因
下表列出需要主动改变的条件。预期行为来自机制分析,复现时还需记录运行环境和原始输出,不能将预期当作已经测得的结果。
| 改变的条件 | 需要验证的行为 |
|---|---|
| 两个分支指向同一提交 | 内容和历史起点可以完全相同 |
| 其中一条分支新增提交 | 只有相应引用向前移动 |
| 标签用于标记版本 | 仍要确认标签指向与类型 |
对照 1:两个分支指向同一提交
内容和历史起点可以完全相同。观察时记录各引用实际指向的提交号。把这个条件与基准情形分开,有助于判断变化来自哪一层;若得到相反结果,应先核对前提,再修改实现。
对照 2:其中一条分支新增提交
只有相应引用向前移动。观察时记录父提交和分支指针。把这个条件与基准情形分开,有助于判断变化来自哪一层;若得到相反结果,应先核对前提,再修改实现。
对照 3:标签用于标记版本
仍要确认标签指向与类型。观察时记录标签对象及目标提交。把这个条件与基准情形分开,有助于判断变化来自哪一层;若得到相反结果,应先核对前提,再修改实现。
4. 适用条件与取舍
引用名称便于交流,准确版本仍应使用提交标识。构建与部署回执记录分支名之外,还要记录实际提交,避免分支继续前进后含义改变。
一次正常运行只覆盖了这组输入。继续扩展前,应把上面的异常对照保留下来,尤其关注“标签用于标记版本”这一分支。后续方案若改变了图中任意一处依赖,原来的判断就要重新验证,不能仅凭界面相似或返回值相同沿用结论。