Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git 如何计算提交、树和blob的哈希?_Git_Hash - Fatal编程技术网

Git 如何计算提交、树和blob的哈希?

Git 如何计算提交、树和blob的哈希?,git,hash,Git,Hash,对于如何计算提交、树和blob的SHA-1哈希,我感到困惑。根据,提交哈希是基于以下因素计算的: 提交的源树(分解到所有子树和blob) 父提交sha1 作者信息 提交者信息(对,这些是不同的!) 提交消息 树哈希和blob哈希也涉及相同的因素吗?Git有时被称为“内容可寻址文件系统”。散列是地址,它们基于各种对象的内容。因此,为了知道散列是基于什么,我们只需要知道各种对象的内容 斑点 一个blob仅仅是一个八位字节流。没别的了。它类似于Unix文件系统中的文件内容概念 因此,blob的哈希仅基

对于如何计算提交、树和blob的SHA-1哈希,我感到困惑。根据,提交哈希是基于以下因素计算的:

  • 提交的源树(分解到所有子树和blob)
  • 父提交sha1
  • 作者信息
  • 提交者信息(对,这些是不同的!)
  • 提交消息
  • 树哈希和blob哈希也涉及相同的因素吗?

    Git有时被称为“内容可寻址文件系统”。散列是地址,它们基于各种对象的内容。因此,为了知道散列是基于什么,我们只需要知道各种对象的内容

    斑点 一个blob仅仅是一个八位字节流。没别的了。它类似于Unix文件系统中的文件内容概念

    因此,blob的哈希仅基于其内容,而blob没有元数据

    树 树将名称和权限与其他对象(BLOB或树)关联。一棵树就是一个由四个部分组成的列表(权限、类型、哈希、名称)。例如,树可能如下所示:

    100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
    100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
    040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib
    
    blob 12\0Hello, World
    
    请注意第三个条目,它本身就是一棵树

    树类似于Unix文件系统中的目录特殊文件

    同样,散列是基于树的内容的,这意味着它的叶子的名称、权限、类型和散列

    提交 提交会及时记录树的快照以及一些元数据以及快照的生成方式。提交包括:

    • 父提交(包括零)的(任意数量)哈希列表
    • 树丛
    • 提交消息
    • 提交元数据(提交日期和提交者名称)
    • 创作元数据(创作日期和作者姓名)
    提交的哈希值基于这些值

    标签 标记不是上述意义上的对象。它们不是对象存储的一部分,也没有散列。它们是对对象的引用。(注意:任何对象都可以被标记,而不仅仅是提交,尽管这是正常的用例。)

    带注释的标记 带注释的标记是不同的:它是对象存储的一部分

    带注释的标记存储:

    • 提交的散列
    • 标记消息
    • 标记元数据(标记器名称和标记日期)
    与所有其他对象一样,哈希是基于所有对象计算的,仅此而已

    签名标签 签名标记类似于带注释的标记,但添加了加密签名

    笔记 Notes允许您将任意提交与任意Git对象关联

    纸币的存储稍微复杂一些。实际上,注释只是一个提交(包含包含包含注释内容的blob的树)。Git为notes创建了一个特殊的分支,notes提交和它的“annotee对象”之间的关联就发生在这里。我不知道具体是怎么做的

    但是,由于注释只是一个提交,并且关联发生在外部,因此注释的哈希与任何其他提交都是一样的


    存储格式 存储格式包含一个简单的标头。实际存储(和散列)的内容是标头,后跟空八位组,后跟对象内容

    标题包含以ASCII编码的对象内容的类型和长度。因此,包含ASCII编码的字符串
    Hello,World
    的blob如下所示:

    100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
    100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
    040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib
    
    blob 12\0Hello, World
    
    这就是散列和存储的内容

    其他类型的对象具有更结构化的格式,因此树对象将以头
    tree\0
    开始,然后是树的严格定义、结构化、序列化表示

    提交也是如此,以此类推

    大多数格式都是基于简单ASCII的文本格式。例如,大小不是编码为二进制整数,而是编码为十进制整数,每个数字表示为相应的ASCII字符

    压缩 在计算散列之后,使用zlib deflate压缩与包括头部的对象相对应的八位元流,并且基于散列将得到的八位元流存储在文件中;目录中的默认值

    .git/objects/<first two characters of the hash>/<remaining hash>
    
    .git/objects//
    
    包装 上述存储格式称为松散对象格式,因为每个对象都是单独存储的。有一种更有效的存储格式(也用作网络传输格式),称为packfile

    打包文件是一个重要的速度和存储优化工具,但它们相当复杂,所以我不打算详细描述它们

    作为第一种近似方法,packfile由连接到单个文件和第二个文件中的所有未压缩对象组成,该文件包含对象所在packfile中位置的索引。然后将packfile作为一个整体进行压缩,这样可以获得更好的压缩比,因为该算法还可以发现对象之间的冗余,而不仅仅是单个对象内的冗余。(例如,若一个blob有两个几乎相同的修订版……这是SCM中的标准。)

    它不使用zlib deflate,而是使用二进制增量压缩算法。它还使用某些启发式方法来确定如何将对象放置在packfile中,以便将可能具有较大相似性的对象紧密地放置在一起。(delta算法实际上无法一次看到整个packfile,这将消耗太多内存,而是在packfile上的滑动窗口上运行;启发式算法试图确保相似对象落在同一窗口内。)其中一些启发式方法是:查看树与blob关联的名称,尝试将具有相同名称的名称保持在一起,尝试将具有相同文件扩展名的名称保持在一起,尝试将后续修订保持在一起,等等

    闲逛 松散(即未包装)物体为JU