builtin/gc: inline config values specific to the "files" backend
The `struct gc_config` contains a set of values that we read via the Git repository's configuration. Several of those values that are consumed by the object database optimization logic are inherently specific to the "files" config. In a later commit we'll make the logic to optimize object databases pluggable. So by carrying these "files"-backend specific values in the generic config struct means that other backends would have to worry about these values, too. This feels somewhat dirty, as implementation- specific details should live with the backends themselves. Inline these values directly at the call sites that need them instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Jul 13, 2026 at 07:52 UTC
57ca517baca6c28ed11e923ed7f25bb5c7af8909
1 file changed
+53
-62
builtin/gc.c
+53
-62
@@ -130,22 +130,11 @@ struct gc_config {
130
unsigned long max_cruft_size;
131
int aggressive_depth;
132
int aggressive_window;
133
- int gc_auto_threshold;
134
- int gc_auto_pack_limit;
133
int detach_auto;
134
char *gc_log_expire;
135
char *prune_expire;
136
char *prune_worktrees_expire;
139
- char *repack_filter;
140
- char *repack_filter_to;
137
char *repack_expire_to;
142
- unsigned long big_pack_threshold;
143
- unsigned long max_delta_cache_size;
144
- /*
145
- * Remove this member from gc_config once repo_settings is passed
146
- * through the callchain.
147
- */
148
- size_t delta_base_cache_limit;
138
};
139
140
#define GC_CONFIG_INIT { \
@@ -154,14 +143,10 @@ struct gc_config {
143
.cruft_packs = 1, \
144
.aggressive_depth = 50, \
145
.aggressive_window = 250, \
157
- .gc_auto_threshold = 6700, \
158
- .gc_auto_pack_limit = 50, \
146
.detach_auto = 1, \
147
.gc_log_expire = xstrdup("1.day.ago"), \
148
.prune_expire = xstrdup("2.weeks.ago"), \
149
.prune_worktrees_expire = xstrdup("3.months.ago"), \
163
- .max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE, \
164
- .delta_base_cache_limit = DEFAULT_DELTA_BASE_CACHE_LIMIT, \
150
}
151
152
static void gc_config_release(struct gc_config *cfg)
@@ -169,15 +154,12 @@ static void gc_config_release(struct gc_config *cfg)
154
free(cfg->gc_log_expire);
155
free(cfg->prune_expire);
156
free(cfg->prune_worktrees_expire);
172
- free(cfg->repack_filter);
173
- free(cfg->repack_filter_to);
157
}
158
159
static void gc_config(struct gc_config *cfg)
160
{
161
const char *value;
162
char *owned = NULL;
180
- unsigned long ulongval;
163
164
if (!repo_config_get_value(the_repository, "gc.packrefs", &value)) {
165
if (value && !strcmp(value, "notbare"))
@@ -192,8 +174,6 @@ static void gc_config(struct gc_config *cfg)
174
175
repo_config_get_int(the_repository, "gc.aggressivewindow", &cfg->aggressive_window);
176
repo_config_get_int(the_repository, "gc.aggressivedepth", &cfg->aggressive_depth);
195
- repo_config_get_int(the_repository, "gc.auto", &cfg->gc_auto_threshold);
196
- repo_config_get_int(the_repository, "gc.autopacklimit", &cfg->gc_auto_pack_limit);
177
repo_config_get_bool(the_repository, "gc.autodetach", &cfg->detach_auto);
178
repo_config_get_bool(the_repository, "gc.cruftpacks", &cfg->cruft_packs);
179
repo_config_get_ulong(the_repository, "gc.maxcruftsize", &cfg->max_cruft_size);
@@ -213,22 +193,6 @@ static void gc_config(struct gc_config *cfg)
193
cfg->gc_log_expire = owned;
194
}
195
216
- repo_config_get_ulong(the_repository, "gc.bigpackthreshold", &cfg->big_pack_threshold);
217
- repo_config_get_ulong(the_repository, "pack.deltacachesize", &cfg->max_delta_cache_size);
218
-
219
- if (!repo_config_get_ulong(the_repository, "core.deltabasecachelimit", &ulongval))
220
- cfg->delta_base_cache_limit = ulongval;
221
-
222
- if (!repo_config_get_string(the_repository, "gc.repackfilter", &owned)) {
223
- free(cfg->repack_filter);
224
- cfg->repack_filter = owned;
225
- }
226
-
227
- if (!repo_config_get_string(the_repository, "gc.repackfilterto", &owned)) {
228
- free(cfg->repack_filter_to);
229
- cfg->repack_filter_to = owned;
230
- }
231
-
196
repo_config(the_repository, git_default_config, NULL);
197
}
198
@@ -504,12 +468,12 @@ static struct packed_git *find_base_packs(struct string_list *packs,
468
return base;
469
}
470
507
-static int too_many_packs(struct gc_config *cfg)
471
+static int too_many_packs(int gc_auto_pack_limit)
472
{
473
struct packed_git *p;
474
int cnt = 0;
475
512
- if (cfg->gc_auto_pack_limit <= 0)
476
+ if (gc_auto_pack_limit <= 0)
477
return 0;
478
479
repo_for_each_pack(the_repository, p) {
@@ -523,7 +487,7 @@ static int too_many_packs(struct gc_config *cfg)
487
*/
488
cnt++;
489
}
526
- return cfg->gc_auto_pack_limit < cnt;
490
+ return gc_auto_pack_limit < cnt;
491
}
492
493
static uint64_t total_ram(void)
@@ -571,9 +535,10 @@ static uint64_t total_ram(void)
535
return 0;
536
}
537
574
-static uint64_t estimate_repack_memory(struct gc_config *cfg,
575
- struct packed_git *pack)
538
+static uint64_t estimate_repack_memory(struct packed_git *pack)
539
{
540
+ unsigned long max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE;
541
+ unsigned long delta_base_cache_limit = DEFAULT_DELTA_BASE_CACHE_LIMIT;
542
unsigned long nr_objects;
543
size_t os_cache, heap;
544
@@ -584,6 +549,9 @@ static uint64_t estimate_repack_memory(struct gc_config *cfg,
549
if (!pack || !nr_objects)
550
return 0;
551
552
+ repo_config_get_ulong(the_repository, "pack.deltacachesize", &max_delta_cache_size);
553
+ repo_config_get_ulong(the_repository, "core.deltabasecachelimit", &delta_base_cache_limit);
554
+
555
/*
556
* First we have to scan through at least one pack.
557
* Assume enough room in OS file cache to keep the entire pack
@@ -611,9 +579,9 @@ static uint64_t estimate_repack_memory(struct gc_config *cfg,
579
* read_sha1_file() (either at delta calculation phase, or
580
* writing phase) also fills up the delta base cache
581
*/
614
- heap += cfg->delta_base_cache_limit;
582
+ heap += delta_base_cache_limit;
583
/* and of course pack-objects has its own delta cache */
616
- heap += cfg->max_delta_cache_size;
584
+ heap += max_delta_cache_size;
585
586
return os_cache + heap;
587
}
@@ -629,6 +597,12 @@ static void add_repack_all_option(struct gc_config *cfg,
597
struct string_list *keep_pack,
598
struct strvec *args)
599
{
600
+ char *repack_filter = NULL;
601
+ char *repack_filter_to = NULL;
602
+
603
+ repo_config_get_string(the_repository, "gc.repackfilter", &repack_filter);
604
+ repo_config_get_string(the_repository, "gc.repackfilterto", &repack_filter_to);
605
+
606
if (cfg->prune_expire && !strcmp(cfg->prune_expire, "now")
607
&& !(cfg->cruft_packs && cfg->repack_expire_to))
608
strvec_push(args, "-a");
@@ -650,10 +624,13 @@ static void add_repack_all_option(struct gc_config *cfg,
624
if (keep_pack)
625
for_each_string_list(keep_pack, keep_one_pack, args);
626
653
- if (cfg->repack_filter && *cfg->repack_filter)
654
- strvec_pushf(args, "--filter=%s", cfg->repack_filter);
655
- if (cfg->repack_filter_to && *cfg->repack_filter_to)
656
- strvec_pushf(args, "--filter-to=%s", cfg->repack_filter_to);
627
+ if (repack_filter && *repack_filter)
628
+ strvec_pushf(args, "--filter=%s", repack_filter);
629
+ if (repack_filter_to && *repack_filter_to)
630
+ strvec_pushf(args, "--filter-to=%s", repack_filter_to);
631
+
632
+ free(repack_filter);
633
+ free(repack_filter_to);
634
}
635
636
static void add_repack_incremental_option(struct strvec *args)
@@ -661,16 +638,24 @@ static void add_repack_incremental_option(struct strvec *args)
638
strvec_push(args, "--no-write-bitmap-index");
639
}
640
664
-static int need_to_gc(struct gc_config *cfg)
641
+static int need_to_gc(struct repository *repo)
642
{
643
+ int gc_auto_threshold = 6700;
644
+ int gc_auto_pack_limit = 50;
645
+
646
+ repo_config_get_int(repo, "gc.auto", &gc_auto_threshold);
647
+ repo_config_get_int(repo, "gc.autopacklimit", &gc_auto_pack_limit);
648
+
649
/*
650
* Setting gc.auto to 0 or negative can disable the
651
* automatic gc.
652
*/
670
- if (cfg->gc_auto_threshold <= 0)
653
+ if (gc_auto_threshold <= 0)
654
return 0;
672
- if (!too_many_packs(cfg) && !too_many_loose_objects(cfg->gc_auto_threshold))
655
+ if (!too_many_packs(gc_auto_pack_limit) &&
656
+ !too_many_loose_objects(gc_auto_threshold))
657
return 0;
658
+
659
return 1;
660
}
661
@@ -807,8 +792,15 @@ static int maintenance_task_odb(struct maintenance_run_opts *opts,
792
int aggressive)
793
{
794
struct child_process repack_cmd = CHILD_PROCESS_INIT;
795
+ unsigned long big_pack_threshold = 0;
796
+ int gc_auto_threshold = 6700;
797
+ int gc_auto_pack_limit = 50;
798
int ret;
799
800
+ repo_config_get_int(the_repository, "gc.auto", &gc_auto_threshold);
801
+ repo_config_get_int(the_repository, "gc.autopacklimit", &gc_auto_pack_limit);
802
+ repo_config_get_ulong(the_repository, "gc.bigpackthreshold", &big_pack_threshold);
803
+
804
if (the_repository->repository_format_precious_objects)
805
return 0;
806
@@ -843,19 +835,18 @@ static int maintenance_task_odb(struct maintenance_run_opts *opts,
835
if (keep_largest_pack != -1) {
836
if (keep_largest_pack)
837
find_base_packs(&keep_pack, 0);
846
- } else if (cfg->big_pack_threshold) {
847
- find_base_packs(&keep_pack, cfg->big_pack_threshold);
838
+ } else if (big_pack_threshold) {
839
+ find_base_packs(&keep_pack, big_pack_threshold);
840
}
841
842
add_repack_all_option(cfg, &keep_pack, &repack_cmd.args);
843
string_list_clear(&keep_pack, 0);
852
- } else if (too_many_packs(cfg)) {
844
+ } else if (too_many_packs(gc_auto_pack_limit)) {
845
struct string_list keep_pack = STRING_LIST_INIT_NODUP;
846
855
- if (cfg->big_pack_threshold) {
856
- find_base_packs(&keep_pack, cfg->big_pack_threshold);
857
- if (keep_pack.nr >= cfg->gc_auto_pack_limit) {
858
- cfg->big_pack_threshold = 0;
847
+ if (big_pack_threshold) {
848
+ find_base_packs(&keep_pack, big_pack_threshold);
849
+ if (keep_pack.nr >= gc_auto_pack_limit) {
850
string_list_clear(&keep_pack, 0);
851
find_base_packs(&keep_pack, 0);
852
}
@@ -864,7 +855,7 @@ static int maintenance_task_odb(struct maintenance_run_opts *opts,
855
uint64_t mem_have, mem_want;
856
857
mem_have = total_ram();
867
- mem_want = estimate_repack_memory(cfg, p);
858
+ mem_want = estimate_repack_memory(p);
859
860
/*
861
* Only allow 1/2 of memory for pack-objects, leave
@@ -905,7 +896,7 @@ static int maintenance_task_odb(struct maintenance_run_opts *opts,
896
}
897
}
898
908
- if (opts->auto_flag && too_many_loose_objects(cfg->gc_auto_threshold))
899
+ if (opts->auto_flag && too_many_loose_objects(gc_auto_threshold))
900
warning(_("There are too many unreachable loose objects; "
901
"run 'git prune' to remove them."));
902
@@ -994,7 +985,7 @@ int cmd_gc(int argc,
985
/*
986
* Auto-gc should be least intrusive as possible.
987
*/
997
- if (!need_to_gc(&cfg) || run_hooks(the_repository, "pre-auto-gc")) {
988
+ if (!need_to_gc(the_repository) || run_hooks(the_repository, "pre-auto-gc")) {
989
ret = 0;
990
goto out;
991
}
@@ -1291,9 +1282,9 @@ static int maintenance_task_gc_background(struct maintenance_run_opts *opts,
1282
return run_command(&child);
1283
}
1284
1294
-static int gc_condition(struct gc_config *cfg)
1285
+static int gc_condition(struct gc_config *cfg UNUSED)
1286
{
1296
- return need_to_gc(cfg);
1287
+ return need_to_gc(the_repository);
1288
}
1289
1290
static int prune_packed(struct maintenance_run_opts *opts)