存储在树对象中的 SHA1 哈希(由 返回)git ls-tree
与文件内容的 SHA1 哈希(由 返回)不匹配sha1sum
:
$ git cat-file blob 4716ca912495c805b94a88ef6dc3fb4aff46bf3c | sha1sum
de20247992af0f949ae8df4fa9a37e4a03d7063e -
Git 如何计算文件哈希?它会在计算哈希之前压缩内容吗?
Git 为对象添加前缀“blob”,后跟长度(作为人类可读的整数),后跟 NUL 字符
$ echo -e 'blob 14\0Hello, World!' | shasum
8ab686eafeb1f44702738c8b0f24f2567c36da6d
来源:http ://alblue.bandlem.com/2011/08/git-tip-of-week-objects.html
git hash-object
这是验证您的测试方法的快速方法:
s='abc'
printf "$s" | git hash-object --stdin
printf "blob $(printf "$s" | wc -c)\0$s" | sha1sum
输出:
f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7f
f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7f -
GNU Coreutils在哪里sha1sum
。
然后归结为了解每种对象类型的格式。我们已经介绍了琐碎的blob
,这里是其他的:
我需要它用于 Python 3 中的一些单元测试,所以我想我会把它留在这里。
def git_blob_hash(data):
if isinstance(data, str):
data = data.encode()
data = b'blob ' + str(len(data)).encode() + b'\0' + data
h = hashlib.sha1()
h.update(data)
return h.hexdigest()
我在任何地方都坚持\n
行尾,但在某些情况下,Git 也可能在计算这个哈希之前改变你的行尾.replace('\r\n', '\n')
,所以你可能也需要一个。
根据Leif Gruenwoldt的回答,这里有一个 shell 函数替代git hash-object
:
git-hash-object () { # substitute when the `git` command is not available
local type=blob
[ "$1" = "-t" ] && shift && type=$1 && shift
# depending on eol/autocrlf settings, you may want to substitute CRLFs by LFs
# by using `perl -pe 's/\r$//g'` instead of `cat` in the next 2 commands
local size=$(cat $1 | wc -c | sed 's/ .*$//')
( echo -en "$type $size\0"; cat "$1" ) | sha1sum | sed 's/ .*$//'
}
测试:
$ echo 'Hello, World!' > test.txt
$ git hash-object test.txt
8ab686eafeb1f44702738c8b0f24f2567c36da6d
$ git-hash-object test.txt
8ab686eafeb1f44702738c8b0f24f2567c36da6d