松散对象多到多少才会自动 gc?文档说 6700,但 git 并不真的数 6700 个。这篇用精确构造的 26、27、28 个对象和随机分布的几千个对象,把触发点测出来,再看 gc 之后还会不会再触发,以及 pack 数量这个另一条触发条件。
$ git config --get gc.auto || echo "gc.auto 未设置(git 默认 6700)" gc.auto 未设置(git 默认 6700) (6700 + 255) // 256 = 27:objects/17 里松散对象超过 27 个才触发
git gc --auto 不去数全部松散对象——那太贵。它只数 .git/objects/17 一个目录里的文件,和 (gc.auto + 255) / 256 比较,默认 gc.auto 是 6700,阈值 27,超过才触发。因为对象 hash 均匀分布,一个目录约占 1/256。
objects/17 里 26 个 → git gc --auto 输出: (没有输出,什么也没做) objects/17 里 27 个 → git gc --auto 输出: (没有输出,什么也没做) objects/17 里 28 个 → git gc --auto 输出: Auto packing the repository for optimum performance. / See "git help gc" for manual housekeeping. / warning: There are too many unreachable loose objects; run 'git prune' to remove them.
人为往 objects/17 里放 26、27、28 个对象:27 个仍不触发,28 个触发。这证实了是“超过 27”。
松散对象总数 objects/17 个数 触发 gc --auto
5,000 14 否
6,000 27 否
6,500 33 是
6,700 17 否
7,000 32 是
7,500 35 是
8,000 29 是随机分布的对象让 objects/17 的个数上下波动:6,000 个对象时 27 个(没触发),6,700 个时只有 17 个(没触发),6,500 个时 33 个(触发)。所以“松散对象 6700 个触发”只是个大概的数。
第一次触发之后 objects/17 里还有 28 个松散对象
第 1 次再执行 git gc --auto:
Auto packing the repository for optimum performance.
See "git help gc" for manual housekeeping.
Nothing new to pack.
warning: There are too many unreachable loose objects; run 'git prune' to remove them.
第 2 次再执行 git gc --auto:
Auto packing the repository for optimum performance.
See "git help gc" for manual housekeeping.
Nothing new to pack.
warning: There are too many unreachable loose objects; run 'git prune' to remove them.
两次之后 objects/17 里仍有 28 个自动 gc 会打包可达对象,但不可达的松散对象不满过期时间是不会被清理的,于是 objects/17 里的数量不变,下一次 gc --auto 又会触发并警告 too many unreachable loose objects。要清理它们得 git prune 或等它们过期。
现在有 50 个 pack git gc --auto → (没有输出);pack 数 50 再多一个:51 个 pack git gc --auto → Auto packing the repository for optimum performance. / See "git help gc" for manual housekeeping.;pack 数 1
另一个条件是 pack 数量:超过 gc.autoPackLimit(默认 50)就会触发,把它们合并成一个。