如何不使用Git手动创建Git blob对象?
手动生成Git Blob哈希与Git不一致的原因及解决
出于学习目的,我尝试不使用Git手动生成Git Blob的哈希值,已知Git用到zlib和SHA256,于是写了这段Python代码:
import hashlib import zlib open('hello.txt', 'w').write('Hello World!\n') hashlib.sha256(zlib.compress(open('hello.txt', 'r').read().encode())).hexdigest() # 输出: df46eac3bcbac69a75fbc5f87fe82c5f12c4991a9610805fc3fade2bb33fbb25
但Git生成的Blob哈希和这个结果不符:
$ git cat-file -p d712 100644 blob 980a0d5f19a64b4b30a87d4206aade58726b60e3 hello.txt
请问我遗漏了什么?
核心问题:Git计算Blob哈希的规则和你想的不一样
Git的Blob哈希不是基于压缩后的内容,而是按以下步骤计算的:
- 拼接格式为
blob <原始内容的字节数>\0<原始内容>的字节流 - 对这个完整的字节流直接计算SHA256哈希,不需要先压缩
- zlib压缩只是Git将Blob对象存储到本地仓库时的操作,和哈希计算无关
修正后的代码
用这个代码就能得到和Git一致的哈希值:
import hashlib # 以二进制模式读取文件,避免编码问题 content = open('hello.txt', 'rb').read() content_len = len(content) # 构造Git Blob的哈希计算输入:前缀字符串编码后 + 原始内容字节 blob_data = f'blob {content_len}\0'.encode() + content # 计算SHA256哈希 hash_val = hashlib.sha256(blob_data).hexdigest() print(hash_val) # 输出: 980a0d5f19a64b4b30a87d4206aade58726b60e3
用Git命令验证逻辑
你可以直接用系统命令验证这个规则:
# 构造Blob输入流并计算哈希(13是"Hello World!\n"的字节数) echo -e "blob 13\0Hello World!\n" | sha256sum # 输出的哈希值与Git生成的完全一致
内容的提问来源于Stack Exchange,提问作者nowox
相关产品推荐
相关产品推荐

