From 05c324b92fe723674cbf9ae1b0b1675821b6c275 Mon Sep 17 00:00:00 2001 From: Burak Kaan Karaçay Date: Thu, 12 Mar 2026 17:44:36 +0300 Subject: run-command: wean start_command() off the_repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The start_command() relies on the_repository due to the close_object_store flag in 'struct child_process'. When this flag is set, start_command() closes the object store associated with the_repository before spawning a child process. To eliminate this dependency, replace the 'close_object_store' with the new 'struct object_database *odb_to_close' field. This allows callers to specify the object store that needs to be closed. Suggested-by: René Scharfe Signed-off-by: Burak Kaan Karaçay Signed-off-by: Junio C Hamano --- builtin/gc.c | 14 +++++++++----- builtin/pull.c | 2 +- run-command.c | 6 +++--- run-command.h | 2 +- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/builtin/gc.c b/builtin/gc.c index fb329c2cff..5d8d358f7a 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1030,7 +1030,7 @@ int cmd_gc(int argc, struct child_process repack_cmd = CHILD_PROCESS_INIT; repack_cmd.git_cmd = 1; - repack_cmd.close_object_store = 1; + repack_cmd.odb_to_close = the_repository->objects; strvec_pushv(&repack_cmd.args, repack_args.v); if (run_command(&repack_cmd)) die(FAILED_RUN, repack_args.v[0]); @@ -1199,7 +1199,8 @@ static int run_write_commit_graph(struct maintenance_run_opts *opts) { struct child_process child = CHILD_PROCESS_INIT; - child.git_cmd = child.close_object_store = 1; + child.git_cmd = 1; + child.odb_to_close = the_repository->objects; strvec_pushl(&child.args, "commit-graph", "write", "--split", "--reachable", NULL); @@ -1268,7 +1269,8 @@ static int maintenance_task_gc_background(struct maintenance_run_opts *opts, { struct child_process child = CHILD_PROCESS_INIT; - child.git_cmd = child.close_object_store = 1; + child.git_cmd = 1; + child.odb_to_close = the_repository->objects; strvec_push(&child.args, "gc"); if (opts->auto_flag) @@ -1484,7 +1486,8 @@ static int multi_pack_index_expire(struct maintenance_run_opts *opts) { struct child_process child = CHILD_PROCESS_INIT; - child.git_cmd = child.close_object_store = 1; + child.git_cmd = 1; + child.odb_to_close = the_repository->objects; strvec_pushl(&child.args, "multi-pack-index", "expire", NULL); if (opts->quiet) @@ -1542,7 +1545,8 @@ static int multi_pack_index_repack(struct maintenance_run_opts *opts) { struct child_process child = CHILD_PROCESS_INIT; - child.git_cmd = child.close_object_store = 1; + child.git_cmd = 1; + child.odb_to_close = the_repository->objects; strvec_pushl(&child.args, "multi-pack-index", "repack", NULL); if (opts->quiet) diff --git a/builtin/pull.c b/builtin/pull.c index 6ad420ce6f..7e67fdce97 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -454,7 +454,7 @@ static int run_fetch(const char *repo, const char **refspecs) } else if (*refspecs) BUG("refspecs without repo?"); cmd.git_cmd = 1; - cmd.close_object_store = 1; + cmd.odb_to_close = the_repository->objects; return run_command(&cmd); } diff --git a/run-command.c b/run-command.c index b27064ef57..ed5e8be976 100644 --- a/run-command.c +++ b/run-command.c @@ -742,8 +742,8 @@ fail_pipe: fflush(NULL); - if (cmd->close_object_store) - odb_close(the_repository->objects); + if (cmd->odb_to_close) + odb_close(cmd->odb_to_close); #ifndef GIT_WINDOWS_NATIVE { @@ -1955,7 +1955,7 @@ int prepare_auto_maintenance(int quiet, struct child_process *maint) auto_detach = git_env_bool("GIT_TEST_MAINT_AUTO_DETACH", true); maint->git_cmd = 1; - maint->close_object_store = 1; + maint->odb_to_close = the_repository->objects; strvec_pushl(&maint->args, "maintenance", "run", "--auto", NULL); strvec_push(&maint->args, quiet ? "--quiet" : "--no-quiet"); strvec_push(&maint->args, auto_detach ? "--detach" : "--no-detach"); diff --git a/run-command.h b/run-command.h index e1ca965b5b..af4c9da279 100644 --- a/run-command.h +++ b/run-command.h @@ -136,7 +136,7 @@ struct child_process { * want to repack because that would delete `.pack` files (and on * Windows, you cannot delete files that are still in use). */ - unsigned close_object_store:1; + struct object_database *odb_to_close; unsigned stdout_to_stderr:1; unsigned clean_on_exit:1; -- cgit v1.3-5-g9baa From 9df3be8e2e7e2c9bf200de4bcfbd4e690a57f033 Mon Sep 17 00:00:00 2001 From: Burak Kaan Karaçay Date: Thu, 12 Mar 2026 17:44:37 +0300 Subject: run-command: wean auto_maintenance() functions off the_repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prepare_auto_maintenance() relies on the_repository to read configurations. Since run_auto_maintenance() calls prepare_auto_maintenance(), it also implicitly depends the_repository. Add 'struct repository *' as a parameter to both functions and update all callers to pass the_repository. With no global repository dependencies left in this file, remove the USE_THE_REPOSITORY_VARIABLE macro. Suggested-by: Patrick Steinhardt Signed-off-by: Burak Kaan Karaçay Signed-off-by: Junio C Hamano --- builtin/am.c | 2 +- builtin/commit.c | 2 +- builtin/fetch.c | 2 +- builtin/merge.c | 2 +- builtin/rebase.c | 4 +++- builtin/receive-pack.c | 2 +- run-command.c | 16 ++++++++-------- run-command.h | 7 +++++-- 8 files changed, 21 insertions(+), 16 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index e0c767e223..9d0b51c651 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1937,7 +1937,7 @@ next: */ if (!state->rebasing) { am_destroy(state); - run_auto_maintenance(state->quiet); + run_auto_maintenance(the_repository, state->quiet); } } diff --git a/builtin/commit.c b/builtin/commit.c index 844bdcc728..7b23c1f883 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1958,7 +1958,7 @@ int cmd_commit(int argc, git_test_write_commit_graph_or_die(the_repository->objects->sources); repo_rerere(the_repository, 0); - run_auto_maintenance(quiet); + run_auto_maintenance(the_repository, quiet); run_commit_hook(use_editor, repo_get_index_file(the_repository), NULL, "post-commit", NULL); if (amend && !no_post_rewrite) { diff --git a/builtin/fetch.c b/builtin/fetch.c index 8a36cf67b5..4795b2a13c 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -2873,7 +2873,7 @@ int cmd_fetch(int argc, if (opt_val != 0) git_config_push_parameter("maintenance.incremental-repack.auto=-1"); } - run_auto_maintenance(verbosity < 0); + run_auto_maintenance(the_repository, verbosity < 0); } cleanup: diff --git a/builtin/merge.c b/builtin/merge.c index 4e456a381c..2cbce56f8d 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -506,7 +506,7 @@ static void finish(struct commit *head_commit, * We ignore errors in 'gc --auto', since the * user should see them. */ - run_auto_maintenance(verbosity < 0); + run_auto_maintenance(the_repository, verbosity < 0); } } if (new_head && show_diffstat) { diff --git a/builtin/rebase.c b/builtin/rebase.c index c487e10907..8c1316db38 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -562,7 +562,9 @@ static int finish_rebase(struct rebase_options *opts) * We ignore errors in 'git maintenance run --auto', since the * user should see them. */ - run_auto_maintenance(!(opts->flags & (REBASE_NO_QUIET|REBASE_VERBOSE))); + run_auto_maintenance(the_repository, + !(opts->flags & (REBASE_NO_QUIET|REBASE_VERBOSE))); + if (opts->type == REBASE_MERGE) { struct replay_opts replay = REPLAY_OPTS_INIT; diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index d6225df890..e34edff406 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -2727,7 +2727,7 @@ int cmd_receive_pack(int argc, if (auto_gc) { struct child_process proc = CHILD_PROCESS_INIT; - if (prepare_auto_maintenance(1, &proc)) { + if (prepare_auto_maintenance(the_repository, 1, &proc)) { proc.no_stdin = 1; proc.stdout_to_stderr = 1; proc.err = use_sideband ? -1 : 0; diff --git a/run-command.c b/run-command.c index ed5e8be976..38f4c699f8 100644 --- a/run-command.c +++ b/run-command.c @@ -1,4 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE #define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" @@ -1937,11 +1936,12 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts) trace2_region_leave(tr2_category, tr2_label, NULL); } -int prepare_auto_maintenance(int quiet, struct child_process *maint) +int prepare_auto_maintenance(struct repository *r, int quiet, + struct child_process *maint) { int enabled, auto_detach; - if (!repo_config_get_bool(the_repository, "maintenance.auto", &enabled) && + if (!repo_config_get_bool(r, "maintenance.auto", &enabled) && !enabled) return 0; @@ -1950,12 +1950,12 @@ int prepare_auto_maintenance(int quiet, struct child_process *maint) * honoring `gc.autoDetach`. This is somewhat weird, but required to * retain behaviour from when we used to run git-gc(1) here. */ - if (repo_config_get_bool(the_repository, "maintenance.autodetach", &auto_detach) && - repo_config_get_bool(the_repository, "gc.autodetach", &auto_detach)) + if (repo_config_get_bool(r, "maintenance.autodetach", &auto_detach) && + repo_config_get_bool(r, "gc.autodetach", &auto_detach)) auto_detach = git_env_bool("GIT_TEST_MAINT_AUTO_DETACH", true); maint->git_cmd = 1; - maint->odb_to_close = the_repository->objects; + maint->odb_to_close = r->objects; strvec_pushl(&maint->args, "maintenance", "run", "--auto", NULL); strvec_push(&maint->args, quiet ? "--quiet" : "--no-quiet"); strvec_push(&maint->args, auto_detach ? "--detach" : "--no-detach"); @@ -1963,10 +1963,10 @@ int prepare_auto_maintenance(int quiet, struct child_process *maint) return 1; } -int run_auto_maintenance(int quiet) +int run_auto_maintenance(struct repository *r, int quiet) { struct child_process maint = CHILD_PROCESS_INIT; - if (!prepare_auto_maintenance(quiet, &maint)) + if (!prepare_auto_maintenance(r, quiet, &maint)) return 0; return run_command(&maint); } diff --git a/run-command.h b/run-command.h index af4c9da279..ad25740fe6 100644 --- a/run-command.h +++ b/run-command.h @@ -5,6 +5,8 @@ #include "strvec.h" +struct repository; + /** * The run-command API offers a versatile tool to run sub-processes with * redirected input and output as well as with a modified environment @@ -227,12 +229,13 @@ int run_command(struct child_process *); * process has been prepared and is ready to run, or 0 in case auto-maintenance * should be skipped. */ -int prepare_auto_maintenance(int quiet, struct child_process *maint); +int prepare_auto_maintenance(struct repository *r, int quiet, + struct child_process *maint); /* * Trigger an auto-gc */ -int run_auto_maintenance(int quiet); +int run_auto_maintenance(struct repository *r, int quiet); /** * Execute the given command, sending "in" to its stdin, and capturing its -- cgit v1.3-5-g9baa