builtin/maintenance: make the geometric factor configurable

The geometric repacking task uses a factor of two for its geometric sequence, meaning that each next pack must contain at least twice as many objects as the next-smaller one. In some cases it may be helpful to configure this factor though to reduce the number of packfile merges even further, e.g. in very big repositories. But while git-repack(1) itself supports doing this, the maintenance task does not give us a way to tune it. Introduce a new "maintenance.geometric-repack.splitFactor" configuration to plug this gap. Signed-off-by: Patrick Steinhardt <ps@pks.im> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Oct 24, 2025 at 08:57 UTC 5c2ad50193896dc74e51e4b7a5af4ea734746316
3 files changed +45 -1
Documentation/config/maintenance.adoc
+5
@@ -86,6 +86,11 @@ maintenance.geometric-repack.auto::
86 objects that would be written into a new packfile. The default value is
87 100.
88
89 +maintenance.geometric-repack.splitFactor::
90 + This integer config option controls the factor used for the geometric
91 + sequence. See the `--geometric=` option in linkgit:git-repack[1] for
92 + more details. Defaults to `2`.
93 +
94 maintenance.reflog-expire.auto::
95 This integer config option controls how often the `reflog-expire` task
96 should be run as part of `git maintenance run --auto`. If zero, then
builtin/gc.c
+8 -1
@@ -1582,6 +1582,9 @@ static int maintenance_task_geometric_repack(struct maintenance_run_opts *opts,
1582 struct child_process child = CHILD_PROCESS_INIT;
1583 int ret;
1584
1585 + repo_config_get_int(the_repository, "maintenance.geometric-repack.splitFactor",
1586 + &geometry.split_factor);
1587 +
1588 existing_packs.repo = the_repository;
1589 existing_packs_collect(&existing_packs, &kept_packs);
1590 pack_geometry_init(&geometry, &existing_packs, &po_args);
@@ -1591,7 +1594,8 @@ static int maintenance_task_geometric_repack(struct maintenance_run_opts *opts,
1594
1595 strvec_pushl(&child.args, "repack", "-d", "-l", NULL);
1596 if (geometry.split < geometry.pack_nr)
1594 - strvec_push(&child.args, "--geometric=2");
1597 + strvec_pushf(&child.args, "--geometric=%d",
1598 + geometry.split_factor);
1599 else
1600 add_repack_all_option(cfg, NULL, &child.args);
1601 if (opts->quiet)
@@ -1632,6 +1636,9 @@ static int geometric_repack_auto_condition(struct gc_config *cfg UNUSED)
1636 if (auto_value < 0)
1637 return 1;
1638
1639 + repo_config_get_int(the_repository, "maintenance.geometric-repack.splitFactor",
1640 + &geometry.split_factor);
1641 +
1642 existing_packs.repo = the_repository;
1643 existing_packs_collect(&existing_packs, &kept_packs);
1644 pack_geometry_init(&geometry, &existing_packs, &po_args);
t/t7900-maintenance.sh
+32
@@ -603,6 +603,38 @@ test_expect_success 'geometric repacking with --auto' '
603 )
604 '
605
606 +test_expect_success 'geometric repacking honors configured split factor' '
607 + test_when_finished "rm -rf repo" &&
608 + git init repo &&
609 + (
610 + cd repo &&
611 + git config set maintenance.auto false &&
612 +
613 + # Create three different packs with 9, 2 and 1 object, respectively.
614 + # This is done so that only a subset of packs would be merged
615 + # together so that we can verify that `git repack` receives the
616 + # correct geometric factor.
617 + for i in $(test_seq 9)
618 + do
619 + echo first-$i | git hash-object -w --stdin -t blob || return 1
620 + done &&
621 + git repack --geometric=2 -d &&
622 +
623 + for i in $(test_seq 2)
624 + do
625 + echo second-$i | git hash-object -w --stdin -t blob || return 1
626 + done &&
627 + git repack --geometric=2 -d &&
628 +
629 + echo third | git hash-object -w --stdin -t blob &&
630 + git repack --geometric=2 -d &&
631 +
632 + test_geometric_repack_needed false splitFactor=2 &&
633 + test_geometric_repack_needed true splitFactor=3 &&
634 + test_subcommand git repack -d -l --geometric=3 --quiet --write-midx <trace2.txt
635 + )
636 +'
637 +
638 test_expect_success 'pack-refs task' '
639 for n in $(test_seq 1 5)
640 do