【问题标题】:Git: How is the SHA1 value of a tree object generated?Git:如何生成树对象的 SHA1 值?
【发布时间】:2012-08-18 14:01:39
【问题描述】:

如题所示,值是基于里面所有树对象(递归)的内容吗?

即,如果两个树对象具有相同的哈希值,我是否可以将它们视为完全相同的文件树(包括所有子目录和文件)?

【问题讨论】:

  • 我不知道实现的细节,但 Linus 本人声称你的最后陈述既是真实的,也是 git 的整体基础。
  • 你所说的子树是什么意思 - 你能不能举一个反省的例子来解释你的问题,因为它不清楚

标签: git sha


【解决方案1】:

您可以看到一些关于用于计算树 SHA here 的粗略细节。

有关存储树的二进制格式的更多信息,请参见here

实际使用的 SHA 只是该详细版本中描述的缓冲区的 SHA。

关键点是 SHA 依赖于所有包含的对象或树的文件名、它们的 SHA 和它们的权限。更改其中任何一个,您都会更改 SHA。如果两棵树具有相同的 SHA,那么所有这些组件都必须匹配(排除冲突的可能性,因为它们几乎是不可能的)。

【讨论】:

  • 不好意思,好像没有详细讲SHA是怎么计算的。我找到的是句子:“This is the SHA-1 hash — a checksum of the content you’re storing plus a header”。
  • 添加了更多细节,详细说明树的存储方式以及 SHA 的计算方式。
【解决方案2】:

我认为不可能有两个具有相同哈希的树对象,因为对象文件由存储库中的哈希命名。此外,为了使两个树对象相同,这将要求提交状态在两种情况下都相同,直到所有暂存文件的内容,因为树对象保留对暂存文件的 SHA-1 引用。

post 可能有助于澄清这一点。

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    为了扩展Michael Anderson's answer,树对象的哈希计算方法与任何其他对象的哈希相同:它是 H(object-content-including-header),其中 H 是哈希函数(SHA-1 或,现在是 SHA-256)。包含标题的内容具有链接中描述的形式:

    • 对象的类型:文字文本“blob”、“tree”、“commit”或“tag”(后跟空格)。它们采用 ASCII 或 UTF-8 格式(因为它们仅由 ASCII 字节组成,所以无论哪种方式都只是一个字节串)。

    • 对象大小的 ASCII 表示,以十进制表示。例如,如果剩余的数据是 16 字节长,我们会得到 ASCII 字符 16

    • 一个 ASCII NUL(零字节)。

    • 对象的原始数据。

    对于 tree 对象,原始数据是三元组的一些重复出现次数:模式、名称、哈希。模式是不带前导零的八进制数,以 ASCII 表示。它与名称之间用空格隔开(字节值 32 十进制)。该名称通常假定为 UTF-8 字节,尽管很少或根本没有检查它是否是有效的 UTF-8;它不能包含 ASCII / 或 NUL 字符。它由 ASCII NUL 终止。使用 SHA-1 时,哈希是原始的 20 字节哈希 ID,使用 SHA-256 时是 32 字节哈希 ID。

    这三个元组是从 Git 的索引生成的,Git 的索引是按排序顺序保存的。这意味着如果你想生成 Git 会生成的 same 树对象数据,你必须以 same order 生成条目。我有示例 Python 代码,它将读取一个目录并收集将进入树对象 here 的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-07
      • 2012-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多