Git ls-tree显示的Blob哈希未在.git/objects中找到,如何获取真实Blob哈希?
关于Git Tree与Blob哈希的疑问解答
嘿,我来帮你理清这个问题~首先得纠正一个关键误解:git ls-tree显示的哈希就是文件真实的Blob哈希,并不是和文件名结合后的哈希。你找不到它的原因,是Git存储对象的方式和你预想的不一样,而查看Tree对象内部结构完全可行,而且不需要修改仓库内容!
为什么在.git/objects里找不到对应的Blob?
Git存储对象时会做两个特殊处理:
- 拆分哈希路径:Blob的完整哈希是40位十六进制字符串,Git会把前2位作为目录名,后38位作为文件名。比如Blob哈希是
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391,实际存储路径是.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391,你直接在.git/objects根目录找完整哈希肯定找不到。 - 打包存储:如果仓库执行过
git gc(Git会自动定期执行,也可以手动触发),零散的Blob/Tree/Commit对象会被打包进.git/objects/pack/目录下的.pack和.idx文件里,此时松散的单个对象文件就会被删除,但git cat-file依然能通过打包文件读取到对象内容。
如何查看Tree对象的内部结构?
直接用git cat-file -p <Tree哈希>命令就行!这个命令会输出Tree对象的原始内容,每一行的格式和git ls-tree的输出完全一致:权限 类型 哈希 文件名,比如:
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 README.md 040000 tree a1b2c3d4e5f67890abcdef1234567890abcdef12 docs/
这就是Tree对象的真实内部结构,里面的Blob哈希就是文件对应的真实哈希。
验证Blob存在并找到它的存储位置的方法
- 确认Blob哈希合法:执行
git cat-file -t <Blob哈希>,如果返回blob,说明这个哈希确实是有效的Blob对象。 - 查找松散Blob:用以下命令直接定位:
或者直接手动拼接路径查看:find .git/objects -name "<Blob哈希的后38位>".git/objects/<哈希前2位>/<哈希后38位> - 查找打包中的Blob:如果上面的命令找不到,说明Blob在打包文件里,用以下命令确认:
git verify-pack -v .git/objects/pack/*.pack | grep <Blob哈希>
总结
你完全不需要担心改写仓库内容,上面所有命令都是只读操作,不会修改任何仓库数据。git ls-tree显示的就是真实的Blob哈希,只是Git的存储方式让你没法直接在.git/objects根目录找到它而已。查看Tree内部结构用git cat-file -p <Tree哈希>就足够啦~
内容的提问来源于stack exchange,提问作者Wyckham Seelig
相关产品推荐
相关产品推荐

