Skip to content

Commit 0ea94b0

Browse files
pks-tgitster
authored andcommitted
builtin/gc: remove global repack variable
The global `repack` variable is used to store all command line arguments that we eventually want to pass to git-repack(1). It is being appended to from multiple different functions, which makes it hard to follow the logic. Besides being hard to follow, it also makes it unnecessarily hard to reuse this infrastructure in new code. Refactor the code so that we store this variable on the stack and pass a pointer to it around as needed. This is done so that we can reuse `add_repack_all_options()` in a subsequent commit. The refactoring itself is straight-forward. One function that deserves attention though is `need_to_gc()`: this function determines whether or not we need to execute garbage collection for `git gc --auto`, but also for `git maintenance run --auto`. But besides figuring out whether we have to perform GC, the function also sets up the `repack` arguments. For `git gc --auto` it's trivial to adapt, as we already have the on-stack variable at our fingertips. But for the maintenance condition it's less obvious what to do. As it turns out, we can just use another temporary variable there that we then immediately discard. If we need to perform GC we execute a child git-gc(1) process to repack objects for us, and that process will have to recompute the arguments anyway. Signed-off-by: Patrick Steinhardt <ps@pks.im> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 8bca1c5 commit 0ea94b0

1 file changed

Lines changed: 45 additions & 29 deletions

File tree

builtin/gc.c

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ static const char * const builtin_gc_usage[] = {
5555
};
5656

5757
static timestamp_t gc_log_expire_time;
58-
static struct strvec repack = STRVEC_INIT;
5958
static struct tempfile *pidfile;
6059
static struct lock_file log_lock;
6160
static struct string_list pack_garbage = STRING_LIST_INIT_DUP;
@@ -618,48 +617,50 @@ static uint64_t estimate_repack_memory(struct gc_config *cfg,
618617
return os_cache + heap;
619618
}
620619

621-
static int keep_one_pack(struct string_list_item *item, void *data UNUSED)
620+
static int keep_one_pack(struct string_list_item *item, void *data)
622621
{
623-
strvec_pushf(&repack, "--keep-pack=%s", basename(item->string));
622+
struct strvec *args = data;
623+
strvec_pushf(args, "--keep-pack=%s", basename(item->string));
624624
return 0;
625625
}
626626

627627
static void add_repack_all_option(struct gc_config *cfg,
628-
struct string_list *keep_pack)
628+
struct string_list *keep_pack,
629+
struct strvec *args)
629630
{
630631
if (cfg->prune_expire && !strcmp(cfg->prune_expire, "now")
631632
&& !(cfg->cruft_packs && cfg->repack_expire_to))
632-
strvec_push(&repack, "-a");
633+
strvec_push(args, "-a");
633634
else if (cfg->cruft_packs) {
634-
strvec_push(&repack, "--cruft");
635+
strvec_push(args, "--cruft");
635636
if (cfg->prune_expire)
636-
strvec_pushf(&repack, "--cruft-expiration=%s", cfg->prune_expire);
637+
strvec_pushf(args, "--cruft-expiration=%s", cfg->prune_expire);
637638
if (cfg->max_cruft_size)
638-
strvec_pushf(&repack, "--max-cruft-size=%lu",
639+
strvec_pushf(args, "--max-cruft-size=%lu",
639640
cfg->max_cruft_size);
640641
if (cfg->repack_expire_to)
641-
strvec_pushf(&repack, "--expire-to=%s", cfg->repack_expire_to);
642+
strvec_pushf(args, "--expire-to=%s", cfg->repack_expire_to);
642643
} else {
643-
strvec_push(&repack, "-A");
644+
strvec_push(args, "-A");
644645
if (cfg->prune_expire)
645-
strvec_pushf(&repack, "--unpack-unreachable=%s", cfg->prune_expire);
646+
strvec_pushf(args, "--unpack-unreachable=%s", cfg->prune_expire);
646647
}
647648

648649
if (keep_pack)
649-
for_each_string_list(keep_pack, keep_one_pack, NULL);
650+
for_each_string_list(keep_pack, keep_one_pack, args);
650651

651652
if (cfg->repack_filter && *cfg->repack_filter)
652-
strvec_pushf(&repack, "--filter=%s", cfg->repack_filter);
653+
strvec_pushf(args, "--filter=%s", cfg->repack_filter);
653654
if (cfg->repack_filter_to && *cfg->repack_filter_to)
654-
strvec_pushf(&repack, "--filter-to=%s", cfg->repack_filter_to);
655+
strvec_pushf(args, "--filter-to=%s", cfg->repack_filter_to);
655656
}
656657

657-
static void add_repack_incremental_option(void)
658+
static void add_repack_incremental_option(struct strvec *args)
658659
{
659-
strvec_push(&repack, "--no-write-bitmap-index");
660+
strvec_push(args, "--no-write-bitmap-index");
660661
}
661662

662-
static int need_to_gc(struct gc_config *cfg)
663+
static int need_to_gc(struct gc_config *cfg, struct strvec *repack_args)
663664
{
664665
/*
665666
* Setting gc.auto to 0 or negative can disable the
@@ -700,10 +701,10 @@ static int need_to_gc(struct gc_config *cfg)
700701
string_list_clear(&keep_pack, 0);
701702
}
702703

703-
add_repack_all_option(cfg, &keep_pack);
704+
add_repack_all_option(cfg, &keep_pack, repack_args);
704705
string_list_clear(&keep_pack, 0);
705706
} else if (too_many_loose_objects(cfg))
706-
add_repack_incremental_option();
707+
add_repack_incremental_option(repack_args);
707708
else
708709
return 0;
709710

@@ -852,6 +853,7 @@ int cmd_gc(int argc,
852853
int keep_largest_pack = -1;
853854
int skip_foreground_tasks = 0;
854855
timestamp_t dummy;
856+
struct strvec repack_args = STRVEC_INIT;
855857
struct maintenance_run_opts opts = MAINTENANCE_RUN_OPTS_INIT;
856858
struct gc_config cfg = GC_CONFIG_INIT;
857859
const char *prune_expire_sentinel = "sentinel";
@@ -891,7 +893,7 @@ int cmd_gc(int argc,
891893
show_usage_with_options_if_asked(argc, argv,
892894
builtin_gc_usage, builtin_gc_options);
893895

894-
strvec_pushl(&repack, "repack", "-d", "-l", NULL);
896+
strvec_pushl(&repack_args, "repack", "-d", "-l", NULL);
895897

896898
gc_config(&cfg);
897899

@@ -914,14 +916,14 @@ int cmd_gc(int argc,
914916
die(_("failed to parse prune expiry value %s"), cfg.prune_expire);
915917

916918
if (aggressive) {
917-
strvec_push(&repack, "-f");
919+
strvec_push(&repack_args, "-f");
918920
if (cfg.aggressive_depth > 0)
919-
strvec_pushf(&repack, "--depth=%d", cfg.aggressive_depth);
921+
strvec_pushf(&repack_args, "--depth=%d", cfg.aggressive_depth);
920922
if (cfg.aggressive_window > 0)
921-
strvec_pushf(&repack, "--window=%d", cfg.aggressive_window);
923+
strvec_pushf(&repack_args, "--window=%d", cfg.aggressive_window);
922924
}
923925
if (opts.quiet)
924-
strvec_push(&repack, "-q");
926+
strvec_push(&repack_args, "-q");
925927

926928
if (opts.auto_flag) {
927929
if (cfg.detach_auto && opts.detach < 0)
@@ -930,7 +932,7 @@ int cmd_gc(int argc,
930932
/*
931933
* Auto-gc should be least intrusive as possible.
932934
*/
933-
if (!need_to_gc(&cfg)) {
935+
if (!need_to_gc(&cfg, &repack_args)) {
934936
ret = 0;
935937
goto out;
936938
}
@@ -952,7 +954,7 @@ int cmd_gc(int argc,
952954
find_base_packs(&keep_pack, cfg.big_pack_threshold);
953955
}
954956

955-
add_repack_all_option(&cfg, &keep_pack);
957+
add_repack_all_option(&cfg, &keep_pack, &repack_args);
956958
string_list_clear(&keep_pack, 0);
957959
}
958960

@@ -1014,9 +1016,9 @@ int cmd_gc(int argc,
10141016

10151017
repack_cmd.git_cmd = 1;
10161018
repack_cmd.close_object_store = 1;
1017-
strvec_pushv(&repack_cmd.args, repack.v);
1019+
strvec_pushv(&repack_cmd.args, repack_args.v);
10181020
if (run_command(&repack_cmd))
1019-
die(FAILED_RUN, repack.v[0]);
1021+
die(FAILED_RUN, repack_args.v[0]);
10201022

10211023
if (cfg.prune_expire) {
10221024
struct child_process prune_cmd = CHILD_PROCESS_INIT;
@@ -1067,6 +1069,7 @@ int cmd_gc(int argc,
10671069

10681070
out:
10691071
maintenance_run_opts_release(&opts);
1072+
strvec_clear(&repack_args);
10701073
gc_config_release(&cfg);
10711074
return 0;
10721075
}
@@ -1269,6 +1272,19 @@ static int maintenance_task_gc_background(struct maintenance_run_opts *opts,
12691272
return run_command(&child);
12701273
}
12711274

1275+
static int gc_condition(struct gc_config *cfg)
1276+
{
1277+
/*
1278+
* Note that it's fine to drop the repack arguments here, as we execute
1279+
* git-gc(1) as a separate child process anyway. So it knows to compute
1280+
* these arguments again.
1281+
*/
1282+
struct strvec repack_args = STRVEC_INIT;
1283+
int ret = need_to_gc(cfg, &repack_args);
1284+
strvec_clear(&repack_args);
1285+
return ret;
1286+
}
1287+
12721288
static int prune_packed(struct maintenance_run_opts *opts)
12731289
{
12741290
struct child_process child = CHILD_PROCESS_INIT;
@@ -1596,7 +1612,7 @@ static const struct maintenance_task tasks[] = {
15961612
.name = "gc",
15971613
.foreground = maintenance_task_gc_foreground,
15981614
.background = maintenance_task_gc_background,
1599-
.auto_condition = need_to_gc,
1615+
.auto_condition = gc_condition,
16001616
},
16011617
[TASK_COMMIT_GRAPH] = {
16021618
.name = "commit-graph",

0 commit comments

Comments
 (0)