我对 Git 还不熟悉。今天,我通过 Git 终端拉取了一个分支,收到了以下消息:
远程:计数对象:5,完成。
远程:压缩对象:100%(3/3),完成。
远程:共有 3 个文件发生了变化(delta),其中 2 个是新的提交,另外 1 个是旧的提交被修改过。
正在解压对象:100%(3/3),完成。
这里的 delta 指什么?
我对 Git 还不熟悉。今天,我通过 Git 终端拉取了一个分支,收到了以下消息:
远程:计数对象:5,完成。
远程:压缩对象:100%(3/3),完成。
远程:共有 3 个文件发生了变化(delta),其中 2 个是新的提交,另外 1 个是旧的提交被修改过。
正在解压对象:100%(3/3),完成。
这里的 delta 指什么?
好的,首先我们需要了解Git如何在存储库中存储数据。最重要的是它始终存储整个文件,换句话说,在概念层面上,Git在每次提交中都会存储项目树的“完全副本”。
好的,但你可能会问,为什么每次提交不会通过新的整个树复制增加存储库的大小。这就是魔法发生的地方。首先让我们看看我们当前树中有2个文件,并已提交。
a.txt
b.txt
当我们更改 b.txt
但保留 a.txt
不变时,我们无需存储 a.txt
的全新副本,只需指向旧的副本(因为其哈希值未更改)。
但是让我们再往前进一步,我们也不需要完整地存储 b.txt
文件,只需存储更改的部分。因此,我们将 b.txt
拆分成已知大小的块,并将 b.txt
节点制作成这些块的列表。通过这种方式,我们可以仅一次存储重复的块,并节省空间。而这些"块"中的每一个都被称为增量(delta)。
if (progress)
fprintf_ln(stderr,
_("Total %"PRIu32" (delta %"PRIu32"),"
" reused %"PRIu32" (delta %"PRIu32")"),
written, written_delta, reused, reused_delta);
增量数据是一系列指令,用于从基础对象重构对象。如果基础对象被增量化,则必须首先将其转换为规范形式。每个指令都会将更多的数据追加到目标对象中,直到它完成。到目前为止,支持两种指令:一种是从源对象复制字节范围的指令,另一种是插入在指令本身中的新数据。
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)