Git 中基于内容的寻址有哪些好处?

coo*_*bit 2 git sha

问题:

Git 使用基于内容的文件寻址系统(即它使用 blob 和树哈希作为“文件名”)。我想知道这种寻址系统有什么好处?

我可以清楚地看到一些好处,但这些好处都是次要的:

  1. 如果有人更改 git 存储库中的某些文件,它将破坏指向该文件的所有提交。因此,您肯定会知道发生了不好的事情。但它真的那么有用吗?
  2. 对文件使用哈希可以将真实文件名与其内容分离,因此您可以“便宜地”重命名文件......

我觉得使用 sha 进行文件寻址的真正原因是完全不同的。谁能解释一下吗?

PS澄清。问题是为什么 Git 使用哈希来寻址文件,而不是它是如何做到的。我知道如何做,我需要知道为什么。

PPS 有一篇关于 Git 原理的文章以及为什么 Git 看起来如此奇怪(因为它应该在除了核心操作系统和文本编辑器之外没有其他软件的机器上使用),但这篇文章仍然只提到了这个原因:

如果您计算文件的 sha 并且该 sha 已经在对象文件夹中,那么您就知道不需要再次存储它,因为 sha 取决于内容。

好吧,这就是我明白的原因。还有其他原因为什么要使用内容可寻址文件系统

Mar*_*ger 6

git 需要做的最常见的事情之一就是比较项目的两个版本。由于对象存储(提交、树和 blob)是内容可寻址的,因此可以通过比较“文件名”非常快速地完成此操作。

此外,在存储内容时,很容易看出它是否是您已经存储的内容的副本,因此您可以避免存储重复项。

  • 不,git 不会重新计算工作目录中所有文件的哈希值。它依赖 fstat 来了解工作文件是否可能发生更改(除非有人故意试图隐藏更改,否则这是可靠的) - 并且它可以配置为跳过该检查以及子目录,即使这样也会浪费时间时间。另外,这在您“添加”时相关,而不是在“提交”时相关,后者并不真正涉及工作目录。“添加”过程会计算任何可能更改的对象的哈希值,并根据需要将其存储在索引中 (2认同)

Sta*_*sev 6

该哈希值是对象的唯一 ID。您可以对存储在数据库中的 blob 执行相同的操作 - 计算哈希值并将其设为 ID。其优点如下:

  1. 重复数据删除。如果您有相同的 blob(Git 中的相同文件) - 您不会复制数据 - 它将被存储一次并从不同的位置引用。意思就是:
    • 您可以复制相同的文件或文件夹,并且 Git“数据库”中不会有任何重复项,只有对同一 blob 的多个引用。因此,要存储/传输的空间量被最小化。
    • 当您重命名/移动文件时 - 它们的内容不会以不同的名称再次添加到 Git。Git 将生成相同的哈希值,因此将很快识别出不需要创建新对象。同样,相同的对象将从不同的位置引用。
    • 如果您逐个提交删除文件,然后在另一个提交中再次添加它 - 仍然不会创建新对象,因为旧对象仍然驻留在 中.git(它们被旧提交引用,因此必须保留在 中.git)。
  2. 另外,如何快速显示两次提交之间的差异?对于 Git 来说,这很容易,因为文件夹只是引用 blob 和其他文件夹的对象(树) - 并且此信息也是内容可寻址的。因此,如果树(文件夹)现在引用不同的 blob/树(或它们的名称已更改),则基于哈希的 ID 将更改。因此,Git 可以首先检查树(文件夹)的哈希值,看看它们的内容是否不同,以及 Git 是否需要介入来检查其他差异。
  3. 您不必存储有关哪个代理ID 引用哪些数据的额外数据库(元信息)。可以从内容中推断出ID。

PS:虽然第 1-2 点也可以通过代理 ID 来实现,但您只需将哈希值与这些 ID一起存储即可。因此,在存储新文件之前,您必须计算其哈希值并通过数据库中的哈希值查找代理 ID。不太方便,但可能。