builtin/gc: forward git-gc(1)'s `--auto` flag when packing refs
Forward the `--auto` flag to git-pack-refs(1) when it has been invoked with this flag itself. This does not change anything for the "files" backend, which will continue to eagerly pack refs. But it does ensure that the "reftable" backend only compacts refs as required. This change does not impact git-maintenance(1) because this command will in fact never run the pack-refs task when run with `--auto`. This issue will be addressed in a subsequent commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Mar 25, 2024 at 11:03 UTC
bfc2f9eb8e83f394cc397f978c833edced507923
2 files changed
+28
-12
builtin/gc.c
+12
-9
@@ -212,6 +212,9 @@ static int maintenance_task_pack_refs(MAYBE_UNUSED struct maintenance_run_opts *
212
213
cmd.git_cmd = 1;
214
strvec_pushl(&cmd.args, "pack-refs", "--all", "--prune", NULL);
215
+ if (opts->auto_flag)
216
+ strvec_push(&cmd.args, "--auto");
217
+
218
return run_command(&cmd);
219
}
220
@@ -572,7 +575,7 @@ done:
575
return ret;
576
}
577
575
-static void gc_before_repack(void)
578
+static void gc_before_repack(struct maintenance_run_opts *opts)
579
{
580
/*
581
* We may be called twice, as both the pre- and
@@ -583,7 +586,7 @@ static void gc_before_repack(void)
586
if (done++)
587
return;
588
586
- if (pack_refs && maintenance_task_pack_refs(NULL))
589
+ if (pack_refs && maintenance_task_pack_refs(opts))
590
die(FAILED_RUN, "pack-refs");
591
592
if (prune_reflogs) {
@@ -599,7 +602,6 @@ static void gc_before_repack(void)
602
int cmd_gc(int argc, const char **argv, const char *prefix)
603
{
604
int aggressive = 0;
602
- int auto_gc = 0;
605
int quiet = 0;
606
int force = 0;
607
const char *name;
@@ -608,6 +610,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
610
int keep_largest_pack = -1;
611
timestamp_t dummy;
612
struct child_process rerere_cmd = CHILD_PROCESS_INIT;
613
+ struct maintenance_run_opts opts = {0};
614
615
struct option builtin_gc_options[] = {
616
OPT__QUIET(&quiet, N_("suppress progress reporting")),
@@ -618,7 +621,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
621
OPT_MAGNITUDE(0, "max-cruft-size", &max_cruft_size,
622
N_("with --cruft, limit the size of new cruft packs")),
623
OPT_BOOL(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")),
621
- OPT_BOOL_F(0, "auto", &auto_gc, N_("enable auto-gc mode"),
624
+ OPT_BOOL_F(0, "auto", &opts.auto_flag, N_("enable auto-gc mode"),
625
PARSE_OPT_NOCOMPLETE),
626
OPT_BOOL_F(0, "force", &force,
627
N_("force running gc even if there may be another gc running"),
@@ -663,7 +666,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
666
if (quiet)
667
strvec_push(&repack, "-q");
668
666
- if (auto_gc) {
669
+ if (opts.auto_flag) {
670
/*
671
* Auto-gc should be least intrusive as possible.
672
*/
@@ -688,7 +691,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
691
692
if (lock_repo_for_gc(force, &pid))
693
return 0;
691
- gc_before_repack(); /* dies on failure */
694
+ gc_before_repack(&opts); /* dies on failure */
695
delete_tempfile(&pidfile);
696
697
/*
@@ -713,7 +716,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
716
717
name = lock_repo_for_gc(force, &pid);
718
if (name) {
716
- if (auto_gc)
719
+ if (opts.auto_flag)
720
return 0; /* be quiet on --auto */
721
die(_("gc is already running on machine '%s' pid %"PRIuMAX" (use --force if not)"),
722
name, (uintmax_t)pid);
@@ -728,7 +731,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
731
atexit(process_log_file_at_exit);
732
}
733
731
- gc_before_repack();
734
+ gc_before_repack(&opts);
735
736
if (!repository_format_precious_objects) {
737
struct child_process repack_cmd = CHILD_PROCESS_INIT;
@@ -783,7 +786,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
786
!quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,
787
NULL);
788
786
- if (auto_gc && too_many_loose_objects())
789
+ if (opts.auto_flag && too_many_loose_objects())
790
warning(_("There are too many unreachable loose objects; "
791
"run 'git prune' to remove them."));
792
t/t0610-reftable-basics.sh
+16
-3
@@ -387,7 +387,9 @@ test_expect_success 'pack-refs: compaction raises locking errors' '
387
test_cmp expect err
388
'
389
390
-test_expect_success 'pack-refs: auto compaction' '
390
+for command in pack-refs gc
391
+do
392
+test_expect_success "$command: auto compaction" '
393
test_when_finished "rm -rf repo" &&
394
git init repo &&
395
(
@@ -395,14 +397,24 @@ test_expect_success 'pack-refs: auto compaction' '
397
398
test_commit A &&
399
400
+ # We need a bit of setup to ensure that git-gc(1) actually
401
+ # triggers, and that it does not write anything to the refdb.
402
+ git config gc.auto 1 &&
403
+ git config gc.autoDetach 0 &&
404
+ git config gc.reflogExpire never &&
405
+ git config gc.reflogExpireUnreachable never &&
406
+ test_oid blob17_1 | git hash-object -w --stdin &&
407
+
408
# The tables should have been auto-compacted, and thus auto
409
# compaction should not have to do anything.
410
ls -1 .git/reftable >tables-expect &&
411
test_line_count = 4 tables-expect &&
402
- git pack-refs --auto &&
412
+ git $command --auto &&
413
ls -1 .git/reftable >tables-actual &&
414
test_cmp tables-expect tables-actual &&
415
416
+ test_oid blob17_2 | git hash-object -w --stdin &&
417
+
418
# Lock all tables write some refs. Auto-compaction will be
419
# unable to compact tables and thus fails gracefully, leaving
420
# the stack in a sub-optimal state.
@@ -416,10 +428,11 @@ test_expect_success 'pack-refs: auto compaction' '
428
rm .git/reftable/*.lock &&
429
test_line_count = 5 .git/reftable/tables.list &&
430
419
- git pack-refs --auto &&
431
+ git $command --auto &&
432
test_line_count = 1 .git/reftable/tables.list
433
)
434
'
435
+done
436
437
test_expect_success 'pack-refs: prunes stale tables' '
438
test_when_finished "rm -rf repo" &&