Refs¶
如果对象数据库回答的是“仓库里存了什么”,那么 refs 回答的就是“这些历史节点现在叫什么名字”。
ref 是什么¶
ref 本质上就是一个名字到对象 ID 的映射。
最常见的 ref 包括:
- 分支;
- 标签;
- 远端跟踪分支;
HEAD。
其中:
- 分支通常指向 commit;
- 轻量标签通常也直接指向 commit;
- 附注标签 ref 先指向 tag 对象,再由 tag 对象指向目标对象。
为什么 ref 系统很重要¶
很多 Git 操作本质上都不是“改对象”,而是“移动名字”:
commit生成新 commit 后,要更新当前分支 ref;branch <name>只是新建一个 ref;tag也是写 ref;- fast-forward merge 只是推进 ref;
reset --soft主要也是改 ref。
如果 ref 系统设计不好,很多高层命令都会一起变得混乱。
HEAD 为什么特别¶
HEAD 表示当前检出目标。
常见情况下它是一个符号引用,比如:
ref: refs/heads/main
这表示 HEAD 不是直接存一个 commit,而是指向某个分支。
当你 checkout 到一个裸 commit 时,HEAD 就会进入 detached 状态。
所以 HEAD 既是 ref 系统的一部分,又比普通 branch 更特殊。
为什么 ref 更新要加锁¶
refs 是高价值元数据。
如果改写时没有锁保护,可能出现:
- 并发写覆盖;
- 半写入;
- 旧值被错误踩掉;
- 分支历史丢失。
因此项目文档明确要求:
- 写 ref 前先创建
.lock; - 写完后原子替换;
- 必要时校验预期旧值。
这类保护逻辑必须集中复用,不能每个命令自己发明一套。