解压Git树对象

3
我写了一个小的Groovy实用程序,可以解压git blob对象并且能够正常工作,我可以看到blob的内容。这同样适用于commits。
但是,在trees中存在问题。当我解包它们时,会得到如下信息:tree 29100644 a�⛲��CK�)�wZ���S�。从对象大小后面可以看出,无法读取内容。看起来这个内容以不同的格式保存。
以下是我的代码:
   ByteArrayOutputStream result = new ByteArrayOutputStream()
   InflaterOutputStream byteWriter = new InflaterOutputStream(result)
   byteWriter.write(new File(input).bytes)
   byteWriter.close()
   println result

尝试在Ruby中做了类似的事情,结果也是一样的。因此我认为问题在于文件的格式不是Zlib格式。
1个回答

5
但是树形内容并不是一个可读的字符串,如果我遵循文章"Git tree objects, how are they stored?" 的话:
一般格式如下:
  • 前4个字节声明对象类型。在我们的例子中,这四个字节是“tree”,使用ASCII编码。
  • 然后是一个空格,
  • 接着是条目,没有分隔符。
确切的格式如下。所有大写字母都是“非终端符号”,我会稍后解释。
tree ZN(A FNS)*

其中:

  • N 代表 NUL 字符
  • Z 代表对象的大小(以字节为单位)
  • A 代表 Unix 访问代码,使用 ASCII 编码,例如> 对于普通文件的访问权限为 100644。
  • F 代表文件名(我不确定其编码方式,但肯定与 ASCII 兼容),以 NUL 结尾。
S is the 20 byte SHA hash of the entry pointed to, 20 bytes long.

这里有一个例子。
假设我们有一个包含两个文件的目录,分别叫做testtest2。该目录的SHA值为f0e12ff4a9a6ba281d57c7467df585b1249f0fa5。您可以在输出中看到条目的SHA哈希值。

$ git cat-file -p f0e12ff4a9a6ba281d57c7467df585b1249f0fa5
100644 blob 9033296159b99df844df0d5740fc8ea1d2572a84    test
100644 blob a7f8d9e5dcf3a68fdd2bfb727cde12029875260b    test2

tree


感谢您指引我正确的方向。我无法理解SHA1是如何编码成20字节的,但在这里找到了资料:http://git.rsbx.net/Documents/Git_Data_Formats.txt 但是那里的语言太过复杂,而且看起来算法也不是很简单。另一个了解它是如何工作的选择是JGit源代码:https://github.com/eclipse/jgit/ 但也不是非常易读。 - Stanislav Bashkyrtsev
1
获取十六进制编码的SHA1的20字节输出的简单方法是将其输入到“xxd -r -p”中。 - Dave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接