如何设置Git压缩级别?

boo*_*ife 8 git

Git 能够压缩对象和打包文件。如何设置此压缩级别?

通常,答案是设置core.compressionpack.compression

然而,我尝试将它们设置为 1 或 9,然后gc --aggressive在单独的测试中运行repack -a -d。这不会.git以任何有意义的方式改变文件夹的大小。我在 GitHub 上的 14 GB 各种开源存储库上进行了尝试。源代码是高度可压缩的。应该有区别。我使用官方 Git 2.25 在 Windows 上运行了这些测试。

我将这些发现解释为我没有设法改变压缩级别。我怎样才能真正改变 Git 压缩级别?

tor*_*rek 11

重要的

\n

进行重新包装时,请务必使用-F以下方式:

\n
\n

--no-reuse-object选项传递给git-pack-objects

\n
\n

正如文档git repack所述,您发现了。否则,您的新压缩级别将不会应用于任何现有对象。

\n

背景

\n

一共有三个旋钮:

\n
    \n
  • core.compressioncore.loosecompression设置和的默认值pack.compression。如果未明确设置,则其他两个将保留其设置或默认设置。
  • \n
  • core.loosecompression设置 zlib 压缩默认值。如果未设置,则默认为 zlib 自己的“最佳速度”值。
  • \n
  • pack.compression设置包压缩默认值。如果未设置,则默认为 zlib\ 自己的“默认压缩”级别(这可能取决于您的 zlib 但我认为通常为 6;请参阅了解 zlib)。
  • \n
\n

但在包文件中,压缩级别与最终包文件大小的相关性可能要小得多。原因是包文件格式是......好吧,这是技术文档的链接,但我将其总结为通常由增量链主导,而不是通常由文件内容主导

\n

松散对象由zlib 压缩的 Git 标头和原始文件内容组成。在这里,压缩(和级别)通常会产生与您自己进行 zlib 压缩相同的效果,因为标头与典型文件相比非常小,并且这些字节不应干扰子字符串查找。整个对象被压缩,而不考虑任何其他对象。

\n

然而,打包对象可以是基础对象,也可以增量对象。如果打包对象是基础对象,则其压缩可能类似于松散对象的压缩。但是,如果打包对象被增量化,它将由二进制指令组成,而不是文本。这些不太可能压缩得很好。

\n

假设您的 Delta 链平均长度为 20 个对象。这意味着对于每一个基础对象,都有 19 个增量对象。假设压缩对于基础对象效果非常好(例如,压缩到原始大小的 35%),而对于增量对象则效果非常糟糕(例如,压缩到原始大小的 97%)。进一步假设基础对象的平均大小为 64K,增量对象(包括指令)的平均大小为 6.4K。然后将这些数字分别提高到 32% 和 94%\xe2\x80\x94 这可能是现实的,但我还没有进行任何实际测量\xe2\x80\x94 将使我们:

\n
    \n
  • 原值:35%(65536) + 19 * (97%(6554)) = 22938 + 19 * 6537 = 147141
  • \n
  • 9级:32%(65536) + 19 * (94%(6554)) = 20972 + 19 * 6161 = 138031
  • \n
\n

这并没有我们预期的那么大:松散对象会缩小约 8.5%,但打包文件会缩小约 6.5%。

\n

(对真实 Git 数据进行各种打包实验的结果,而不是这些思想实验,会很有趣。更有趣的可能是尝试上面第一个链接中提到的其他一些压缩算法。)

\n