Git 2.33.0 正式发布

1,496

开源 Git 项目昨天发布了 Git 2.33,其中包含来自超过 74 个贡献者的功能和错误修复,其中 19 个是新贡献者。

几何重装

从历史版本看,git repack做了两件事之一:要么将所有松散对象重新打包到一个新包中(可选地删除每个对象的松散副本),要么将所有包重新打包成一个新包(可选地删除冗余包)。

一般来说,当包较少时,Git 具有更好的性能,因为许多操作会随着存储库中包的数量而扩展。因此,将所有东西都打包成一个包通常是个好办法。但从历史版本看,繁忙的存储库通常需要将它们的所有内容打包成一个巨大的包。这是因为可达性位图是服务器端 Git 性能的关键优化,只能描述单个包中的对象。因此,如果您想使用位图有效地覆盖存储库中的许多对象,则这些对象必须一起存储在同一个包中。

开发团队正在努力消除该限制,但在此过程中的一个重要步骤是实施一种新的重新包装方案,该方案在相对较少的包装数量和包装之间进行权衡将最近添加的对象放在一起(换句话说,近似自上一个 以来添加的新对象repack)。

为此,Git 学习了一种新的“几何”重新打包策略。这个想法是确定一组(小)可以组合在一起的包,以便剩余的包根据对象大小形成几何级数。换句话说,如果最小的包有N对象,那么下一个最大的包将至少有2N对象,依此类推,在此过程中的每一步都加倍(或以任意常数增长)。

为了更好地理解它是如何工作的,让我们通过一个关于七包的例子来工作。首先,Git 根据它们包含的对象数量(每个方块内的数字)按升序排列所有包(下面用绿色或红色方块表示)。然后,比较相邻的包(从最大的包开始并朝着较小的包开始)以确保存在几何级数:

image.png

在这里,进展在第二包和第三包之间被打破。这是因为这两个包都有相同数量的对象(在这种情况下,只有一个)。Git 然后决定至少前两个包将包含在一个新包中,该包旨在恢复几何级数。然后它需要弄清楚还必须卷起多少个较大的包才能保持进度:

Scaling-monorepo-maintenance-fig-12.png

合并前两个包会给我们两个对象,这仍然太大而无法适应进程(因为下一个最大的包只有一个对象)。但是将前四包卷起来就足够了,因为第五包包含的对象是前四包加起来的两倍多:

image.png

您可以通过使用以下脚本比较几何重新打包前后笔记本电脑上存储库上的打包大小来自己尝试:

$ packsizes() {
    find .git/objects/pack -type f -name '*.pack' |
    while read pack; do
      printf "%7d %s\n" \
        "$(git show-index < ${pack%.pack}.idx | wc -l)" "$pack"
    done | sort -rn
  }
$ packsizes # before
$ git repack --geometric=2 -d
$ packsizes # after

我们也做出了贡献补丁写入新的磁盘上的反向索引格式的多包索引。通过允许 Git 将位位置映射回多包索引中的对象,这种格式最终将用于支持多包位图。

总之,这两个功能将使使用可达性位图覆盖生成的包中的对象成为可能,即使剩余的包不止一个。这些补丁仍在完善和审查中,但期待我们在将它们合并到版本中时进行更新。

原文:github.blog/2021-08-16-…