builtin/gc: extract object database optimizations into separate function
Extract the object database optimization logic from `cmd_gc()` into a new `maintenance_task_odb()` helper function. This is a pure refactoring with no intended functional change. Note that the message that notifies the user about too many loose objects is moved into the new function, as well. It is inherently an implementation detail of how the "files" source works, and as a consequence we'll move it around in a later commit, as well. This reordering means that the warning may now be printed at a different point in time, but it's not expected that this will have any practical implications. 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
e86fe6fe62d0fb5b54a1afed6166d3e27d28f081
1 file changed
+49
-30
builtin/gc.c
+49
-30
@@ -839,6 +839,53 @@ static int gc_foreground_tasks(struct maintenance_run_opts *opts,
839
return 0;
840
}
841
842
+static int maintenance_task_odb(struct maintenance_run_opts *opts,
843
+ struct gc_config *cfg,
844
+ struct strvec *repack_args)
845
+{
846
+ struct child_process repack_cmd = CHILD_PROCESS_INIT;
847
+ int ret;
848
+
849
+ if (the_repository->repository_format_precious_objects)
850
+ return 0;
851
+
852
+ repack_cmd.git_cmd = 1;
853
+ repack_cmd.odb_to_close = the_repository->objects;
854
+ strvec_pushv(&repack_cmd.args, repack_args->v);
855
+ if (run_command(&repack_cmd)) {
856
+ ret = error(FAILED_RUN, repack_args->v[0]);
857
+ goto out;
858
+ }
859
+
860
+ if (cfg->prune_expire) {
861
+ struct child_process prune_cmd = CHILD_PROCESS_INIT;
862
+
863
+ strvec_pushl(&prune_cmd.args, "prune", "--expire", NULL);
864
+ /* run `git prune` even if using cruft packs */
865
+ strvec_push(&prune_cmd.args, cfg->prune_expire);
866
+ if (opts->quiet)
867
+ strvec_push(&prune_cmd.args, "--no-progress");
868
+ if (repo_has_promisor_remote(the_repository))
869
+ strvec_push(&prune_cmd.args,
870
+ "--exclude-promisor-objects");
871
+ prune_cmd.git_cmd = 1;
872
+
873
+ if (run_command(&prune_cmd)) {
874
+ ret = error(FAILED_RUN, prune_cmd.args.v[0]);
875
+ goto out;
876
+ }
877
+ }
878
+
879
+ if (opts->auto_flag && too_many_loose_objects(cfg->gc_auto_threshold))
880
+ warning(_("There are too many unreachable loose objects; "
881
+ "run 'git prune' to remove them."));
882
+
883
+ ret = 0;
884
+
885
+out:
886
+ return ret;
887
+}
888
+
889
int cmd_gc(int argc,
890
const char **argv,
891
const char *prefix,
@@ -1018,32 +1065,8 @@ int cmd_gc(int argc,
1065
if (maintenance_task_rerere_gc(&opts, &cfg))
1066
die(FAILED_RUN, "rerere");
1067
1021
- if (!the_repository->repository_format_precious_objects) {
1022
- struct child_process repack_cmd = CHILD_PROCESS_INIT;
1023
-
1024
- repack_cmd.git_cmd = 1;
1025
- repack_cmd.odb_to_close = the_repository->objects;
1026
- strvec_pushv(&repack_cmd.args, repack_args.v);
1027
- if (run_command(&repack_cmd))
1028
- die(FAILED_RUN, repack_args.v[0]);
1029
-
1030
- if (cfg.prune_expire) {
1031
- struct child_process prune_cmd = CHILD_PROCESS_INIT;
1032
-
1033
- strvec_pushl(&prune_cmd.args, "prune", "--expire", NULL);
1034
- /* run `git prune` even if using cruft packs */
1035
- strvec_push(&prune_cmd.args, cfg.prune_expire);
1036
- if (opts.quiet)
1037
- strvec_push(&prune_cmd.args, "--no-progress");
1038
- if (repo_has_promisor_remote(the_repository))
1039
- strvec_push(&prune_cmd.args,
1040
- "--exclude-promisor-objects");
1041
- prune_cmd.git_cmd = 1;
1042
-
1043
- if (run_command(&prune_cmd))
1044
- die(FAILED_RUN, prune_cmd.args.v[0]);
1045
- }
1046
- }
1068
+ if (maintenance_task_odb(&opts, &cfg, &repack_args))
1069
+ die(NULL);
1070
1071
report_garbage = report_pack_garbage;
1072
odb_reprepare(the_repository->objects);
@@ -1057,10 +1080,6 @@ int cmd_gc(int argc,
1080
!opts.quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,
1081
NULL);
1082
1060
- if (opts.auto_flag && too_many_loose_objects(cfg.gc_auto_threshold))
1061
- warning(_("There are too many unreachable loose objects; "
1062
- "run 'git prune' to remove them."));
1063
-
1083
if (!daemonized) {
1084
char *path = repo_git_path(the_repository, "gc.log");
1085
unlink(path);