大仓库执行
git log、git merge-base 或
git push --dry-run 时,需要沿 parent 链遍历
commit。纯对象读取成本高,Git
在对象库旁路维护两类只读加速文件:commit-graph
缓存提交拓扑与 generation number;pack
bitmap 在 pack 旁记录可达性位图,服务
git rev-list 等。
本文说明文件路径与机制边界;不写未实测的性能倍率(WRITING_GUIDE:性能数据须真实跑过)。
一、commit-graph
路径:.git/objects/info/commit-graph(可多文件链
commit-graph-chain,见 gitformat-commit-graph)。
生成:
git commit-graph write实测单提交仓库生成后:
.git/objects/info/commit-graph # 约 1 KB 级
作用(概念):
- 按 commit SHA 快速查 parent、root tree、generation number。
- Generation number:拓扑层级标量,用于判断祖先/后代关系时剪枝,减少全图 walk。
commit-graph 不改变对象库语义;删除后 Git 回退到读 commit 对象,功能仍正确,仅可能更慢。
二、pack bitmap
路径:与 pack 同名前缀,如
pack-8f8a….bitmap(由 git repack
等在条件满足时生成,依赖 pack.writeBitmaps
等配置)。
作用(概念):
- 为 pack 内对象预计算可达性位图,使
git rev-list --objects等遍历避免重复解 pack。 - 对大型托管仓库的
git clone/fetch协商也有使用场景(与协议层相关,第 14 篇 仅谈落盘)。
无 bitmap 时命令仍可用;属于优化层。
三、与 maintenance 的关系
git gc 可能重写 pack 并更新
bitmap;commit-graph write
常作为维护任务的一部分(git maintenance /
钩子)。详见 gc/repack。
四、实验建议
在本地仓库对比:
git commit-graph write
ls -la .git/objects/info/
git rev-list --count --all若要做耗时对比,须固定仓库规模、禁用/启用 commit-graph、预热次数 ≥3 并写明 CPU/Git 版本——本系列不收录未完成的 benchmark 数字。
五、本文边界
- 不解析 commit-graph 二进制 chunk 逐字段(需要时查 gitformat-commit-graph)。
- bitmap 格式见 pack 文档扩展章节,不逐位图解。
参考资料
- Git documentation, gitformat-commit-graph
- Git documentation, gitformat-pack(bitmap 相关)
- 实验环境:Git 2.54.0
系列索引:Git 内部结构 · 上篇:delta 压缩 · 下篇:gc/repack
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【Git 内部】.git 目录全景:三棵树与仓库布局
git init 之后 .git 里每个路径干什么?对照 gitrepository-layout 与本地 find 清单,建立 bare/non-bare、三棵树、objects/refs/index 的磁盘级地图。
【Git 内部】松散对象:zlib 载荷与 SHA-1 路径
blob/tree/commit 在磁盘上如何编码?对象头 type size、zlib 压缩、objects/ab/cdef 路径命名,对照 git hash-object 与手工 SHA-1 验证。
【Git 内部】对象图:tree、commit、tag 的链式结构
一次提交在对象库里如何连成链?tree 条目 mode/name/hash、commit 的 tree/parent 字段、annotated tag,用 git cat-file -p 展开并画对象图。
【Git 内部】refs、HEAD 与 packed-refs
分支和标签在磁盘上只是一行 SHA?refs/heads、符号引用 HEAD、packed-refs 文件头与 peeled tag 的格式与生成时机。