【问题标题】:Why does Git hash only the Contents of A File?为什么 Git 只对文件的内容进行哈希处理?
【发布时间】:2017-11-24 01:35:33
【问题描述】:

this post,计算Git中文件的哈希

    Commit Hash (SHA1) = SHA1("blob " + <size_of_file> + "\0" + <contents_of_file>)

我自己测试了两个空文件是否正确:

    100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       empty1.txt
    100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       empty2.txt

但是为什么 Git 会从哈希中排除文件名呢?它如何区分empty1.txt 和empty2.txt?

如果我将 empty1.txt 的名称更改为 empty2.txt,当我调用 git status 时,Git 如何跟踪该更改?

【问题讨论】:

  • Git 通过树形结构管理工作目录。在该树结构中,文件名以字典方式映射到 SHA-1 blob。所以树维护文件名和 SHA-1 之间的关系,而不是 blob 本身。
  • 这个树结构是一个显式对象(例如 HashMap)吗?这个树结构和 Git 的结构是一样的吗——提交、树、blob、标签?
  • 我不知道你所说的“显式”对象是什么意思,但是它存储在某个地方。是的,它是 Git 使用的四个对象之一。
  • 嗯,有道理——所以当调用 status 时,Git 只是在提交树与其父树之间进行比较,对吧?
  • 我不确定……我对 Git 实现的了解相当有限。我只是想指出,blob SHA-1 并不是唯一用于识别文件的东西,这些 blob 是树结构的一部分。

标签: git hash


【解决方案1】:

但是为什么 Git 会从哈希中排除文件名呢?怎么区分empty1.txt和empty2.txt?

因为 Git 管理 content(如果两个文件的内容相同,它们的 SHA1 也会相同)。

文件名称tree (directory content)管理,它列出了给定文件夹中的文件。

$ git cat-file -p 3c4e9cd789d88d8d89c1073707c3585e41b0e614
040000 tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579      bak
100644 blob fa49b077972391ad58037050f2a75f74e3671e92      new.txt
100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a      test.txt

【讨论】:

  • 因此,如果我理解正确,Git 会创建一个包含索引中列出的对象的树。对象(树、blob)的类型是否连同其 SHA-1 一起存储在该文件中?那么,Git 是如何使用这个索引/树来检测哪些文件被修改、未跟踪或删除的呢?
  • 索引树本身是否与提交无关?当我打开存储库的索引时,我注意到它已被序列化。
  • @SlackOverflow 该类型是 SHA1 的一部分:stackoverflow.com/a/21361195/6309
  • 编辑:alblue.bandlem.com/2011/10/… 似乎表明情况并非如此。不过,我想知道 index 如何在不作为对象的情况下进行快速比较。
  • @SlackOverflow git 状态最近有所改善:stackoverflow.com/a/43667992/6309
猜你喜欢
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 2021-06-18
  • 2019-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多