[PATCH 1/2] maintenance: account for promisor pack geometry
Taylor Blau <[email protected]> Tue, 4 Aug 2026 20:57:40 -0700
| Newsgroups | org.kernel.vger.git |
|---|---|
| Message-ID | <a9de123b43efb58c53c99c71eb7e34f29e075071.1785902237.git.ttaylorr@openai.com> |
Commit 9bc151850c (builtin/maintenance: introduce "geometric-repack" task, 2025-10-24) added a new maintenance task to perform either a geometric repack, or an all-into-one repack if the geometric repack would itself produce a single pack. Some time later, commit dcc9c7ef47 (builtin/repack: handle promisor packs with geometric repacking, 2026-01-05) taught the geometric repacking machinery to separate promisor packs from ordinary ones, but did not update the maintenance task accordingly. As a consequence, the geometric-repack maintenance task only considers the non-promisor pack progression. It falls back to all-into-one whenever a geometric repack would roll up all non-promisor packs into a single pack, even if the promisor progression would keep a large pack and roll up only smaller ones. Check both progressions before choosing the repack mode. If either leaves a pack above its split, geometric repack still avoids rewriting that pack, whereas the all-into-one fallback would rewrite it. Use the fallback only when neither progression leaves a pack behind. That preserves the reason for the fallback: let the all-into-one repack handle unreachable objects when it is not rewriting more packs than the geometric repack. Signed-off-by: Taylor Blau <[email protected]> --- builtin/gc.c | 3 ++- t/t7900-maintenance.sh | 45 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/builtin/gc.c b/builtin/gc.c index 49c8474fad..ed75c12c43 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1593,7 +1593,8 @@ static int maintenance_task_geometric_repack(struct maintenance_run_opts *opts, child.odb_to_close = the_repository->objects; strvec_pushl(&child.args, "repack", "-d", "-l", NULL); - if (geometry.split < geometry.pack_nr) + if (geometry.split < geometry.pack_nr || + geometry.promisor_split < geometry.promisor_pack_nr) strvec_pushf(&child.args, "--geometric=%d", geometry.split_factor); else diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index a8d691719d..ba5b359e77 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -659,6 +659,51 @@ test_expect_success 'geometric repacking task' ' ) ' +objdir=.git/objects +packdir=$objdir/pack + +pack_promisor () { + p="$(echo "$@" | git pack-objects --revs $packdir/pack)" && + touch "$packdir/pack-$p.promisor" && + echo "$p" +} + +test_expect_success 'geometric repacking task handles promisor packs' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git config set maintenance.auto false && + git remote add promisor garbage && + git config set remote.promisor.promisor true && + + for n in $(test_seq 6) + do + test_commit $n || return 1 + done && + + A="$(pack_promisor 1)" && + B="$(pack_promisor 1..2)" && + C="$(pack_promisor 2..6)" && + git prune-packed && + + ls $packdir/pack-*.promisor | sort >promisors.before && + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \ + git maintenance run --quiet --task=geometric-repack && + ls $packdir/pack-*.promisor | sort >promisors.after && + + test_subcommand git repack -d -l --geometric=2 \ + --quiet --write-midx <trace2.txt && + + test_line_count = 2 promisors.after && + + printf "$packdir/pack-%s.promisor\n" "$A" "$B" | sort >expect && + comm -23 promisors.before promisors.after >actual && + + test_cmp expect actual + ) +' + test_geometric_repack_needed () { NEEDED="$1" GEOMETRIC_CONFIG="$2" && -- 2.55.0.483.gdc2fffc37c