对象数据库¶
对象数据库是整个 Git 复现项目的根基。
如果这一层做不稳,后面所有命令都只是建立在不可靠存储之上的假动作。
最低要求是什么¶
一个 Git 风格对象数据库至少要能做到:
- 按
[type] [size]\x00[content]编码对象; - 计算 SHA-1;
- 按对象 ID 写入对象库路径;
- 用 zlib 压缩 loose object;
- 读出来时能解压、解析、校验;
- 对损坏对象拒绝继续工作。
这不是“可选增强”,这是仓库可信度的底线。
为什么对象层必须先做扎实¶
因为后面的很多行为都只是对象层的组合:
add先写 blob;write-tree组合 tree;commit-tree写 commit;- tag 可能写 tag 对象;
- pack 只是另一种组织对象的方式;
- fetch / push 只是在传输对象。
所以只要对象层出现这些问题:
- header 算错;
- size 不一致;
- hash 不对应;
- zlib 内容损坏;
整个系统都会跟着失真。
loose object 为什么适合教学¶
在项目早期,loose object 非常适合教学:
- 路径结构直观;
- 一对象一文件;
- 易于检查;
- 易于和官方 Git 做交叉验证。
这也是为什么很多 Git 复现项目先从 loose object 开始,而不是一上来就做 pack。
大文件为什么要流式处理¶
如果 hash-object 或 add 遇到很大的文件,直接整文件读进内存不安全。
所以项目文档明确要求大文件使用分块读取,比如 64KB chunk。
这件事看起来像性能细节,实际上也是健壮性要求:
- 避免内存暴涨;
- 保持 hash 和压缩流程可流式推进;
- 让实现更接近真实工具。
pack fallback 为什么重要¶
对象数据库不应该只会读 loose object。
一旦仓库里开始出现 pack / idx,读取逻辑就要支持:
- 先查 loose object;
- 没有时回退到 pack;
- 通过 idx 做随机定位;
- 必要时展开 delta。
这也是项目从“本地玩具系统”过渡到“具备分布式同步骨架”的关键一步。