三十年间 Git 对象 ID 一直是 SHA-1。碰撞攻击促使 Git 支持
SHA-256 对象格式;引用存储也在实验
reftable 以替代大量松散 ref 与
packed-refs。二者都改变「磁盘长什么样」,但截至
Git 2.54,默认仍是 SHA-1 + 松散/packed refs。
一、SHA-256 对象格式
创建仓库:
git init --object-format=sha256 sha256-democonfig 含:
[extensions]
objectformat = sha256对象 ID 为 64 十六进制字符;松散路径仍为前 2 字符目录 + 剩余 62 字符文件名,例如(Git 2.54.0 实测):
.git/objects/b6/1a639b8969bb23943c5f7dc89040350f213704e522fb4b2cbda6995f71617c
哈希算法换为 SHA-256,对象头与 zlib
布局不变(仍是 type size\0 +
载荷)。与 SHA-1
仓库不能直接混合对象;克隆、fetch
需双方支持相同 object format。
托管平台与旧客户端支持不均——生产迁移前须核对工具链。实验失败时以 gitformat-hash 规范为准,不硬跑命令。
二、与 SHA-1 仓库的差异小结
| 项目 | SHA-1(默认) | SHA-256 |
|---|---|---|
| ID 长度 | 40 hex | 64 hex |
| 路径 | objects/ab/ + 38 |
objects/ab/ + 62 |
| index/tree 内二进制 SHA | 20 字节 | 32 字节 |
| 默认 init | 是 | 需显式 flag |
松散对象与 pack 的逻辑类型(blob/tree/commit/tag)不变,见 第 02、07 篇。
三、reftable 是什么
reftable 把引用存进单个(或分片)二进制表文件,支持:
- 原子批量更新
- 更快查找与复制
- 可选日志嵌入
设计文档见 Git 源码
Documentation/technical/reftable.md(A
级来源路径)。与文本 refs/heads/* +
packed-refs 并存期长:由
core.refFormat
等配置控制,默认仓库仍为传统布局(第
04 篇)。
本文不写「reftable 已全面替代
packed-refs」——应以当前版本的 git init
默认行为为准。
四、演进时间线(事实边界)
- SHA-256:Git 2.29+
起逐步可用,持续修补互操作与转换工具(
git format-sha1等,依版本查阅 manual)。 - reftable:长期实验特性,主要用于大型托管与
git clone优化场景;普通开发者磁盘上最常见仍是refs/文本文件。
跟进新版本时,核对 Release Notes 中
objectformat 与 reftable
段落。
五、选型建议(工程判断)
- 新项目除非全员工具链确认,否则默认 SHA-1 仍最省事。
- 需抗哈希碰撞合规时评估 SHA-256,并规划托管端、CI、子模块一致性。
- reftable
对读者通常是认知储备;排查日常仓库仍以
refs/packed-refs为主。
六、本文边界
- 不逐步解析 reftable 二进制 record(见 technical 文档)。
- 不做 SHA-1→SHA-256 迁移操作手册。
复现 SHA-256:
git init --object-format=sha256 demo && cd demo
echo x > a.txt && git add a && git commit -m t
git rev-parse HEAD # 64 字符
find .git/objects -type f参考资料
- Git documentation, gitformat-hash
git/gitrepository,Documentation/technical/reftable.md(版本 pin 至所用 Git tag)- 实验环境:Git 2.54.0,WSL2 Linux
系列索引:Git 内部结构 · 上篇:worktree/submodule
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【Git 内部】Git 内部结构:对象库与磁盘文件格式
从 .git 目录布局、松散对象与 packfile 格式,到 refs、index、reflog、gc/fsck 与 fetch/push 落地——用官方 format 文档与本地实测 dump 系统讲清 Git 把版本历史存在哪、每个命令改写了哪些文件。全 16 篇。
【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 展开并画对象图。