The full repack cost
Traditional git gc runs git repack -ad, rewriting all objects into one packfile. On a multi-gigabyte repo, this is hours of CPU and IO. Geometric repacking (Git 2.32+) avoids this by maintaining a series of packs whose sizes follow a geometric progression — only the smallest are merged each cycle.
How it works
Pack sizes form a sequence where each pack is at least N times larger than the next smaller. When the invariant is violated (small packs accumulate from frequent fetches), Git merges only the offenders into a new pack, leaving the largest pack untouched. The aggregate cost over time is O(total objects × log) instead of O(total objects) per gc.
Running
git repack --geometric=2 -d
git repack --geometric=2 -d --write-midx
git config maintenance.incremental-repack.enabled true
The factor (2 here) is the size ratio. Larger factors mean fewer, larger packs; smaller factors mean more, smaller packs.
Pairing with MIDX
Geometric repack produces multiple packs by design. Without an MIDX, lookups slow down. Always pair them:
git config core.multiPackIndex true
git multi-pack-index write
git multi-pack-index expire
See "Multi-pack-index (MIDX): unified pack object lookup".
Background maintenance
git maintenance includes an incremental-repack task that runs geometric repack plus MIDX upkeep:
git maintenance start
git maintenance run --task=incremental-repack
When to force full repack
After massive history rewrites (filter-repo, big rebases), the largest pack contains many unreachable objects. Run a full repack occasionally:
git repack -ad --depth=50 --window=250 --write-midx --write-bitmap-index
Server-side considerations
Forge servers (GitHub, GitLab, Gitea) use geometric repack at scale. Self-hosted Gitea 1.20+ enables it by default. For raw bare repos behind ssh, configure manually.
Common mistakes
Running geometric repack without MIDX — performance regresses as packs accumulate. Setting the factor too small (e.g., 1.1) — packs proliferate. Mixing manual git gc with git maintenance; pick one.
Common values
- Default
--geometric=2: balanced. --geometric=4: fewer, larger packs; less frequent merges.--geometric=1.5: more aggressive merging.
Related
See "Multi-pack-index (MIDX): unified pack object lookup", "Background maintenance: git maintenance run/start/stop", and "Git garbage collection: gc, prune, and pack-refs".