Git Tree和Commit对象的校验和计算

时间:2011-06-10 07:44:18

标签: ruby git implementation

我发现git的内部管道非常吸引人。至少在概念层面上它简单而优雅。关于该主题的许多来源都详细描述了blob对象(Git MagicGit Internals),甚至还描述了如何用Pro Git中的几行红宝石编写blob对象的简短ruby脚本:

require 'zlib'
require 'fileutils'
require 'digest/sha1'

content = "StackOverflow"

header = "blob #{content.length}\0"
data = header + content

sha1 = Digest::SHA1.hexdigest(data)

zlib_content = Zlib::Deflate.deflate(data)
path = '.git/objects/' + sha1[0,2] + '/' + sha1[2,38]
FileUtils.mkdir_p(File.dirname(path))
File.open(path, 'w') { |f| f.write zlib_content }         

通常会得出结论,其他存储对象(树,提交和标记)完全相同,但标题不同。但是,内部格式似乎存在一些差异,因为修改脚本标题和文本内容只会导致损坏的树或提交条目和/或不匹配的校验和。与blob相比,其他对象是以不同的方式存储的吗?

cat-file和其他对象的漂亮打印输出似乎与实际的存储文件实现没有太大的相似之处。

根据Git Magic,树对象格式为

"tree" SP "<content length>" NUL "<permissions> <filename>" NUL <checksum>

但是我无法用这种可靠的红宝石技能为此生成正确的校验和。是否可以像blob对象一样轻松地生成树和提交对象。有人可以为此提供短代码片段吗?

1 个答案:

答案 0 :(得分:4)

您是否看过为{github供电而开发的grit

有人可能已经在ruby中实现了这个,很可能在那里实现了。

希望有所帮助。