如何计算git哈希值?

时间:2016-02-16 10:53:19

标签: git hash

我试图了解git如何计算refs的哈希值。

$ git ls-remote https://github.com/git/git  

....
29932f3915935d773dc8d52c292cadd81c81071d    refs/tags/v2.4.2
9eabf5b536662000f79978c4d1b6e4eff5c8d785    refs/tags/v2.4.2^{}
....

在本地克隆回购。检查refs/tags/v2.4.2^{} ref by sha

$ git cat-file -p 9eabf5b536662000f79978c4d1b6e4eff5c8d785 

tree 655a20f99af32926cbf6d8fab092506ddd70e49c
parent df08eb357dd7f432c3dcbe0ef4b3212a38b4aeff
author Junio C Hamano <gitster@pobox.com> 1432673399 -0700
committer Junio C Hamano <gitster@pobox.com> 1432673399 -0700

Git 2.4.2

Signed-off-by: Junio C Hamano <gitster@pobox.com>

复制解压缩的内容,以便我们可以散列它。(AFAIK git在散列时使用未压缩的版本)

git cat-file -p 9eabf5b536662000f79978c4d1b6e4eff5c8d785 > fi

让我们使用git自己的哈希命令使用SHA-1内容

git hash-object fi
3cf741bbdbcdeed65e5371912742e854a035e665

为什么输出不是[9e]abf5b536662000f79978c4d1b6e4eff5c8d785?我理解前两个字符(9e)是十六进制的长度。我应该如何散列fi的内容,以便我可以获得git ref abf5b536662000f79978c4d1b6e4eff5c8d785

2 个答案:

答案 0 :(得分:7)

如&#34; How is git commit sha1 formed &#34;中所述,公式为:

(printf "<type> %s\0" $(git cat-file <type> <ref> | wc -c); git cat-file <type> <ref>)|sha1sum

如果是提交 9eabf5b536662000f79978c4d1b6e4eff5c8d785(v2.4.2^{},并引用了一棵树):

(printf "commit %s\0" $(git cat-file commit 9eabf5b536662000f79978c4d1b6e4eff5c8d785 | wc -c); git cat-file commit 9eabf5b536662000f79978c4d1b6e4eff5c8d785 )|sha1sum

这将给出9eabf5b536662000f79978c4d1b6e4eff5c8d785。

一如既往:

(printf "commit %s\0" $(git cat-file commit v2.4.2{} | wc -c); git cat-file commit v2.4.2{})|sha1sum

(仍然是9eabf5b536662000f79978c4d1b6e4eff5c8d785)

同样,计算标签v2.4.2的SHA1将是:

(printf "tag %s\0" $(git cat-file tag v2.4.2 | wc -c); git cat-file tag v2.4.2)|sha1sum

那会给29932f3915935d773dc8d52c292cadd81c81071d。

答案 1 :(得分:5)

这里有点混乱。 Git使用不同类型的对象:blob,trees和commit。 以下命令:

git cat-file -t <hash>

告诉您给定哈希的对象类型。 因此,在您的示例中,散列9eabf5b536662000f79978c4d1b6e4eff5c8d785对应于提交对象。

现在,正如你自己想出的那样,运行这个:

git cat-file -p 9eabf5b536662000f79978c4d1b6e4eff5c8d785

根据类型(在本例中为提交)提供对象的内容。

但是,这个:

git hash-object fi

...计算blob的哈希,其内容是上一个命令的输出(在您的示例中),但它可能是其他任何内容(例如&#34; hello world!&#34;)。试试这个:

echo "blob 277\0$(cat fi)" | shasum

输出与上一个命令相同。这基本上是Git哈希的一个blob。因此,通过散列fi,您将生成blob对象。但正如我们所见,9eabf5b536662000f79978c4d1b6e4eff5c8d785是一个提交,而不是一个blob。所以,为了获得相同的哈希值,你不能将其原样哈希。

提交的哈希基于其他一些使其独特的信息(例如提交者,作者,日期等)。以下文章准确地告诉您提交的哈希是什么:

The anatomy of a git commit

因此,您可以通过提供文章中指定的所有数据与原始提交中使用的完全相同的值来获得相同的哈希值。

这也可能有用:

Git from the bottom up