在Git中,"delta"是什么意思?

9

我对 Git 还不熟悉。今天,我通过 Git 终端拉取了一个分支,收到了以下消息:

远程:计数对象:5,完成。

远程:压缩对象:100%(3/3),完成。

远程:共有 3 个文件发生了变化(delta),其中 2 个是新的提交,另外 1 个是旧的提交被修改过。

正在解压对象:100%(3/3),完成。

这里的 delta 指什么?


Delta涉及到压缩文件,我认为。 - Syntax Error
3个回答

15

好的,首先我们需要了解Git如何在存储库中存储数据。最重要的是它始终存储整个文件,换句话说,在概念层面上,Git在每次提交中都会存储项目树的“完全副本”。

好的,但你可能会问,为什么每次提交不会通过新的整个树复制增加存储库的大小。这就是魔法发生的地方。首先让我们看看我们当前树中有2个文件,并已提交。

a.txt
b.txt

当我们更改 b.txt 但保留 a.txt 不变时,我们无需存储 a.txt 的全新副本,只需指向旧的副本(因为其哈希值未更改)。

但是让我们再往前进一步,我们也不需要完整地存储 b.txt 文件,只需存储更改的部分。因此,我们将 b.txt 拆分成已知大小的块,并将 b.txt 节点制作成这些块的列表。通过这种方式,我们可以仅一次存储重复的块,并节省空间。而这些"块"中的每一个都被称为增量(delta)。


这是否意味着一个文件实际上是几个块的合并? - Mandroid
是的,确实可能发生这种情况。 - Hauleth

6

Git使用差异编码,这种编码方式会将数据存储或传输成连续数据之间的差异(delta),而不是完整的文件。

打包中的对象以差异形式存储,即用于对其他对象进行一系列更改的序列。

如需了解更多信息,请点击此处


2
这很令人困惑,因为“deltas”不是差异。Git 不存储差异。 - Hauleth
1
@Hauleth:Git确实不存储(文本)差异,但是增量编码一种差分编码形式。“差异”和“区别”并不相同。 - torek
然而,对于新手来说,使用那种措辞可能非常令人困惑。 - Hauleth

2

相关源代码

if (progress)
    fprintf_ln(stderr,
           _("Total %"PRIu32" (delta %"PRIu32"),"
             " reused %"PRIu32" (delta %"PRIu32")"),
           written, written_delta, reused, reused_delta);

文档: 打包格式

增量数据是一系列指令,用于从基础对象重构对象。如果基础对象被增量化,则必须首先将其转换为规范形式。每个指令都会将更多的数据追加到目标对象中,直到它完成。到目前为止,支持两种指令:一种是从源对象复制字节范围的指令,另一种是插入在指令本身中的新数据。

Git 内部原理 - Packfiles

Git 在磁盘上保存对象的初始格式称为“松散”对象格式。然而,偶尔 Git 会将多个这些对象打包到一个名为“packfile”的单个二进制文件中,以节省空间并提高效率。如果您周围有太多的松散对象,或者手动运行 git gc 命令,或者推送到远程服务器,Git 就会这样做。要查看发生了什么,您可以通过调用 git gc 命令手动要求 Git 打包对象:

$ git gc
Counting objects: 18, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (18/18), done.
Total 18 (delta 3), reused 0 (delta 0)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接