代码之家  ›  专栏  ›  技术社区  ›  Determinant

Git:树对象的SHA1值是如何生成的?

  •  0
  • Determinant  · 技术社区  · 13 年前

    正如标题所示,该值是否基于内部所有树对象的内容(递归)?

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

    3 回复  |  直到 13 年前
        1
  •  1
  •   Michael Anderson    13 年前

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

    可以找到有关存储树的二进制格式的更多信息 here

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

    需要注意的关键点是,SHA取决于所有包含的对象或树的文件名、它们的SHA及其权限。改变其中的任何一个,你就改变了SHA。如果两棵树具有相同的SHA,那么所有这些组件都必须匹配(排除碰撞的可能性,因为它们几乎是不可能的)。

        2
  •  0
  •   Anuradha Weeraman    13 年前

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

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

    希望这能有所帮助。

        3
  •  0
  •   torek    5 年前

    展开一点 Michael Anderson's answer ,树对象的哈希的计算方式与任何其他对象的哈希相同:它是H(包括标头的对象内容),其中H是哈希函数(SHA-1或现在的SHA-256)。包括标题在内的内容具有链接中描述的形式:

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

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

    • ASCII NUL(零字节)。

    • 对象的原始数据。

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

    这三个元组是根据Git的索引生成的,Git的指数按排序顺序保存。这意味着,如果要生成 相同的 树对象数据 Git公司 会,您必须在 相同的订单 .我有一个示例Python代码,它将读取一个目录并收集将进入树对象的数据 here