SHA-256 仓库和普通仓库有什么不同?这篇在同一份内容上创建两种仓库,对比配置、hash 长度、tree 和 index 的字节数,手算 SHA-256 的 blob hash,最后试试两种仓库能不能互相 fetch。
[sha1]
$ git rev-parse --show-object-format; git config --local --list | grep -E "repositoryformatversion|objectformat" || true
sha1
core.repositoryformatversion=0
[sha256]
$ git rev-parse --show-object-format; git config --local --list | grep -E "repositoryformatversion|objectformat" || true
sha256
extensions.objectformat=sha256
core.repositoryformatversion=1git init --object-format=sha256 决定整个仓库的哈希算法,写进 extensions.objectformat,并把 core.repositoryformatversion 提到 1。之后无法改变。
[sha1] HEAD = 5bda956e00d5b8a1079763653230b1007eaac8a6 (40 位十六进制) [sha256] HEAD = 21e5ed726238c38fbc7e807fc88d94ea828ed649a5f048027def37a98c0fdfa9 (64 位十六进制) $ find .git/objects -type f | head -3 .git/objects/95/af096e0de45efede313bca8272ccf0194f5e067a8ceca790bdb40099c66bee .git/objects/a3/5f338c4e3f3d62632a3413b62bf1761b0f65e638e03566303b266eb7985130 .git/objects/eb/6216fa5957e18a0e6ed849dd06c22fde18d084356aaf8d551e89fdb3011489 $ git log --oneline -1; git log --abbrev=10 --oneline -1 21e5ed7 提交 21e5ed7262 提交
hash 从 40 位十六进制变成 64 位,松散对象的文件名也变成“2 位目录加 62 位文件名”。git log 的默认缩写仍然是 7 位。
git: a35f338c4e3f3d62632a3413b62bf1761b0f65e638e03566303b266eb7985130 手算: a35f338c4e3f3d62632a3413b62bf1761b0f65e638e03566303b266eb7985130 一致: True
对象格式没有变,仍是“类型 长度 NUL 内容”,只是换了 SHA-256。手算 blob 的 hash 与 git 一致。
[sha1] tree 解压后 359 字节,头部 "tree 350",10 个条目,每个条目的 hash 占 20 字节 [sha256] tree 解压后 479 字节,头部 "tree 470",10 个条目,每个条目的 hash 占 32 字节
tree 条目的 hash 从 20 字节变成 32 字节,10 个条目的 tree 从 359 字节变成 479 字节;索引文件也相应变大。仓库里 hash 出现的地方都会变大,但相对于文件内容本身通常很小。
[sha1] .git/index = 786 字节,tree 对象解压后 359 字节 [sha256] .git/index = 970 字节,tree 对象解压后 479 字节
同样 10 个文件,.git/index 从 786 字节增加到 970 字节。
$ git fetch /work/l7sha1 main 2>&1 | head -5 fatal: mismatched algorithms: client sha256; server sha1 $ git fetch /work/l7sha256 main 2>&1 | head -5 fatal: mismatched algorithms: client sha1; server sha256 $ git clone -q /work/l7sha256 l7clone 2>&1 && git -C l7clone rev-parse --show-object-format sha256
两种仓库之间不能 fetch / push,会立刻报 mismatched algorithms。clone 一个 sha256 的远程会自动得到 sha256 的本地仓库。这就是 SHA-256 仓库在实际使用中要考虑的最大障碍:服务器、客户端和工具链都要支持。