欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

Git对象的hash方法 Git中的数据对象 次  来源:宝鼎软件 时间:2018-06-26

原文出处: 彭金金

在上一篇文章中,将了数据工具、树工具和提交工具三种Git工具,每种工具管帐算出一个hash值。那么,Git是如何计较出Git工具的hash值?本文的内容就是来解答这个问题。

Git工具的hash要领

Git中的数据工具、树工具和提交工具的hash要领道理是一样的,可以描写为:

header = "<type> " + content.length + "\0"
hash = sha1(header + content)

上面公式暗示,Git在计较工具hash时,首先会在工具头部添加一个header。这个header由3部门构成:第一部门暗示工具的范例,可以取值blobtreecommit以别离暗示数据工具、树工具、提交工具;第二部门是数据的字节长度;第三部门是一个空字节,用来将headercontent脱离开。将header添加到content头部之后,利用sha1算法计较出一个40位的hash值。

在手动计较Git工具的hash时,有两点需要留意:
1.header中第二部门关于数据长度的计较,必然是字节的长度而不是字符串的长度;
2.header + content的操纵并不是字符串级此外拼接,而是二进制级此外拼接。

各类Git工具的hash要领沟通,昆山软件开发,差异的在于:
1.头部范例差异,数据工具是blob,树工具是tree,提交工具是commit
2.数据内容差异,数据工具的内容可以是任意内容,而树工具和提交工具的内容有牢靠的名目。

接下来别离讲数据工具、树工具和提交工具的详细的hash要领。

数据工具

数据工具的名目如下:

blob <content length><NULL><content>

从上一篇文章中我们知道,利用git hash-object可以计较出一个40位的hash值,譬喻:

$ echo -n "what is up, doc?" | git hash-object --stdin
bd9dbf5aae1a3862dd1526723246b20206e5fc37

留意,劳务派遣管理系统,上面在echo后头利用了-n选项,用来阻止自动在字符串末端添加换行符,不然会导致实际传给git hash-objectwhat is up, doc?\n,而不是我们直观认为的what is up, doc?

为验证前面提到的Git工具hash要领,我们利用openssl sha1来手动计较what is up, doc?的hash值:

$ echo -n "blob 16\0what is up, doc?" | openssl sha1
bd9dbf5aae1a3862dd1526723246b20206e5fc37

可以发明,手动计较出的hash值与git hash-object计较出来的一模一样。

在Git工具hash要领的留意事项中,提到header中第二部门关于数据长度的计较,必然是字节的长度而不是字符串的长度。由于what is up, doc?只有英文字符,在UTF8中刚好字符的长度和字节的长度都便是16,很容易将这个长度误解为字符的长度。假设我们以中文来试验:

$ echo -n "中文" | git hash-object --stdin
efbb13322ba66f682e179ebff5eeb1bd6ef83972
$ echo -n "blob 2\0中文" | openssl sha1
d1dc2c3eed26b05289bddb857713b60b8c23ed29

我们可以看到,git hash-objectopenssl sha1计较出来的hash值基础纷歧样。这是因为中文两个字符作为UTF名目存储后的字符长度不是2,详细是几多呢?可以利用wc来计较:

$ echo -n "中文" | wc -c
       6

中文字符串的字节长度是6,从头手动计较发明得出的hash值就能对应上了:

$ echo -n "blob 6\0中文" | openssl sha1
efbb13322ba66f682e179ebff5eeb1bd6ef83972

树工具

树工具的内容名目如下:

tree <content length><NUL><file mode> <filename><NUL><item sha>...

需要留意的是,<item sha>部门是二进制形式的sha1码,而不是十六进制形式的sha1码。