如何计算git哈希值? [英] How is the git hash calculated?

查看:214
本文介绍了如何计算git哈希值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解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
作者Junio C Hamano< gitster@pobox.com> 1432673399 -0700
提交者Junio C Hamano< gitster@pobox.com> 1432673399 -0700

Git 2.4.2

签名:Junio C Hamano< gitster@pobox.com>

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

  git cat-file -p 9eabf5b536662000f79978c4d1b6e4eff5c8d785> 


$ b

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

  git hash-object fi 
3cf741bbdbcdeed65e5371912742e854a035e665

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

解决方案

git commit sha1 formed ,公式为:

 (printf< type>%s\0 $(git cat-file< type>< ref> | wc -c); git cat-file< type>< ref> | sha1sum 
对于提交 9eabf5b536662000f79978c4d1b6e4eff5c8d785(即 v2.4.2 ^ {} ,并引用了一个树):

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

这会给9eabf5b536662000f79978c4d1b6e4eff5c8d785。



如同:

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

(仍然是9eabf5b536662000f79978c4d1b6e4eff5c8d785)



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

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

这会给29932f3915935d773dc8d52c292cadd81c81071d。


I'm trying to understand how git calculates the hash of refs.

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

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

Clone the repo locally. Check the 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>

Copy the decompressed content so that we can hash it.(AFAIK git uses the uncompressed version when it's hashing)

git cat-file -p 9eabf5b536662000f79978c4d1b6e4eff5c8d785 > fi

Let's SHA-1 the content using git's own hash command

git hash-object fi
3cf741bbdbcdeed65e5371912742e854a035e665

Why the output is not [9e]abf5b536662000f79978c4d1b6e4eff5c8d785? I understand the first two characters (9e) is the length in hex. How should I hash the content of fi so that I can get the git ref abf5b536662000f79978c4d1b6e4eff5c8d785 ?

解决方案

As described in "How is git commit sha1 formed ", the formula is:

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

In the case of the commit 9eabf5b536662000f79978c4d1b6e4eff5c8d785 (which is v2.4.2^{}, and which referenced a tree) :

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

That will give 9eabf5b536662000f79978c4d1b6e4eff5c8d785.

As would:

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

(still 9eabf5b536662000f79978c4d1b6e4eff5c8d785)

Similarly, computing the SHA1 of the tag v2.4.2 would be:

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

That would give 29932f3915935d773dc8d52c292cadd81c81071d.

这篇关于如何计算git哈希值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆