{"thread":{"id":"65210","subject":"[PATCH 0/4] wean start_command() off the_repository","startedAt":"2026-03-11T15:19:38Z","lastAt":"2026-03-13T06:23:24Z","messageCount":18,"participants":["Burak Kaan Karaçay","René Scharfe","Jeff King","Junio C Hamano","Patrick Steinhardt"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"538614","messageId":"20260311151923.4178655-1-bkkaracay@gmail.com","threadId":"65210","inReplyTo":null,"subject":"[PATCH 0/4] wean start_command() off the_repository","fromName":"Burak Kaan Karaçay","fromEmail":"bkkaracay@gmail.com","sentAt":"2026-03-11T15:19:19Z","receivedAt":"2026-03-11T15:19:38Z","isPatch":true,"sender":{"key":"bkkaracay@gmail.com","avatar":"https://avatars.githubusercontent.com/u/29117336?v=4"},"body":"Hi,\n\nstart_command() relies on the_repository due to the 'close_object_store'\nflag in 'struct child_process'. Introduce repo_start_command() to allow\nworking with arbitrary repositories. Turn start_command() into a macro\nthat wraps repo_start_command() and migrate the existing callers with a\ncocci script.\n\nFor callers that cannot access 'the_repository' due to the lack of\nUSE_THE_REPOSITORY_VARIABLE, define the macro. If the caller already has\na local repository context, pass it explicitly instead of defining the\nmacro.\n\nThanks,\nBurak Kaan Karaçay\n\nBurak Kaan Karaçay (4):\n  run-command: add repo_start_command()\n  run-command: use repo_start_command() in strict callers\n  run-command: redefine start_command() as a wrapper macro\n  cocci: convert start_command() to repo_start_command()\n\n archive-tar.c                           |  2 +-\n branch.c                                |  2 +-\n builtin/credential-cache.c              |  4 +++-\n builtin/difftool.c                      |  4 ++--\n builtin/gc.c                            | 16 ++++++++--------\n builtin/help.c                          |  2 +-\n builtin/index-pack.c                    |  2 +-\n builtin/merge.c                         |  2 +-\n builtin/notes.c                         |  2 +-\n builtin/receive-pack.c                  |  6 +++---\n builtin/remote-ext.c                    |  4 +++-\n builtin/repack.c                        |  2 +-\n builtin/replace.c                       |  2 +-\n builtin/upload-archive.c                |  2 +-\n builtin/worktree.c                      |  2 +-\n bundle-uri.c                            |  2 +-\n bundle.c                                |  2 +-\n column.c                                |  3 ++-\n compat/mingw.c                          |  2 +-\n connect.c                               |  4 ++--\n connected.c                             |  2 +-\n contrib/coccinelle/the_repository.cocci |  3 +++\n convert.c                               |  2 +-\n credential.c                            |  3 ++-\n daemon.c                                |  6 +++---\n diff.c                                  |  2 +-\n editor.c                                |  2 +-\n fetch-pack.c                            |  4 ++--\n http-backend.c                          |  2 +-\n imap-send.c                             |  2 +-\n midx-write.c                            |  4 +++-\n odb.c                                   |  2 +-\n pager.c                                 |  2 +-\n parallel-checkout.c                     |  2 +-\n promisor-remote.c                       |  2 +-\n prompt.c                                |  3 ++-\n range-diff.c                            |  2 +-\n reachable.c                             |  2 +-\n remote-curl.c                           |  2 +-\n repack-cruft.c                          |  4 +++-\n repack-filtered.c                       |  4 +++-\n repack-midx.c                           |  4 +++-\n repack-promisor.c                       |  6 ++++--\n run-command.c                           | 12 ++++++------\n run-command.h                           |  6 ++++--\n send-pack.c                             |  4 ++--\n sub-process.c                           |  5 ++++-\n submodule.c                             | 12 ++++++------\n t/helper/test-run-command.c             |  6 ++++--\n transport-helper.c                      |  6 +++---\n upload-pack.c                           |  4 ++--\n 51 files changed, 108 insertions(+), 81 deletions(-)\n\n-- \n2.53.0\n\n"},{"id":"538615","messageId":"20260311151923.4178655-2-bkkaracay@gmail.com","threadId":"65210","inReplyTo":"20260311151923.4178655-1-bkkaracay@gmail.com","subject":"[PATCH 1/4] run-command: add repo_start_command()","fromName":"Burak Kaan Karaçay","fromEmail":"bkkaracay@gmail.com","sentAt":"2026-03-11T15:19:20Z","receivedAt":"2026-03-11T15:19:44Z","isPatch":true,"sender":{"key":"bkkaracay@gmail.com","avatar":"https://avatars.githubusercontent.com/u/29117336?v=4"},"body":"Currently start_command() relies on implicitly the_repository to close\nobject store before the spawning a child process. This prevents callers\nfrom safely starting commands in context of a different repository.\n\nIntroduce repo_start_command() which takes 'struct repository *' as\nargument. To avoid breaking existing callers, redefine start_command()\nas a wrapper to pass the_repository to repo_start_command().\n\nSigned-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com>\n---\n run-command.c | 7 ++++++-\n run-command.h | 4 +++-\n 2 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/run-command.c b/run-command.c\nindex b27064ef57..fadc3d5283 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -675,6 +675,11 @@ static void trace_run_command(const struct child_process *cp)\n }\n \n int start_command(struct child_process *cmd)\n+{\n+\treturn repo_start_command(the_repository, cmd);\n+}\n+\n+int repo_start_command(struct repository *repo, struct child_process *cmd)\n {\n \tint need_in, need_out, need_err;\n \tint fdin[2], fdout[2], fderr[2];\n@@ -743,7 +748,7 @@ int start_command(struct child_process *cmd)\n \tfflush(NULL);\n \n \tif (cmd->close_object_store)\n-\t\todb_close(the_repository->objects);\n+\t\todb_close(repo->objects);\n \n #ifndef GIT_WINDOWS_NATIVE\n {\ndiff --git a/run-command.h b/run-command.h\nindex e1ca965b5b..654ca659b3 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -2,7 +2,6 @@\n #define RUN_COMMAND_H\n \n #include \"thread-utils.h\"\n-\n #include \"strvec.h\"\n \n /**\n@@ -15,6 +14,7 @@\n  * produces in the caller in order to process it.\n  */\n \n+struct repository;\n \n /**\n  * This describes the arguments, redirections, and environment of a\n@@ -205,7 +205,9 @@ char *git_shell_path(void);\n  * that specifies the details and returns pipe FDs (if requested).\n  * See below for details.\n  */\n+\n int start_command(struct child_process *);\n+int repo_start_command(struct repository *, struct child_process *);\n \n /**\n  * Wait for the completion of a sub-process that was started with\n-- \n2.53.0\n\n"},{"id":"538616","messageId":"20260311151923.4178655-3-bkkaracay@gmail.com","threadId":"65210","inReplyTo":"20260311151923.4178655-1-bkkaracay@gmail.com","subject":"[PATCH 2/4] run-command: use repo_start_command() in strict callers","fromName":"Burak Kaan Karaçay","fromEmail":"bkkaracay@gmail.com","sentAt":"2026-03-11T15:19:21Z","receivedAt":"2026-03-11T15:19:48Z","isPatch":true,"sender":{"key":"bkkaracay@gmail.com","avatar":"https://avatars.githubusercontent.com/u/29117336?v=4"},"body":"Some callers have been freed from global state and they do not define\nthe 'USE_THE_REPOSITORY_VARIABLE' macro.\n\nTo complete the mitigation of 'start_command()', update these callers to\nuse repo_start_command() and pass their local 'struct repository' as an\nargument, completely eliminating their hidden reliance on the global\nstate.\n\nSigned-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com>\n---\n builtin/difftool.c | 4 ++--\n odb.c              | 2 +-\n pager.c            | 2 +-\n repack-promisor.c  | 2 +-\n send-pack.c        | 4 ++--\n 5 files changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/difftool.c b/builtin/difftool.c\nindex e4bc1f8316..15ac552edf 100644\n--- a/builtin/difftool.c\n+++ b/builtin/difftool.c\n@@ -257,7 +257,7 @@ static void changed_files(struct repository *repo,\n \tdiff_files.out = -1;\n \tdiff_files.dir = workdir;\n \tstrvec_pushf(&diff_files.env, \"GIT_INDEX_FILE=%s\", index_path);\n-\tif (start_command(&diff_files))\n+\tif (repo_start_command(repo, &diff_files))\n \t\tdie(\"could not obtain raw diff\");\n \tfp = xfdopen(diff_files.out, \"r\");\n \twhile (!strbuf_getline_nul(&buf, fp)) {\n@@ -437,7 +437,7 @@ static int run_dir_diff(struct repository *repo,\n \tchild->clean_on_exit = 1;\n \tchild->dir = prefix;\n \tchild->out = -1;\n-\tif (start_command(child))\n+\tif (repo_start_command(repo, child))\n \t\tdie(\"could not obtain raw diff\");\n \tfp = xfdopen(child->out, \"r\");\n \ndiff --git a/odb.c b/odb.c\nindex 776de5356c..8ec279f84e 100644\n--- a/odb.c\n+++ b/odb.c\n@@ -535,7 +535,7 @@ static void read_alternate_refs(struct repository *repo,\n \n \tfill_alternate_refs_command(repo, &cmd, path);\n \n-\tif (start_command(&cmd))\n+\tif (repo_start_command(repo, &cmd))\n \t\treturn;\n \n \tfh = xfdopen(cmd.out, \"r\");\ndiff --git a/pager.c b/pager.c\nindex 5531fff50e..9a23ed958d 100644\n--- a/pager.c\n+++ b/pager.c\n@@ -169,7 +169,7 @@ void setup_pager(struct repository *r)\n \tprepare_pager_args(&pager_process, pager);\n \tpager_process.in = -1;\n \tstrvec_push(&pager_process.env, \"GIT_PAGER_IN_USE\");\n-\tif (start_command(&pager_process))\n+\tif (repo_start_command(r, &pager_process))\n \t\tdie(\"unable to execute pager '%s'\", pager);\n \n \t/* original process continues, but writes to the pipe */\ndiff --git a/repack-promisor.c b/repack-promisor.c\nindex 90318ce150..dba161a11a 100644\n--- a/repack-promisor.c\n+++ b/repack-promisor.c\n@@ -125,7 +125,7 @@ void pack_geometry_repack_promisors(struct repository *repo,\n \tprepare_pack_objects(&cmd, args, packtmp);\n \tstrvec_push(&cmd.args, \"--stdin-packs\");\n \tcmd.in = -1;\n-\tif (start_command(&cmd))\n+\tif (repo_start_command(repo, &cmd))\n \t\tdie(_(\"could not start pack-objects to repack promisor packs\"));\n \n \tin = xfdopen(cmd.in, \"w\");\ndiff --git a/send-pack.c b/send-pack.c\nindex 67d6987b1c..c339c3d1ca 100644\n--- a/send-pack.c\n+++ b/send-pack.c\n@@ -92,7 +92,7 @@ static int pack_objects(struct repository *r,\n \tpo.out = args->stateless_rpc ? -1 : fd;\n \tpo.git_cmd = 1;\n \tpo.clean_on_exit = 1;\n-\tif (start_command(&po))\n+\tif (repo_start_command(r, &po))\n \t\tdie_errno(\"git pack-objects failed\");\n \n \t/*\n@@ -459,7 +459,7 @@ static void get_commons_through_negotiation(struct repository *r,\n \t\treturn;\n \t}\n \n-\tif (start_command(&child))\n+\tif (repo_start_command(r, &child))\n \t\tdie(_(\"send-pack: unable to fork off fetch subprocess\"));\n \n \tdo {\n-- \n2.53.0\n\n"},{"id":"538617","messageId":"20260311151923.4178655-4-bkkaracay@gmail.com","threadId":"65210","inReplyTo":"20260311151923.4178655-1-bkkaracay@gmail.com","subject":"[PATCH 3/4] run-command: redefine start_command() as a wrapper macro","fromName":"Burak Kaan Karaçay","fromEmail":"bkkaracay@gmail.com","sentAt":"2026-03-11T15:19:22Z","receivedAt":"2026-03-11T15:19:52Z","isPatch":true,"sender":{"key":"bkkaracay@gmail.com","avatar":"https://avatars.githubusercontent.com/u/29117336?v=4"},"body":"In the commit introducing 'repo_start_command()', 'start_command()' was\nredefined as a wrapper function.\n\nNow, redefine 'start_command()' as a wrapper macro to make 'the_repository'\ndependency explicit at the caller's site. To successfully build, expose\n'the_repository' dependency at the call sites by defining\n'USE_THE_REPOSITORY_VARIABLE' or including 'repository.h' where necessary.\n\nSigned-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com>\n---\n builtin/credential-cache.c  | 2 ++\n builtin/remote-ext.c        | 2 ++\n column.c                    | 1 +\n credential.c                | 1 +\n midx-write.c                | 2 ++\n prompt.c                    | 1 +\n repack-cruft.c              | 2 ++\n repack-filtered.c           | 2 ++\n repack-midx.c               | 2 ++\n repack-promisor.c           | 2 ++\n run-command.c               | 5 -----\n run-command.h               | 2 +-\n sub-process.c               | 3 +++\n t/helper/test-run-command.c | 2 ++\n 14 files changed, 23 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/credential-cache.c b/builtin/credential-cache.c\nindex 7f733cb756..fb17aa87ba 100644\n--- a/builtin/credential-cache.c\n+++ b/builtin/credential-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"builtin.h\"\n #include \"credential.h\"\n #include \"gettext.h\"\ndiff --git a/builtin/remote-ext.c b/builtin/remote-ext.c\nindex bd2037f27d..ed2d551753 100644\n--- a/builtin/remote-ext.c\n+++ b/builtin/remote-ext.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"builtin.h\"\n #include \"transport.h\"\n #include \"run-command.h\"\ndiff --git a/column.c b/column.c\nindex 93fae316b4..998b2ab458 100644\n--- a/column.c\n+++ b/column.c\n@@ -1,3 +1,4 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n #define DISABLE_SIGN_COMPARE_WARNINGS\n \n #include \"git-compat-util.h\"\ndiff --git a/credential.c b/credential.c\nindex 2594c0c422..a513355105 100644\n--- a/credential.c\n+++ b/credential.c\n@@ -1,3 +1,4 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n #define DISABLE_SIGN_COMPARE_WARNINGS\n \n #include \"git-compat-util.h\"\ndiff --git a/midx-write.c b/midx-write.c\nindex 6485cb6706..a53f77f13a 100644\n--- a/midx-write.c\n+++ b/midx-write.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/prompt.c b/prompt.c\nindex 706fba2a50..20a8c34438 100644\n--- a/prompt.c\n+++ b/prompt.c\n@@ -7,6 +7,7 @@\n #include \"strbuf.h\"\n #include \"prompt.h\"\n #include \"compat/terminal.h\"\n+#include \"repository.h\"\n \n static char *do_askpass(const char *cmd, const char *prompt)\n {\ndiff --git a/repack-cruft.c b/repack-cruft.c\nindex 0653e88792..0bfc77792a 100644\n--- a/repack-cruft.c\n+++ b/repack-cruft.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repack.h\"\n #include \"packfile.h\"\ndiff --git a/repack-filtered.c b/repack-filtered.c\nindex edcf7667c5..2f5d1dd709 100644\n--- a/repack-filtered.c\n+++ b/repack-filtered.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repack.h\"\n #include \"repository.h\"\ndiff --git a/repack-midx.c b/repack-midx.c\nindex 0682b80c42..8b4c0d95e3 100644\n--- a/repack-midx.c\n+++ b/repack-midx.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repack.h\"\n #include \"hash.h\"\ndiff --git a/repack-promisor.c b/repack-promisor.c\nindex dba161a11a..70ef19d04f 100644\n--- a/repack-promisor.c\n+++ b/repack-promisor.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repack.h\"\n #include \"hex.h\"\ndiff --git a/run-command.c b/run-command.c\nindex fadc3d5283..af26c636a9 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -674,11 +674,6 @@ static void trace_run_command(const struct child_process *cp)\n \tstrbuf_release(&buf);\n }\n \n-int start_command(struct child_process *cmd)\n-{\n-\treturn repo_start_command(the_repository, cmd);\n-}\n-\n int repo_start_command(struct repository *repo, struct child_process *cmd)\n {\n \tint need_in, need_out, need_err;\ndiff --git a/run-command.h b/run-command.h\nindex 654ca659b3..890d7c5d72 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -206,7 +206,7 @@ char *git_shell_path(void);\n  * See below for details.\n  */\n \n-int start_command(struct child_process *);\n+#define start_command(cmd) repo_start_command(the_repository, cmd)\n int repo_start_command(struct repository *, struct child_process *);\n \n /**\ndiff --git a/sub-process.c b/sub-process.c\nindex 83bf0a0e82..ae7493eb5c 100644\n--- a/sub-process.c\n+++ b/sub-process.c\n@@ -1,10 +1,13 @@\n /*\n  * Generic implementation of background process infrastructure.\n  */\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"sub-process.h\"\n #include \"sigchain.h\"\n #include \"pkt-line.h\"\n+#include \"repository.h\"\n \n int cmd2process_cmp(const void *cmp_data UNUSED,\n \t\t    const struct hashmap_entry *eptr,\ndiff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c\nindex 4a56456894..dcd58f228c 100644\n--- a/t/helper/test-run-command.c\n+++ b/t/helper/test-run-command.c\n@@ -8,6 +8,7 @@\n  * published by the Free Software Foundation.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n #define DISABLE_SIGN_COMPARE_WARNINGS\n \n #include \"test-tool.h\"\n@@ -18,6 +19,7 @@\n #include \"string-list.h\"\n #include \"thread-utils.h\"\n #include \"wildmatch.h\"\n+#include \"repository.h\"\n \n static int number_callbacks;\n static int parallel_next(struct child_process *cp,\n-- \n2.53.0\n\n"},{"id":"538618","messageId":"20260311151923.4178655-5-bkkaracay@gmail.com","threadId":"65210","inReplyTo":"20260311151923.4178655-1-bkkaracay@gmail.com","subject":"[PATCH 4/4] cocci: convert start_command() to repo_start_command()","fromName":"Burak Kaan Karaçay","fromEmail":"bkkaracay@gmail.com","sentAt":"2026-03-11T15:19:23Z","receivedAt":"2026-03-11T15:19:55Z","isPatch":true,"sender":{"key":"bkkaracay@gmail.com","avatar":"https://avatars.githubusercontent.com/u/29117336?v=4"},"body":"Add and apply a semantic patch to migrate the remaining\n'start_command()' calls to 'repo_start_command()' by passing\n'the_repository' as the first parameter.\n\nSigned-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com>\n---\n archive-tar.c                           |  2 +-\n branch.c                                |  2 +-\n builtin/credential-cache.c              |  2 +-\n builtin/gc.c                            | 16 ++++++++--------\n builtin/help.c                          |  2 +-\n builtin/index-pack.c                    |  2 +-\n builtin/merge.c                         |  2 +-\n builtin/notes.c                         |  2 +-\n builtin/receive-pack.c                  |  6 +++---\n builtin/remote-ext.c                    |  2 +-\n builtin/repack.c                        |  2 +-\n builtin/replace.c                       |  2 +-\n builtin/upload-archive.c                |  2 +-\n builtin/worktree.c                      |  2 +-\n bundle-uri.c                            |  2 +-\n bundle.c                                |  2 +-\n column.c                                |  2 +-\n compat/mingw.c                          |  2 +-\n connect.c                               |  4 ++--\n connected.c                             |  2 +-\n contrib/coccinelle/the_repository.cocci |  3 +++\n convert.c                               |  2 +-\n credential.c                            |  2 +-\n daemon.c                                |  6 +++---\n diff.c                                  |  2 +-\n editor.c                                |  2 +-\n fetch-pack.c                            |  4 ++--\n http-backend.c                          |  2 +-\n imap-send.c                             |  2 +-\n midx-write.c                            |  2 +-\n parallel-checkout.c                     |  2 +-\n promisor-remote.c                       |  2 +-\n prompt.c                                |  2 +-\n range-diff.c                            |  2 +-\n reachable.c                             |  2 +-\n remote-curl.c                           |  2 +-\n repack-cruft.c                          |  2 +-\n repack-filtered.c                       |  2 +-\n repack-midx.c                           |  2 +-\n repack-promisor.c                       |  2 +-\n run-command.c                           |  8 ++++----\n sub-process.c                           |  2 +-\n submodule.c                             | 12 ++++++------\n t/helper/test-run-command.c             |  4 ++--\n transport-helper.c                      |  6 +++---\n upload-pack.c                           |  4 ++--\n 46 files changed, 73 insertions(+), 70 deletions(-)\n\ndiff --git a/archive-tar.c b/archive-tar.c\nindex 0fc70d13a8..78124443f5 100644\n--- a/archive-tar.c\n+++ b/archive-tar.c\n@@ -503,7 +503,7 @@ static int write_tar_filter_archive(const struct archiver *ar,\n \tfilter.in = -1;\n \tfilter.silent_exec_failure = 1;\n \n-\tif (start_command(&filter) < 0)\n+\tif (repo_start_command(the_repository, &filter) < 0)\n \t\tdie_errno(_(\"unable to start '%s' filter\"), cmd.buf);\n \tclose(1);\n \tif (dup2(filter.in, 1) < 0)\ndiff --git a/branch.c b/branch.c\nindex 243db7d0fc..878abff79d 100644\n--- a/branch.c\n+++ b/branch.c\n@@ -728,7 +728,7 @@ static int submodule_create_branch(struct repository *r,\n \n \tstrvec_pushl(&child.args, name, start_oid, tracking_name, NULL);\n \n-\tif ((ret = start_command(&child)))\n+\tif ((ret = repo_start_command(the_repository, &child)))\n \t\treturn ret;\n \tret = finish_command(&child);\n \tstrbuf_read(&child_err, child.err, 0);\ndiff --git a/builtin/credential-cache.c b/builtin/credential-cache.c\nindex fb17aa87ba..642d94fca0 100644\n--- a/builtin/credential-cache.c\n+++ b/builtin/credential-cache.c\n@@ -83,7 +83,7 @@ static void spawn_daemon(const char *socket)\n \tdaemon.no_stdin = 1;\n \tdaemon.out = -1;\n \n-\tif (start_command(&daemon))\n+\tif (repo_start_command(the_repository, &daemon))\n \t\tdie_errno(\"unable to start cache daemon\");\n \tr = read_in_full(daemon.out, buf, sizeof(buf));\n \tif (r < 0)\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex fb329c2cff..01da48cc32 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -1396,7 +1396,7 @@ static int pack_loose(struct maintenance_run_opts *opts)\n \t */\n \tpack_proc.out = -1;\n \n-\tif (start_command(&pack_proc)) {\n+\tif (repo_start_command(the_repository, &pack_proc)) {\n \t\terror(_(\"failed to start 'git pack-objects' process\"));\n \t\treturn 1;\n \t}\n@@ -2435,7 +2435,7 @@ static int launchctl_boot_plist(int enable, const char *filename)\n \tchild.no_stderr = 1;\n \tchild.no_stdout = 1;\n \n-\tif (start_command(&child))\n+\tif (repo_start_command(the_repository, &child))\n \t\tdie(_(\"failed to start launchctl\"));\n \n \tresult = finish_command(&child);\n@@ -2474,7 +2474,7 @@ static int launchctl_list_contains_plist(const char *name, const char *cmd)\n \tchild.no_stderr = 1;\n \tchild.no_stdout = 1;\n \n-\tif (start_command(&child))\n+\tif (repo_start_command(the_repository, &child))\n \t\tdie(_(\"failed to start launchctl\"));\n \n \t/* Returns failure if 'name' doesn't exist. */\n@@ -2766,7 +2766,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority\n \tchild.no_stdout = 1;\n \tchild.no_stderr = 1;\n \n-\tif (start_command(&child))\n+\tif (repo_start_command(the_repository, &child))\n \t\tdie(_(\"failed to start schtasks\"));\n \tresult = finish_command(&child);\n \n@@ -2860,7 +2860,7 @@ static int crontab_update_schedule(int run_maintenance, int fd)\n \tcrontab_list.out = dup(fd);\n \tcrontab_list.git_cmd = 0;\n \n-\tif (start_command(&crontab_list)) {\n+\tif (repo_start_command(the_repository, &crontab_list)) {\n \t\tresult = error(_(\"failed to run 'crontab -l'; your system might not support 'cron'\"));\n \t\tgoto out;\n \t}\n@@ -2924,7 +2924,7 @@ static int crontab_update_schedule(int run_maintenance, int fd)\n \tstrvec_push(&crontab_edit.args, get_tempfile_path(tmpedit));\n \tcrontab_edit.git_cmd = 0;\n \n-\tif (start_command(&crontab_edit)) {\n+\tif (repo_start_command(the_repository, &crontab_edit)) {\n \t\tresult = error(_(\"failed to run 'crontab'; your system might not support 'cron'\"));\n \t\tgoto out;\n \t}\n@@ -2950,7 +2950,7 @@ static int real_is_systemd_timer_available(void)\n \tchild.no_stderr = 1;\n \tchild.silent_exec_failure = 1;\n \n-\tif (start_command(&child))\n+\tif (repo_start_command(the_repository, &child))\n \t\treturn 0;\n \tif (finish_command(&child))\n \t\treturn 0;\n@@ -3169,7 +3169,7 @@ static int systemd_timer_enable_unit(int enable,\n \t\t     \"--now\", NULL);\n \tstrvec_pushf(&child.args, SYSTEMD_UNIT_FORMAT, frequency, \"timer\");\n \n-\tif (start_command(&child)) {\n+\tif (repo_start_command(the_repository, &child)) {\n \t\tret = error(_(\"failed to start systemctl\"));\n \t\tgoto out;\n \t}\ndiff --git a/builtin/help.c b/builtin/help.c\nindex 86a3d03a9b..3473a0ae9f 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -242,7 +242,7 @@ static int check_emacsclient_version(void)\n \tstrvec_pushl(&ec_process.args, \"emacsclient\", \"--version\", NULL);\n \tec_process.err = -1;\n \tec_process.stdout_to_stderr = 1;\n-\tif (start_command(&ec_process))\n+\tif (repo_start_command(the_repository, &ec_process))\n \t\treturn error(_(\"Failed to start emacsclient.\"));\n \n \tstrbuf_read(&buffer, ec_process.err, 20);\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex b67fb0256c..5be75cb0eb 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -1840,7 +1840,7 @@ static void repack_local_links(void)\n \t\t\tcmd.git_cmd = 1;\n \t\t\tcmd.in = -1;\n \t\t\tcmd.out = -1;\n-\t\t\tif (start_command(&cmd))\n+\t\t\tif (repo_start_command(the_repository, &cmd))\n \t\t\t\tdie(_(\"could not start pack-objects to repack local links\"));\n \t\t}\n \ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 4e456a381c..fb5875d1b2 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -357,7 +357,7 @@ static int save_state(struct object_id *stash)\n \tcp.out = -1;\n \tcp.git_cmd = 1;\n \n-\tif (start_command(&cp))\n+\tif (repo_start_command(the_repository, &cp))\n \t\tdie(_(\"could not run stash.\"));\n \tlen = strbuf_read(&buffer, cp.out, 1024);\n \tclose(cp.out);\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 9af602bdd7..bf9a46461d 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -173,7 +173,7 @@ static void write_commented_object(int fd, const struct object_id *object)\n \tshow.out = -1;\n \tshow.err = 0;\n \tshow.git_cmd = 1;\n-\tif (start_command(&show))\n+\tif (repo_start_command(the_repository, &show))\n \t\tdie(_(\"unable to start 'show' for object '%s'\"),\n \t\t    oid_to_hex(object));\n \ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex d6225df890..9533179bd6 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -1179,7 +1179,7 @@ static int run_proc_receive_hook(struct command *commands,\n \t\tproc.err = 0;\n \t}\n \n-\tcode = start_command(&proc);\n+\tcode = repo_start_command(the_repository, &proc);\n \tif (code) {\n \t\tif (use_sideband)\n \t\t\tfinish_async(&muxer);\n@@ -2411,7 +2411,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)\n \t\tchild.out = -1;\n \t\tchild.err = err_fd;\n \t\tchild.git_cmd = 1;\n-\t\tstatus = start_command(&child);\n+\t\tstatus = repo_start_command(the_repository, &child);\n \t\tif (status)\n \t\t\treturn \"index-pack fork failed\";\n \n@@ -2732,7 +2732,7 @@ int cmd_receive_pack(int argc,\n \t\t\t\tproc.stdout_to_stderr = 1;\n \t\t\t\tproc.err = use_sideband ? -1 : 0;\n \n-\t\t\t\tif (!start_command(&proc)) {\n+\t\t\t\tif (!repo_start_command(the_repository, &proc)) {\n \t\t\t\t\tif (use_sideband)\n \t\t\t\t\t\tcopy_to_sideband(proc.err, -1, NULL);\n \t\t\t\t\tfinish_command(&proc);\ndiff --git a/builtin/remote-ext.c b/builtin/remote-ext.c\nindex ed2d551753..f12eb0243b 100644\n--- a/builtin/remote-ext.c\n+++ b/builtin/remote-ext.c\n@@ -149,7 +149,7 @@ static int run_child(const char *arg, const char *service)\n \tchild.err = 0;\n \tparse_argv(&child.args, arg, service);\n \n-\tif (start_command(&child) < 0)\n+\tif (repo_start_command(the_repository, &child) < 0)\n \t\tdie(\"Can't run specified command\");\n \n \tif (git_req)\ndiff --git a/builtin/repack.c b/builtin/repack.c\nindex f6bb04bef7..3f7d83238c 100644\n--- a/builtin/repack.c\n+++ b/builtin/repack.c\n@@ -356,7 +356,7 @@ int cmd_repack(int argc,\n \telse\n \t\tcmd.no_stdin = 1;\n \n-\tret = start_command(&cmd);\n+\tret = repo_start_command(the_repository, &cmd);\n \tif (ret)\n \t\tgoto cleanup;\n \ndiff --git a/builtin/replace.c b/builtin/replace.c\nindex 4c62c5ab58..0abf5bc004 100644\n--- a/builtin/replace.c\n+++ b/builtin/replace.c\n@@ -278,7 +278,7 @@ static int import_object(struct object_id *oid, enum object_type type,\n \t\tcmd.in = fd;\n \t\tcmd.out = -1;\n \n-\t\tif (start_command(&cmd)) {\n+\t\tif (repo_start_command(the_repository, &cmd)) {\n \t\t\tclose(fd);\n \t\t\treturn error(_(\"unable to spawn mktree\"));\n \t\t}\ndiff --git a/builtin/upload-archive.c b/builtin/upload-archive.c\nindex 25312bb2a5..a840a78f6c 100644\n--- a/builtin/upload-archive.c\n+++ b/builtin/upload-archive.c\n@@ -106,7 +106,7 @@ struct repository *repo UNUSED)\n \twriter.git_cmd = 1;\n \tstrvec_push(&writer.args, \"upload-archive--writer\");\n \tstrvec_pushv(&writer.args, argv + 1);\n-\tif (start_command(&writer)) {\n+\tif (repo_start_command(the_repository, &writer)) {\n \t\tint err = errno;\n \t\tpacket_write_fmt(1, \"NACK unable to spawn subprocess\\n\");\n \t\tdie(\"upload-archive: %s\", strerror(err));\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex bc2d0d645b..eb509470e2 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -1363,7 +1363,7 @@ static void check_clean_worktree(struct worktree *wt,\n \tcp.git_cmd = 1;\n \tcp.dir = wt->path;\n \tcp.out = -1;\n-\tret = start_command(&cp);\n+\tret = repo_start_command(the_repository, &cp);\n \tif (ret)\n \t\tdie_errno(_(\"failed to run 'git status' on '%s'\"),\n \t\t\t  original_path);\ndiff --git a/bundle-uri.c b/bundle-uri.c\nindex 3b2e347288..b27b909785 100644\n--- a/bundle-uri.c\n+++ b/bundle-uri.c\n@@ -341,7 +341,7 @@ static int download_https_uri_to_file(const char *file, const char *uri)\n \tcp.in = -1;\n \tcp.out = -1;\n \n-\tif (start_command(&cp))\n+\tif (repo_start_command(the_repository, &cp))\n \t\treturn 1;\n \n \tchild_in = fdopen(cp.in, \"w\");\ndiff --git a/bundle.c b/bundle.c\nindex 42327f9739..d2d385fef6 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -355,7 +355,7 @@ static int write_pack_data(int bundle_fd, struct rev_info *revs, struct strvec *\n \t\t}\n \t}\n \n-\tif (start_command(&pack_objects))\n+\tif (repo_start_command(the_repository, &pack_objects))\n \t\treturn error(_(\"Could not spawn pack-objects\"));\n \n \tfor (i = 0; i < revs->pending.nr; i++) {\ndiff --git a/column.c b/column.c\nindex 998b2ab458..a2e26b993d 100644\n--- a/column.c\n+++ b/column.c\n@@ -388,7 +388,7 @@ int run_column_filter(int colopts, const struct column_options *opts)\n \tcolumn_process.out = dup(1);\n \tcolumn_process.git_cmd = 1;\n \n-\tif (start_command(&column_process))\n+\tif (repo_start_command(the_repository, &column_process))\n \t\treturn -2;\n \n \tfd_out = dup(1);\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex c667a2dcda..4825cf596a 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -35,7 +35,7 @@ void open_in_gdb(void)\n \tstrvec_pushl(&cp.args, \"mintty\", \"gdb\", NULL);\n \tstrvec_pushf(&cp.args, \"--pid=%d\", getpid());\n \tcp.clean_on_exit = 1;\n-\tif (start_command(&cp) < 0)\n+\tif (repo_start_command(the_repository, &cp) < 0)\n \t\tdie_errno(\"Could not start gdb\");\n \tsleep(1);\n }\ndiff --git a/connect.c b/connect.c\nindex a02583a102..b223fe7644 100644\n--- a/connect.c\n+++ b/connect.c\n@@ -1054,7 +1054,7 @@ static struct child_process *git_proxy_connect(int fd[2], char *host)\n \tstrvec_push(&proxy->args, port);\n \tproxy->in = -1;\n \tproxy->out = -1;\n-\tif (start_command(proxy))\n+\tif (repo_start_command(the_repository, proxy))\n \t\tdie(_(\"cannot start proxy %s\"), git_proxy_command);\n \tfd[0] = proxy->out; /* read from proxy stdout */\n \tfd[1] = proxy->in;  /* write to proxy stdin */\n@@ -1515,7 +1515,7 @@ struct child_process *git_connect(int fd[2], const char *url,\n \t\t}\n \t\tstrvec_push(&conn->args, cmd.buf);\n \n-\t\tif (start_command(conn))\n+\t\tif (repo_start_command(the_repository, conn))\n \t\t\tdie(_(\"unable to fork\"));\n \n \t\tfd[0] = conn->out; /* read from child's stdout */\ndiff --git a/connected.c b/connected.c\nindex 79403108dd..278cc6a123 100644\n--- a/connected.c\n+++ b/connected.c\n@@ -127,7 +127,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n \telse\n \t\trev_list.no_stderr = opt->quiet;\n \n-\tif (start_command(&rev_list)) {\n+\tif (repo_start_command(the_repository, &rev_list)) {\n \t\tfree(new_pack);\n \t\treturn error(_(\"Could not run 'git rev-list'\"));\n \t}\ndiff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci\nindex f1129f7985..ed0389ea12 100644\n--- a/contrib/coccinelle/the_repository.cocci\n+++ b/contrib/coccinelle/the_repository.cocci\n@@ -12,6 +12,9 @@\n |\n - parse_tree_indirect\n + repo_parse_tree_indirect\n+|\n+- start_command\n++ repo_start_command\n )\n   (\n + the_repository,\ndiff --git a/convert.c b/convert.c\nindex a34ec6ecdc..db3e1996ea 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -662,7 +662,7 @@ static int filter_buffer_or_fd(int in UNUSED, int out, void *data)\n \tchild_process.in = -1;\n \tchild_process.out = out;\n \n-\tif (start_command(&child_process)) {\n+\tif (repo_start_command(the_repository, &child_process)) {\n \t\tstrbuf_release(&cmd);\n \t\treturn error(_(\"cannot fork to run external filter '%s'\"),\n \t\t\t     params->cmd);\ndiff --git a/credential.c b/credential.c\nindex a513355105..5497051df1 100644\n--- a/credential.c\n+++ b/credential.c\n@@ -457,7 +457,7 @@ static int run_credential_helper(struct credential *c,\n \telse\n \t\thelper.no_stdout = 1;\n \n-\tif (start_command(&helper) < 0)\n+\tif (repo_start_command(the_repository, &helper) < 0)\n \t\treturn -1;\n \n \tfp = xfdopen(helper.in, \"w\");\ndiff --git a/daemon.c b/daemon.c\nindex 0a7b1aae44..8eb22851da 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -328,7 +328,7 @@ static int run_access_hook(struct daemon_service *service, const char *dir,\n \tchild.no_stdin = 1;\n \tchild.no_stderr = 1;\n \tchild.out = -1;\n-\tif (start_command(&child)) {\n+\tif (repo_start_command(the_repository, &child)) {\n \t\tlogerror(\"daemon access hook '%s' failed to start\",\n \t\t\t access_hook);\n \t\tgoto error_return;\n@@ -454,7 +454,7 @@ static int run_service_command(struct child_process *cld)\n \tstrvec_push(&cld->args, \".\");\n \tcld->git_cmd = 1;\n \tcld->err = -1;\n-\tif (start_command(cld))\n+\tif (repo_start_command(the_repository, cld))\n \t\treturn -1;\n \n \tclose(0);\n@@ -906,7 +906,7 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)\n \tcld.in = incoming;\n \tcld.out = dup(incoming);\n \n-\tif (start_command(&cld))\n+\tif (repo_start_command(the_repository, &cld))\n \t\tlogerror(\"unable to fork\");\n \telse\n \t\tadd_child(&cld, addr, addrlen);\ndiff --git a/diff.c b/diff.c\nindex e87847fa4b..fbda03ac18 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -7467,7 +7467,7 @@ static char *run_textconv(struct repository *r,\n \n \tchild.use_shell = 1;\n \tchild.out = -1;\n-\tif (start_command(&child)) {\n+\tif (repo_start_command(the_repository, &child)) {\n \t\tremove_tempfile();\n \t\treturn NULL;\n \t}\ndiff --git a/editor.c b/editor.c\nindex fd174e6a03..c96311bb3f 100644\n--- a/editor.c\n+++ b/editor.c\n@@ -92,7 +92,7 @@ static int launch_specified_editor(const char *editor, const char *path,\n \t\t\tstrvec_pushv(&p.env, (const char **)env);\n \t\tp.use_shell = 1;\n \t\tp.trace2_child_class = \"editor\";\n-\t\tif (start_command(&p) < 0) {\n+\t\tif (repo_start_command(the_repository, &p) < 0) {\n \t\t\tstrbuf_release(&realpath);\n \t\t\treturn error(\"unable to start editor '%s'\", editor);\n \t\t}\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex 6ecd468ef7..64476f852f 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -1035,7 +1035,7 @@ static int get_pack(struct fetch_pack_args *args,\n \n \tcmd.in = demux.out;\n \tcmd.git_cmd = 1;\n-\tif (start_command(&cmd))\n+\tif (repo_start_command(the_repository, &cmd))\n \t\tdie(_(\"fetch-pack: unable to fork off %s\"), cmd_name);\n \tif (do_keep && (pack_lockfiles || fsck_objects)) {\n \t\tint is_well_formed;\n@@ -1841,7 +1841,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,\n \t\tcmd.git_cmd = 1;\n \t\tcmd.no_stdin = 1;\n \t\tcmd.out = -1;\n-\t\tif (start_command(&cmd))\n+\t\tif (repo_start_command(the_repository, &cmd))\n \t\t\tdie(\"fetch-pack: unable to spawn http-fetch\");\n \n \t\tif (read_in_full(cmd.out, packname, 5) < 0 ||\ndiff --git a/http-backend.c b/http-backend.c\nindex 1a171c5c5a..08ffb4a393 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -501,7 +501,7 @@ static void run_service(const char **argv, int buffer_input)\n \tcld.git_cmd = 1;\n \tcld.clean_on_exit = 1;\n \tcld.wait_after_clean = 1;\n-\tif (start_command(&cld))\n+\tif (repo_start_command(the_repository, &cld))\n \t\texit(1);\n \n \tclose(1);\ndiff --git a/imap-send.c b/imap-send.c\nindex 26dda7f328..fefdb7a4ba 100644\n--- a/imap-send.c\n+++ b/imap-send.c\n@@ -1155,7 +1155,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, const c\n \t\ttunnel.use_shell = 1;\n \t\ttunnel.in = -1;\n \t\ttunnel.out = -1;\n-\t\tif (start_command(&tunnel))\n+\t\tif (repo_start_command(the_repository, &tunnel))\n \t\t\tdie(\"cannot start proxy %s\", srvc->tunnel);\n \n \t\timap->buf.sock.fd[0] = tunnel.out;\ndiff --git a/midx-write.c b/midx-write.c\nindex a53f77f13a..a1051e7807 100644\n--- a/midx-write.c\n+++ b/midx-write.c\n@@ -1828,7 +1828,7 @@ int midx_repack(struct odb_source *source, size_t batch_size, unsigned flags)\n \tcmd.git_cmd = 1;\n \tcmd.in = cmd.out = -1;\n \n-\tif (start_command(&cmd)) {\n+\tif (repo_start_command(the_repository, &cmd)) {\n \t\terror(_(\"could not start pack-objects\"));\n \t\tresult = 1;\n \t\tgoto cleanup;\ndiff --git a/parallel-checkout.c b/parallel-checkout.c\nindex 0bf4bd6d4a..bd4e8afcf8 100644\n--- a/parallel-checkout.c\n+++ b/parallel-checkout.c\n@@ -476,7 +476,7 @@ static struct pc_worker *setup_workers(struct checkout *state, int num_workers)\n \t\tstrvec_push(&cp->args, \"checkout--worker\");\n \t\tif (state->base_dir_len)\n \t\t\tstrvec_pushf(&cp->args, \"--prefix=%s\", state->base_dir);\n-\t\tif (start_command(cp))\n+\t\tif (repo_start_command(the_repository, cp))\n \t\t\tdie(\"failed to spawn checkout worker\");\n \t}\n \ndiff --git a/promisor-remote.c b/promisor-remote.c\nindex 96fa215b06..4e861260fe 100644\n--- a/promisor-remote.c\n+++ b/promisor-remote.c\n@@ -48,7 +48,7 @@ static int fetch_objects(struct repository *repo,\n \t\t     \"--filter=blob:none\", \"--stdin\", NULL);\n \tif (!repo_config_get_bool(the_repository, \"promisor.quiet\", &quiet) && quiet)\n \t\tstrvec_push(&child.args, \"--quiet\");\n-\tif (start_command(&child))\n+\tif (repo_start_command(the_repository, &child))\n \t\tdie(_(\"promisor-remote: unable to fork off fetch subprocess\"));\n \tchild_in = xfdopen(child.in, \"w\");\n \ndiff --git a/prompt.c b/prompt.c\nindex 20a8c34438..7ff5e8adf9 100644\n--- a/prompt.c\n+++ b/prompt.c\n@@ -20,7 +20,7 @@ static char *do_askpass(const char *cmd, const char *prompt)\n \n \tpass.out = -1;\n \n-\tif (start_command(&pass))\n+\tif (repo_start_command(the_repository, &pass))\n \t\treturn NULL;\n \n \tstrbuf_reset(&buffer);\ndiff --git a/range-diff.c b/range-diff.c\nindex 57edff40a8..a698d84ae1 100644\n--- a/range-diff.c\n+++ b/range-diff.c\n@@ -75,7 +75,7 @@ static int read_patches(const char *range, struct string_list *list,\n \tcp.no_stdin = 1;\n \tcp.git_cmd = 1;\n \n-\tif (start_command(&cp))\n+\tif (repo_start_command(the_repository, &cp))\n \t\treturn error_errno(_(\"could not start `log`\"));\n \tif (strbuf_read(&contents, cp.out, 0) < 0) {\n \t\terror_errno(_(\"could not read `log` output\"));\ndiff --git a/reachable.c b/reachable.c\nindex 101cfc2727..64dcaa6b23 100644\n--- a/reachable.c\n+++ b/reachable.c\n@@ -138,7 +138,7 @@ static int run_one_gc_recent_objects_hook(struct oidset *set,\n \n \tstrvec_push(&cmd.args, args);\n \n-\tif (start_command(&cmd))\n+\tif (repo_start_command(the_repository, &cmd))\n \t\treturn -1;\n \n \tout = xfdopen(cmd.out, \"r\");\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 92e40bb682..5db038302e 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -1093,7 +1093,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads,\n \tclient.out = -1;\n \tclient.git_cmd = 1;\n \tstrvec_pushv(&client.args, client_argv);\n-\tif (start_command(&client))\n+\tif (repo_start_command(the_repository, &client))\n \t\texit(1);\n \twrite_or_die(client.in, preamble->buf, preamble->len);\n \tif (heads)\ndiff --git a/repack-cruft.c b/repack-cruft.c\nindex 0bfc77792a..af4665d029 100644\n--- a/repack-cruft.c\n+++ b/repack-cruft.c\n@@ -62,7 +62,7 @@ int write_cruft_pack(const struct write_pack_opts *opts,\n \n \tcmd.in = -1;\n \n-\tret = start_command(&cmd);\n+\tret = repo_start_command(the_repository, &cmd);\n \tif (ret)\n \t\treturn ret;\n \ndiff --git a/repack-filtered.c b/repack-filtered.c\nindex 2f5d1dd709..b21a7d92a4 100644\n--- a/repack-filtered.c\n+++ b/repack-filtered.c\n@@ -26,7 +26,7 @@ int write_filtered_pack(const struct write_pack_opts *opts,\n \n \tcmd.in = -1;\n \n-\tret = start_command(&cmd);\n+\tret = repo_start_command(the_repository, &cmd);\n \tif (ret)\n \t\treturn ret;\n \ndiff --git a/repack-midx.c b/repack-midx.c\nindex 8b4c0d95e3..32286b5507 100644\n--- a/repack-midx.c\n+++ b/repack-midx.c\n@@ -344,7 +344,7 @@ int write_midx_included_packs(struct repack_write_midx_opts *opts)\n \t\tstrvec_pushf(&cmd.args, \"--refs-snapshot=%s\",\n \t\t\t     opts->refs_snapshot);\n \n-\tret = start_command(&cmd);\n+\tret = repo_start_command(the_repository, &cmd);\n \tif (ret)\n \t\tgoto done;\n \ndiff --git a/repack-promisor.c b/repack-promisor.c\nindex 70ef19d04f..03b17884a3 100644\n--- a/repack-promisor.c\n+++ b/repack-promisor.c\n@@ -26,7 +26,7 @@ static int write_oid(const struct object_id *oid,\n \tstruct child_process *cmd = ctx->cmd;\n \n \tif (cmd->in == -1) {\n-\t\tif (start_command(cmd))\n+\t\tif (repo_start_command(the_repository, cmd))\n \t\t\tdie(_(\"could not start pack-objects to repack promisor objects\"));\n \t}\n \ndiff --git a/run-command.c b/run-command.c\nindex af26c636a9..b7e7ebdf7d 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -1015,7 +1015,7 @@ int run_command(struct child_process *cmd)\n \tif (cmd->out < 0 || cmd->err < 0)\n \t\tBUG(\"run_command with a pipe can cause deadlock\");\n \n-\tcode = start_command(cmd);\n+\tcode = repo_start_command(the_repository, cmd);\n \tif (code)\n \t\treturn code;\n \treturn finish_command(cmd);\n@@ -1430,7 +1430,7 @@ int pipe_command(struct child_process *cmd,\n \tif (err)\n \t\tcmd->err = -1;\n \n-\tif (start_command(cmd) < 0)\n+\tif (repo_start_command(the_repository, cmd) < 0)\n \t\treturn -1;\n \n \tif (in) {\n@@ -1652,7 +1652,7 @@ static int pp_start_one(struct parallel_processes *pp,\n \t\tpp->children[i].process.stdout_to_stderr = 1;\n \t}\n \n-\tif (start_command(&pp->children[i].process)) {\n+\tif (repo_start_command(the_repository, &pp->children[i].process)) {\n \t\tif (opts->start_failure)\n \t\t\tcode = opts->start_failure(opts->ungroup ? NULL :\n \t\t\t\t\t\t   &pp->children[i].err,\n@@ -2006,7 +2006,7 @@ enum start_bg_result start_bg_command(struct child_process *cmd,\n \tif (!cmd->trace2_child_class)\n \t\tcmd->trace2_child_class = \"background\";\n \n-\tret = start_command(cmd);\n+\tret = repo_start_command(the_repository, cmd);\n \tif (ret) {\n \t\t/*\n \t\t * We assume that if `start_command()` fails, we\ndiff --git a/sub-process.c b/sub-process.c\nindex ae7493eb5c..abfa856860 100644\n--- a/sub-process.c\n+++ b/sub-process.c\n@@ -93,7 +93,7 @@ int subprocess_start(struct hashmap *hashmap, struct subprocess_entry *entry, co\n \tprocess->clean_on_exit_handler = subprocess_exit_handler;\n \tprocess->trace2_child_class = \"subprocess\";\n \n-\terr = start_command(process);\n+\terr = repo_start_command(the_repository, process);\n \tif (err) {\n \t\terror(\"cannot fork to run subprocess '%s'\", cmd);\n \t\treturn err;\ndiff --git a/submodule.c b/submodule.c\nindex 4f9aaa2c75..40c474f927 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -718,7 +718,7 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,\n \t\tstrvec_push(&cp.env, GIT_WORK_TREE_ENVIRONMENT \"=.\");\n \t}\n \n-\tif (start_command(&cp)) {\n+\tif (repo_start_command(the_repository, &cp)) {\n \t\tdiff_emit_submodule_error(o, \"(diff failed)\\n\");\n \t\tgoto done;\n \t}\n@@ -1064,7 +1064,7 @@ static int submodule_needs_pushing(struct repository *r,\n \t\tcp.no_stdin = 1;\n \t\tcp.out = -1;\n \t\tcp.dir = path;\n-\t\tif (start_command(&cp))\n+\t\tif (repo_start_command(the_repository, &cp))\n \t\t\tdie(_(\"Could not run 'git rev-list <commits> --not --remotes -n 1' command in submodule %s\"),\n \t\t\t\t\tpath);\n \t\tif (strbuf_read(&buf, cp.out, the_hash_algo->hexsz + 1))\n@@ -1899,7 +1899,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)\n \tcp.no_stdin = 1;\n \tcp.out = -1;\n \tcp.dir = path;\n-\tif (start_command(&cp))\n+\tif (repo_start_command(the_repository, &cp))\n \t\tdie(_(\"Could not run 'git status --porcelain=2' in submodule %s\"), path);\n \n \tfp = xfdopen(cp.out, \"r\");\n@@ -2020,7 +2020,7 @@ int bad_to_remove_submodule(const char *path, unsigned flags)\n \tcp.no_stdin = 1;\n \tcp.out = -1;\n \tcp.dir = path;\n-\tif (start_command(&cp)) {\n+\tif (repo_start_command(the_repository, &cp)) {\n \t\tif (flags & SUBMODULE_REMOVAL_DIE_ON_ERROR)\n \t\t\tdie(_(\"could not start 'git status' in submodule '%s'\"),\n \t\t\t\tpath);\n@@ -2076,7 +2076,7 @@ static int submodule_has_dirty_index(const struct submodule *sub)\n \tcp.no_stdin = 1;\n \tcp.no_stdout = 1;\n \tcp.dir = sub->path;\n-\tif (start_command(&cp))\n+\tif (repo_start_command(the_repository, &cp))\n \t\tdie(_(\"could not recurse into submodule '%s'\"), sub->path);\n \n \treturn finish_command(&cp);\n@@ -2636,7 +2636,7 @@ int get_superproject_working_tree(struct strbuf *buf)\n \tcp.out = -1;\n \tcp.git_cmd = 1;\n \n-\tif (start_command(&cp))\n+\tif (repo_start_command(the_repository, &cp))\n \t\tdie(_(\"could not start ls-files in ..\"));\n \n \tlen = strbuf_read(&sb, cp.out, PATH_MAX);\ndiff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c\nindex dcd58f228c..fb2ba4b7b6 100644\n--- a/t/helper/test-run-command.c\n+++ b/t/helper/test-run-command.c\n@@ -415,7 +415,7 @@ static int inherit_handle(const char *argv0)\n \t\t     \"test-tool\", argv0, \"inherited-handle-child\", NULL);\n \tcp.in = -1;\n \tcp.no_stdout = cp.no_stderr = 1;\n-\tif (start_command(&cp) < 0)\n+\tif (repo_start_command(the_repository, &cp) < 0)\n \t\tdie(\"Could not start child process\");\n \n \t/* Then close it, and try to delete it. */\n@@ -479,7 +479,7 @@ int cmd__run_command(int argc, const char **argv)\n \tstrvec_pushv(&proc.args, (const char **)argv + 2);\n \n \tif (!strcmp(argv[1], \"start-command-ENOENT\")) {\n-\t\tif (start_command(&proc) < 0 && errno == ENOENT) {\n+\t\tif (repo_start_command(the_repository, &proc) < 0 && errno == ENOENT) {\n \t\t\tret = 0;\n \t\t\tgoto cleanup;\n \t\t}\ndiff --git a/transport-helper.c b/transport-helper.c\nindex 4d95d84f9e..c2bfab4c6d 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -154,7 +154,7 @@ static struct child_process *get_helper(struct transport *transport)\n \n \thelper->trace2_child_class = helper->args.v[0]; /* \"remote-<name>\" */\n \n-\tcode = start_command(helper);\n+\tcode = repo_start_command(the_repository, helper);\n \tif (code < 0 && errno == ENOENT)\n \t\tdie(_(\"unable to find remote helper for '%s'\"), data->name);\n \telse if (code != 0)\n@@ -471,7 +471,7 @@ static int get_importer(struct transport *transport, struct child_process *fasti\n \t}\n \tfastimport->git_cmd = 1;\n \n-\tcode = start_command(fastimport);\n+\tcode = repo_start_command(the_repository, fastimport);\n \treturn code;\n }\n \n@@ -500,7 +500,7 @@ static int get_exporter(struct transport *transport,\n \t\tstrvec_push(&fastexport->args, revlist_args->items[i].string);\n \n \tfastexport->git_cmd = 1;\n-\treturn start_command(fastexport);\n+\treturn repo_start_command(the_repository, fastexport);\n }\n \n static int fetch_with_import(struct transport *transport,\ndiff --git a/upload-pack.c b/upload-pack.c\nindex e8c5cce1c7..a8143b7b18 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -338,7 +338,7 @@ static void create_pack_file(struct upload_pack_data *pack_data,\n \tpack_objects.err = -1;\n \tpack_objects.clean_on_exit = 1;\n \n-\tif (start_command(&pack_objects))\n+\tif (repo_start_command(the_repository, &pack_objects))\n \t\tdie(\"git upload-pack: unable to fork git-pack-objects\");\n \n \tpipe_fd = xfdopen(pack_objects.in, \"w\");\n@@ -661,7 +661,7 @@ static int do_reachable_revlist(struct child_process *cmd,\n \t */\n \tsigchain_push(SIGPIPE, SIG_IGN);\n \n-\tif (start_command(cmd))\n+\tif (repo_start_command(the_repository, cmd))\n \t\tgoto error;\n \n \tcmd_in = xfdopen(cmd->in, \"w\");\n-- \n2.53.0\n\n"},{"id":"538651","messageId":"041604ef-0bdb-4c40-a9e1-60c38ae664cb@web.de","threadId":"65210","inReplyTo":"20260311151923.4178655-1-bkkaracay@gmail.com","subject":"Re: [PATCH 0/4] wean start_command() off the_repository","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-03-11T18:18:10Z","receivedAt":"2026-03-11T18:18:19Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"On 3/11/26 4:19 PM, Burak Kaan Karaçay wrote:\n> \n> start_command() relies on the_repository due to the 'close_object_store'\n> flag in 'struct child_process'. Introduce repo_start_command() to allow\n> working with arbitrary repositories. Turn start_command() into a macro\n> that wraps repo_start_command() and migrate the existing callers with a\n> cocci script.\n\nGood idea to expose this hidden dependency.  It's different from the\nother repo_* functions, though, in that most callers can safely pass\nNULL as repo because they don't set close_object_store.\n\nOnly gc, pull and auto-maintenance set close_object_store.  If we\nchanged them to set a pointer to the object store they want to have\nclosed instead of a binary flag then we could leave the other callers\nunchanged.\n\nRené\n\n"},{"id":"538657","messageId":"20260311184522.GB1911377@coredump.intra.peff.net","threadId":"65210","inReplyTo":"041604ef-0bdb-4c40-a9e1-60c38ae664cb@web.de","subject":"Re: [PATCH 0/4] wean start_command() off the_repository","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-03-11T18:45:22Z","receivedAt":"2026-03-11T18:45:24Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Mar 11, 2026 at 07:18:10PM +0100, René Scharfe wrote:\n\n> On 3/11/26 4:19 PM, Burak Kaan Karaçay wrote:\n> > \n> > start_command() relies on the_repository due to the 'close_object_store'\n> > flag in 'struct child_process'. Introduce repo_start_command() to allow\n> > working with arbitrary repositories. Turn start_command() into a macro\n> > that wraps repo_start_command() and migrate the existing callers with a\n> > cocci script.\n> \n> Good idea to expose this hidden dependency.  It's different from the\n> other repo_* functions, though, in that most callers can safely pass\n> NULL as repo because they don't set close_object_store.\n> \n> Only gc, pull and auto-maintenance set close_object_store.  If we\n> changed them to set a pointer to the object store they want to have\n> closed instead of a binary flag then we could leave the other callers\n> unchanged.\n\nFWIW, I was about to write the exact same suggestion.\n\n-Peff\n"},{"id":"538660","messageId":"abG88QUMLptyirHg@gmail.com","threadId":"65210","inReplyTo":"041604ef-0bdb-4c40-a9e1-60c38ae664cb@web.de","subject":"Re: [PATCH 0/4] wean start_command() off the_repository","fromName":"Burak Kaan Karaçay","fromEmail":"bkkaracay@gmail.com","sentAt":"2026-03-11T19:09:04Z","receivedAt":"2026-03-11T19:09:08Z","isPatch":true,"sender":{"key":"bkkaracay@gmail.com","avatar":"https://avatars.githubusercontent.com/u/29117336?v=4"},"body":"On Wed, Mar 11, 2026 at 07:18:10PM +0100, René Scharfe wrote:\n>Only gc, pull and auto-maintenance set close_object_store.  If we\n>changed them to set a pointer to the object store they want to have\n>closed instead of a binary flag then we could leave the other callers\n>unchanged.\n\nWow. That's... elegant! I have never considered that. I will start\npreparing v2.\n\nThanks,\nBurak Kaan Karaçay\n"},{"id":"538663","messageId":"xmqqsea6np5z.fsf@gitster.g","threadId":"65210","inReplyTo":"20260311151923.4178655-3-bkkaracay@gmail.com","subject":"Re: [PATCH 2/4] run-command: use repo_start_command() in strict callers","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-11T19:26:16Z","receivedAt":"2026-03-11T19:26:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Burak Kaan Karaçay <bkkaracay@gmail.com> writes:\n\n> Some callers have been freed from global state and they do not define\n> the 'USE_THE_REPOSITORY_VARIABLE' macro.\n>\n> To complete the mitigation of 'start_command()', update these callers to\n> use repo_start_command() and pass their local 'struct repository' as an\n> argument, completely eliminating their hidden reliance on the global\n> state.\n>\n> Signed-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com>\n> ---\n>  builtin/difftool.c | 4 ++--\n>  odb.c              | 2 +-\n>  pager.c            | 2 +-\n>  repack-promisor.c  | 2 +-\n>  send-pack.c        | 4 ++--\n>  5 files changed, 7 insertions(+), 7 deletions(-)\n>\n> diff --git a/builtin/difftool.c b/builtin/difftool.c\n> index e4bc1f8316..15ac552edf 100644\n> --- a/builtin/difftool.c\n> +++ b/builtin/difftool.c\n> @@ -257,7 +257,7 @@ static void changed_files(struct repository *repo,\n>  \tdiff_files.out = -1;\n>  \tdiff_files.dir = workdir;\n>  \tstrvec_pushf(&diff_files.env, \"GIT_INDEX_FILE=%s\", index_path);\n> -\tif (start_command(&diff_files))\n> +\tif (repo_start_command(repo, &diff_files))\n>  \t\tdie(\"could not obtain raw diff\");\n>  \tfp = xfdopen(diff_files.out, \"r\");\n>  \twhile (!strbuf_getline_nul(&buf, fp)) {\n> @@ -437,7 +437,7 @@ static int run_dir_diff(struct repository *repo,\n>  \tchild->clean_on_exit = 1;\n>  \tchild->dir = prefix;\n>  \tchild->out = -1;\n> -\tif (start_command(child))\n> +\tif (repo_start_command(repo, child))\n>  \t\tdie(\"could not obtain raw diff\");\n>  \tfp = xfdopen(child->out, \"r\");\n\nUp to [1/4], we called start_command(), running the new process in\nthe context of the_repository, and if these \"repo\" were referring to\na repository different from the_repository, we risk changing the\nbehaviour without meaning to do so.\n\nThe difftool command, however, would not be dealing with multiple\nrepositories so it is very likely that the \"repo\" passed to these\ntwo functions are the_repository _anyway_, so these changes are\ncorrect, safe, and a move in the right direction.\n\n> diff --git a/odb.c b/odb.c\n> index 776de5356c..8ec279f84e 100644\n> --- a/odb.c\n> +++ b/odb.c\n> @@ -535,7 +535,7 @@ static void read_alternate_refs(struct repository *repo,\n>  \n>  \tfill_alternate_refs_command(repo, &cmd, path);\n>  \n> -\tif (start_command(&cmd))\n> +\tif (repo_start_command(repo, &cmd))\n>  \t\treturn;\n>  \n>  \tfh = xfdopen(cmd.out, \"r\");\n\nThe only semantic change brought in by [1/4] to start_command() is\nthat the object store of the named repository is closed, instead of\nthe object store of the_repository.  The read_alternate_refs()\nfunction calls fill_alternate_refs_command() to run for-each-ref in\nthe named \"repo\" to find out the refs _they_ have.\n\nBut then, do we really want to close the object database we have\nbeen using in the context of that \"repo\", that is different from\n\"the_repository\" we have been using so far?\n\nOf course, there is no guarantee that the_repository is always the\n\"current\" repository object we are using and trying to read the refs\nfrom this alternate repository in the codebase in an imaginary\nfuture where we can start from one repository, add refs from an\nalternate repository, and while doing so, we may add refs from an\nalternate of the alternate repository, so always starting from\nthe_repository may not be correct, either.  But even before going\nthere, closing object store of \"repo\" feels more wrong than from\n\"the_repository\".  Perhaps repo_start_command() needs to be aware of\ntwo repositories, one that we have been using and neeed to close the\nobject store if instructed, and the other one that we want to launch\nthe new process in its context?  Keeping \"the current repository\" as\na global variable will drag us back to the similar issues these\nefforts to wean us from \"the_repository\" global are trying to\naddress, so if our new repo_start_command() does need to be aware of\nthe two repositories, perhaps it needs to take two repository\nparameters (i.e., where we are coming from, and where we are going\nto)?  I dunno.\n\n> diff --git a/pager.c b/pager.c\n> index 5531fff50e..9a23ed958d 100644\n> --- a/pager.c\n> +++ b/pager.c\n> @@ -169,7 +169,7 @@ void setup_pager(struct repository *r)\n>  \tprepare_pager_args(&pager_process, pager);\n>  \tpager_process.in = -1;\n>  \tstrvec_push(&pager_process.env, \"GIT_PAGER_IN_USE\");\n> -\tif (start_command(&pager_process))\n> +\tif (repo_start_command(r, &pager_process))\n>  \t\tdie(\"unable to execute pager '%s'\", pager);\n>  \n>  \t/* original process continues, but writes to the pipe */\n\nOK.\n\n> diff --git a/repack-promisor.c b/repack-promisor.c\n> index 90318ce150..dba161a11a 100644\n> --- a/repack-promisor.c\n> +++ b/repack-promisor.c\n> @@ -125,7 +125,7 @@ void pack_geometry_repack_promisors(struct repository *repo,\n>  \tprepare_pack_objects(&cmd, args, packtmp);\n>  \tstrvec_push(&cmd.args, \"--stdin-packs\");\n>  \tcmd.in = -1;\n> -\tif (start_command(&cmd))\n> +\tif (repo_start_command(repo, &cmd))\n>  \t\tdie(_(\"could not start pack-objects to repack promisor packs\"));\n>  \n>  \tin = xfdopen(cmd.in, \"w\");\n\nOK.\n\n> diff --git a/send-pack.c b/send-pack.c\n> index 67d6987b1c..c339c3d1ca 100644\n> --- a/send-pack.c\n> +++ b/send-pack.c\n> @@ -92,7 +92,7 @@ static int pack_objects(struct repository *r,\n>  \tpo.out = args->stateless_rpc ? -1 : fd;\n>  \tpo.git_cmd = 1;\n>  \tpo.clean_on_exit = 1;\n> -\tif (start_command(&po))\n> +\tif (repo_start_command(r, &po))\n>  \t\tdie_errno(\"git pack-objects failed\");\n\nOK.\n\n> @@ -459,7 +459,7 @@ static void get_commons_through_negotiation(struct repository *r,\n>  \t\treturn;\n>  \t}\n>  \n> -\tif (start_command(&child))\n> +\tif (repo_start_command(r, &child))\n>  \t\tdie(_(\"send-pack: unable to fork off fetch subprocess\"));\n>  \n>  \tdo {\n\nOK.\n"},{"id":"538665","messageId":"xmqqo6kunoyl.fsf@gitster.g","threadId":"65210","inReplyTo":"20260311151923.4178655-1-bkkaracay@gmail.com","subject":"Re: [PATCH 0/4] wean start_command() off the_repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-11T19:30:42Z","receivedAt":"2026-03-11T19:30:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Burak Kaan Karaçay <bkkaracay@gmail.com> writes:\n\n> start_command() relies on the_repository due to the 'close_object_store'\n> flag in 'struct child_process'. Introduce repo_start_command() to allow\n> working with arbitrary repositories. Turn start_command() into a macro\n> that wraps repo_start_command() and migrate the existing callers with a\n> cocci script.\n>\n> For callers that cannot access 'the_repository' due to the lack of\n> USE_THE_REPOSITORY_VARIABLE, define the macro. If the caller already has\n> a local repository context, pass it explicitly instead of defining the\n> macro.\n>\n> Thanks,\n> Burak Kaan Karaçay\n>\n> Burak Kaan Karaçay (4):\n>   run-command: add repo_start_command()\n>   run-command: use repo_start_command() in strict callers\n>   run-command: redefine start_command() as a wrapper macro\n>   cocci: convert start_command() to repo_start_command()\n\nThe organization to start with a wrapper, and then moving to a macro\nthat is protected behind USE_THE_REPOSITORY_VARIABLE, makes quite a\nlot of sense.  I do not know the answer to the question I asked on\n\"don't we need to know from which repository we are closing the\nobject store while switching to this new repository?\", and without\nknowing the answer, we cannot quite decide what the function\nsignature of repo_start_command() should look like, so the last step\nmight be a bit premature.\n\nOther than that, a well reasoned series.\n\nThanks.\n"},{"id":"538667","messageId":"xmqqjyvinoqp.fsf@gitster.g","threadId":"65210","inReplyTo":"041604ef-0bdb-4c40-a9e1-60c38ae664cb@web.de","subject":"Re: [PATCH 0/4] wean start_command() off the_repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-11T19:35:26Z","receivedAt":"2026-03-11T19:35:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n> On 3/11/26 4:19 PM, Burak Kaan Karaçay wrote:\n>> \n>> start_command() relies on the_repository due to the 'close_object_store'\n>> flag in 'struct child_process'. Introduce repo_start_command() to allow\n>> working with arbitrary repositories. Turn start_command() into a macro\n>> that wraps repo_start_command() and migrate the existing callers with a\n>> cocci script.\n>\n> Good idea to expose this hidden dependency.  It's different from the\n> other repo_* functions, though, in that most callers can safely pass\n> NULL as repo because they don't set close_object_store.\n>\n> Only gc, pull and auto-maintenance set close_object_store.  If we\n> changed them to set a pointer to the object store they want to have\n> closed instead of a binary flag then we could leave the other callers\n> unchanged.\n\nYou solved my \"don't we need to know where we are coming from, in\naddition to where we are going?\" question elegantly.\n\nThanks.\n"},{"id":"538735","messageId":"20260312085341.631318-1-bkkaracay@gmail.com","threadId":"65210","inReplyTo":"20260311151923.4178655-1-bkkaracay@gmail.com","subject":"[PATCH v2] run-command: wean start_command() off the_repository","fromName":"Burak Kaan Karaçay","fromEmail":"bkkaracay@gmail.com","sentAt":"2026-03-12T08:53:41Z","receivedAt":"2026-03-12T08:53:59Z","isPatch":true,"sender":{"key":"bkkaracay@gmail.com","avatar":"https://avatars.githubusercontent.com/u/29117336?v=4"},"body":"The start_command() relies on the_repository due to the\nclose_object_store flag in 'struct child_process'. When this flag is\nset, start_command() closes the object store associated with\nthe_repository before spawning a child process.\n\nTo eliminate this dependency, replace the 'close_object_store' with the\nnew 'odb_to_close' field. This allows callers to specify the object\nstore that needs to be closed.\n\nSuggested-by: René Scharfe <l.s.r@web.de>\nSigned-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com>\n---\n builtin/gc.c   | 14 +++++++++-----\n builtin/pull.c |  2 +-\n run-command.c  |  6 +++---\n run-command.h  |  2 +-\n 4 files changed, 14 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex fb329c2cff..5d8d358f7a 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -1030,7 +1030,7 @@ int cmd_gc(int argc,\n \t\tstruct child_process repack_cmd = CHILD_PROCESS_INIT;\n \n \t\trepack_cmd.git_cmd = 1;\n-\t\trepack_cmd.close_object_store = 1;\n+\t\trepack_cmd.odb_to_close = the_repository->objects;\n \t\tstrvec_pushv(&repack_cmd.args, repack_args.v);\n \t\tif (run_command(&repack_cmd))\n \t\t\tdie(FAILED_RUN, repack_args.v[0]);\n@@ -1199,7 +1199,8 @@ static int run_write_commit_graph(struct maintenance_run_opts *opts)\n {\n \tstruct child_process child = CHILD_PROCESS_INIT;\n \n-\tchild.git_cmd = child.close_object_store = 1;\n+\tchild.git_cmd = 1;\n+\tchild.odb_to_close = the_repository->objects;\n \tstrvec_pushl(&child.args, \"commit-graph\", \"write\",\n \t\t     \"--split\", \"--reachable\", NULL);\n \n@@ -1268,7 +1269,8 @@ static int maintenance_task_gc_background(struct maintenance_run_opts *opts,\n {\n \tstruct child_process child = CHILD_PROCESS_INIT;\n \n-\tchild.git_cmd = child.close_object_store = 1;\n+\tchild.git_cmd = 1;\n+\tchild.odb_to_close = the_repository->objects;\n \tstrvec_push(&child.args, \"gc\");\n \n \tif (opts->auto_flag)\n@@ -1484,7 +1486,8 @@ static int multi_pack_index_expire(struct maintenance_run_opts *opts)\n {\n \tstruct child_process child = CHILD_PROCESS_INIT;\n \n-\tchild.git_cmd = child.close_object_store = 1;\n+\tchild.git_cmd = 1;\n+\tchild.odb_to_close = the_repository->objects;\n \tstrvec_pushl(&child.args, \"multi-pack-index\", \"expire\", NULL);\n \n \tif (opts->quiet)\n@@ -1542,7 +1545,8 @@ static int multi_pack_index_repack(struct maintenance_run_opts *opts)\n {\n \tstruct child_process child = CHILD_PROCESS_INIT;\n \n-\tchild.git_cmd = child.close_object_store = 1;\n+\tchild.git_cmd = 1;\n+\tchild.odb_to_close = the_repository->objects;\n \tstrvec_pushl(&child.args, \"multi-pack-index\", \"repack\", NULL);\n \n \tif (opts->quiet)\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex 6ad420ce6f..7e67fdce97 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -454,7 +454,7 @@ static int run_fetch(const char *repo, const char **refspecs)\n \t} else if (*refspecs)\n \t\tBUG(\"refspecs without repo?\");\n \tcmd.git_cmd = 1;\n-\tcmd.close_object_store = 1;\n+\tcmd.odb_to_close = the_repository->objects;\n \treturn run_command(&cmd);\n }\n \ndiff --git a/run-command.c b/run-command.c\nindex b27064ef57..ed5e8be976 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -742,8 +742,8 @@ int start_command(struct child_process *cmd)\n \n \tfflush(NULL);\n \n-\tif (cmd->close_object_store)\n-\t\todb_close(the_repository->objects);\n+\tif (cmd->odb_to_close)\n+\t\todb_close(cmd->odb_to_close);\n \n #ifndef GIT_WINDOWS_NATIVE\n {\n@@ -1955,7 +1955,7 @@ int prepare_auto_maintenance(int quiet, struct child_process *maint)\n \t\tauto_detach = git_env_bool(\"GIT_TEST_MAINT_AUTO_DETACH\", true);\n \n \tmaint->git_cmd = 1;\n-\tmaint->close_object_store = 1;\n+\tmaint->odb_to_close = the_repository->objects;\n \tstrvec_pushl(&maint->args, \"maintenance\", \"run\", \"--auto\", NULL);\n \tstrvec_push(&maint->args, quiet ? \"--quiet\" : \"--no-quiet\");\n \tstrvec_push(&maint->args, auto_detach ? \"--detach\" : \"--no-detach\");\ndiff --git a/run-command.h b/run-command.h\nindex e1ca965b5b..af4c9da279 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -136,7 +136,7 @@ struct child_process {\n \t * want to repack because that would delete `.pack` files (and on\n \t * Windows, you cannot delete files that are still in use).\n \t */\n-\tunsigned close_object_store:1;\n+\tstruct object_database *odb_to_close;\n \n \tunsigned stdout_to_stderr:1;\n \tunsigned clean_on_exit:1;\n-- \n2.53.0\n\n"},{"id":"538737","messageId":"abKO3155A9mw2pbO@pks.im","threadId":"65210","inReplyTo":"20260312085341.631318-1-bkkaracay@gmail.com","subject":"Re: [PATCH v2] run-command: wean start_command() off the_repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-03-12T10:01:03Z","receivedAt":"2026-03-12T10:01:09Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Mar 12, 2026 at 11:53:41AM +0300, Burak Kaan Karaçay wrote:\n> The start_command() relies on the_repository due to the\n> close_object_store flag in 'struct child_process'. When this flag is\n> set, start_command() closes the object store associated with\n> the_repository before spawning a child process.\n> \n> To eliminate this dependency, replace the 'close_object_store' with the\n> new 'odb_to_close' field. This allows callers to specify the object\n> store that needs to be closed.\n\nI really like this solution.\n\nThere's now only a single other function that still uses\n`the_repository` in `prepare_auto_maintenance()`. Do we maybe want to\nadd a second commit that converts this function and its caller\n`run_auto_maintenance()` to receive the repository as parameter so that\nwe can drop the `USE_THE_REPOSITORY_VARIABLE` declaration?\n\nThanks!\n\nPatrick\n"},{"id":"538753","messageId":"20260312144437.626392-1-bkkaracay@gmail.com","threadId":"65210","inReplyTo":"20260311151923.4178655-1-bkkaracay@gmail.com","subject":"[PATCH v3 0/2] run-command: stop using the_repository","fromName":"Burak Kaan Karaçay","fromEmail":"bkkaracay@gmail.com","sentAt":"2026-03-12T14:44:35Z","receivedAt":"2026-03-12T14:44:46Z","isPatch":true,"sender":{"key":"bkkaracay@gmail.com","avatar":"https://avatars.githubusercontent.com/u/29117336?v=4"},"body":"Hi,\n\nThis patch series aims to remove the_repository dependency in\n'run-command.c'.\n\nThe first patch removes the dependency in start_command() by replacing\nthe boolean 'close_object_store' flag with a pointer to the target\nobject store.\n\nThe second patch handles the prepare_auto_maintenance() and\nrun_auto_maintenance() functions by passing a 'struct repository *'\nparameter. With no global repository dependencies left, it drops the\nUSE_THE_REPOSITORY_VARIABLE macro from the file.\n\nChanges in v3:\n- Added the second patch at the suggestion of Patrick to fully clean up\n  the file.\n\nChanges in v2:\n- Dropped the wrapper approach and rewrote the patch around the approach\n  suggested by René.\n\nThanks for all guidance,\nBurak Kaan Karaçay\n\nBurak Kaan Karaçay (2):\n  run-command: wean start_command() off the_repository\n  run-command: wean auto_maintenance() functions off the_repository\n\n builtin/am.c           |  2 +-\n builtin/commit.c       |  2 +-\n builtin/fetch.c        |  2 +-\n builtin/gc.c           | 14 +++++++++-----\n builtin/merge.c        |  2 +-\n builtin/pull.c         |  2 +-\n builtin/rebase.c       |  4 +++-\n builtin/receive-pack.c |  2 +-\n run-command.c          | 20 ++++++++++----------\n run-command.h          |  9 ++++++---\n 10 files changed, 34 insertions(+), 25 deletions(-)\n\n-- \n2.53.0\n\n"},{"id":"538754","messageId":"20260312144437.626392-2-bkkaracay@gmail.com","threadId":"65210","inReplyTo":"20260312144437.626392-1-bkkaracay@gmail.com","subject":"[PATCH v3 1/2] run-command: wean start_command() off the_repository","fromName":"Burak Kaan Karaçay","fromEmail":"bkkaracay@gmail.com","sentAt":"2026-03-12T14:44:36Z","receivedAt":"2026-03-12T14:44:51Z","isPatch":true,"sender":{"key":"bkkaracay@gmail.com","avatar":"https://avatars.githubusercontent.com/u/29117336?v=4"},"body":"The start_command() relies on the_repository due to the\nclose_object_store flag in 'struct child_process'. When this flag is\nset, start_command() closes the object store associated with\nthe_repository before spawning a child process.\n\nTo eliminate this dependency, replace the 'close_object_store' with the\nnew 'struct object_database *odb_to_close' field. This allows callers to\nspecify the object store that needs to be closed.\n\nSuggested-by: René Scharfe <l.s.r@web.de>\nSigned-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com>\n---\n builtin/gc.c   | 14 +++++++++-----\n builtin/pull.c |  2 +-\n run-command.c  |  6 +++---\n run-command.h  |  2 +-\n 4 files changed, 14 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex fb329c2cff..5d8d358f7a 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -1030,7 +1030,7 @@ int cmd_gc(int argc,\n \t\tstruct child_process repack_cmd = CHILD_PROCESS_INIT;\n \n \t\trepack_cmd.git_cmd = 1;\n-\t\trepack_cmd.close_object_store = 1;\n+\t\trepack_cmd.odb_to_close = the_repository->objects;\n \t\tstrvec_pushv(&repack_cmd.args, repack_args.v);\n \t\tif (run_command(&repack_cmd))\n \t\t\tdie(FAILED_RUN, repack_args.v[0]);\n@@ -1199,7 +1199,8 @@ static int run_write_commit_graph(struct maintenance_run_opts *opts)\n {\n \tstruct child_process child = CHILD_PROCESS_INIT;\n \n-\tchild.git_cmd = child.close_object_store = 1;\n+\tchild.git_cmd = 1;\n+\tchild.odb_to_close = the_repository->objects;\n \tstrvec_pushl(&child.args, \"commit-graph\", \"write\",\n \t\t     \"--split\", \"--reachable\", NULL);\n \n@@ -1268,7 +1269,8 @@ static int maintenance_task_gc_background(struct maintenance_run_opts *opts,\n {\n \tstruct child_process child = CHILD_PROCESS_INIT;\n \n-\tchild.git_cmd = child.close_object_store = 1;\n+\tchild.git_cmd = 1;\n+\tchild.odb_to_close = the_repository->objects;\n \tstrvec_push(&child.args, \"gc\");\n \n \tif (opts->auto_flag)\n@@ -1484,7 +1486,8 @@ static int multi_pack_index_expire(struct maintenance_run_opts *opts)\n {\n \tstruct child_process child = CHILD_PROCESS_INIT;\n \n-\tchild.git_cmd = child.close_object_store = 1;\n+\tchild.git_cmd = 1;\n+\tchild.odb_to_close = the_repository->objects;\n \tstrvec_pushl(&child.args, \"multi-pack-index\", \"expire\", NULL);\n \n \tif (opts->quiet)\n@@ -1542,7 +1545,8 @@ static int multi_pack_index_repack(struct maintenance_run_opts *opts)\n {\n \tstruct child_process child = CHILD_PROCESS_INIT;\n \n-\tchild.git_cmd = child.close_object_store = 1;\n+\tchild.git_cmd = 1;\n+\tchild.odb_to_close = the_repository->objects;\n \tstrvec_pushl(&child.args, \"multi-pack-index\", \"repack\", NULL);\n \n \tif (opts->quiet)\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex 6ad420ce6f..7e67fdce97 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -454,7 +454,7 @@ static int run_fetch(const char *repo, const char **refspecs)\n \t} else if (*refspecs)\n \t\tBUG(\"refspecs without repo?\");\n \tcmd.git_cmd = 1;\n-\tcmd.close_object_store = 1;\n+\tcmd.odb_to_close = the_repository->objects;\n \treturn run_command(&cmd);\n }\n \ndiff --git a/run-command.c b/run-command.c\nindex b27064ef57..ed5e8be976 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -742,8 +742,8 @@ int start_command(struct child_process *cmd)\n \n \tfflush(NULL);\n \n-\tif (cmd->close_object_store)\n-\t\todb_close(the_repository->objects);\n+\tif (cmd->odb_to_close)\n+\t\todb_close(cmd->odb_to_close);\n \n #ifndef GIT_WINDOWS_NATIVE\n {\n@@ -1955,7 +1955,7 @@ int prepare_auto_maintenance(int quiet, struct child_process *maint)\n \t\tauto_detach = git_env_bool(\"GIT_TEST_MAINT_AUTO_DETACH\", true);\n \n \tmaint->git_cmd = 1;\n-\tmaint->close_object_store = 1;\n+\tmaint->odb_to_close = the_repository->objects;\n \tstrvec_pushl(&maint->args, \"maintenance\", \"run\", \"--auto\", NULL);\n \tstrvec_push(&maint->args, quiet ? \"--quiet\" : \"--no-quiet\");\n \tstrvec_push(&maint->args, auto_detach ? \"--detach\" : \"--no-detach\");\ndiff --git a/run-command.h b/run-command.h\nindex e1ca965b5b..af4c9da279 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -136,7 +136,7 @@ struct child_process {\n \t * want to repack because that would delete `.pack` files (and on\n \t * Windows, you cannot delete files that are still in use).\n \t */\n-\tunsigned close_object_store:1;\n+\tstruct object_database *odb_to_close;\n \n \tunsigned stdout_to_stderr:1;\n \tunsigned clean_on_exit:1;\n-- \n2.53.0\n\n"},{"id":"538755","messageId":"20260312144437.626392-3-bkkaracay@gmail.com","threadId":"65210","inReplyTo":"20260312144437.626392-1-bkkaracay@gmail.com","subject":"[PATCH v3 2/2] run-command: wean auto_maintenance() functions off the_repository","fromName":"Burak Kaan Karaçay","fromEmail":"bkkaracay@gmail.com","sentAt":"2026-03-12T14:44:37Z","receivedAt":"2026-03-12T14:44:55Z","isPatch":true,"sender":{"key":"bkkaracay@gmail.com","avatar":"https://avatars.githubusercontent.com/u/29117336?v=4"},"body":"The prepare_auto_maintenance() relies on the_repository to read\nconfigurations. Since run_auto_maintenance() calls\nprepare_auto_maintenance(), it also implicitly depends the_repository.\n\nAdd 'struct repository *' as a parameter to both functions and update\nall callers to pass the_repository.\n\nWith no global repository dependencies left in this file, remove the\nUSE_THE_REPOSITORY_VARIABLE macro.\n\nSuggested-by: Patrick Steinhardt <ps@pks.im>\nSigned-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com>\n---\n builtin/am.c           |  2 +-\n builtin/commit.c       |  2 +-\n builtin/fetch.c        |  2 +-\n builtin/merge.c        |  2 +-\n builtin/rebase.c       |  4 +++-\n builtin/receive-pack.c |  2 +-\n run-command.c          | 16 ++++++++--------\n run-command.h          |  7 +++++--\n 8 files changed, 21 insertions(+), 16 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex e0c767e223..9d0b51c651 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1937,7 +1937,7 @@ static void am_run(struct am_state *state, int resume)\n \t */\n \tif (!state->rebasing) {\n \t\tam_destroy(state);\n-\t\trun_auto_maintenance(state->quiet);\n+\t\trun_auto_maintenance(the_repository, state->quiet);\n \t}\n }\n \ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 844bdcc728..7b23c1f883 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1958,7 +1958,7 @@ int cmd_commit(int argc,\n \tgit_test_write_commit_graph_or_die(the_repository->objects->sources);\n \n \trepo_rerere(the_repository, 0);\n-\trun_auto_maintenance(quiet);\n+\trun_auto_maintenance(the_repository, quiet);\n \trun_commit_hook(use_editor, repo_get_index_file(the_repository),\n \t\t\tNULL, \"post-commit\", NULL);\n \tif (amend && !no_post_rewrite) {\ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex 8a36cf67b5..4795b2a13c 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -2873,7 +2873,7 @@ int cmd_fetch(int argc,\n \t\t\tif (opt_val != 0)\n \t\t\t\tgit_config_push_parameter(\"maintenance.incremental-repack.auto=-1\");\n \t\t}\n-\t\trun_auto_maintenance(verbosity < 0);\n+\t\trun_auto_maintenance(the_repository, verbosity < 0);\n \t}\n \n  cleanup:\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 4e456a381c..2cbce56f8d 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -506,7 +506,7 @@ static void finish(struct commit *head_commit,\n \t\t\t * We ignore errors in 'gc --auto', since the\n \t\t\t * user should see them.\n \t\t\t */\n-\t\t\trun_auto_maintenance(verbosity < 0);\n+\t\t\trun_auto_maintenance(the_repository, verbosity < 0);\n \t\t}\n \t}\n \tif (new_head && show_diffstat) {\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex c487e10907..8c1316db38 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -562,7 +562,9 @@ static int finish_rebase(struct rebase_options *opts)\n \t * We ignore errors in 'git maintenance run --auto', since the\n \t * user should see them.\n \t */\n-\trun_auto_maintenance(!(opts->flags & (REBASE_NO_QUIET|REBASE_VERBOSE)));\n+\trun_auto_maintenance(the_repository,\n+\t\t\t!(opts->flags & (REBASE_NO_QUIET|REBASE_VERBOSE)));\n+\n \tif (opts->type == REBASE_MERGE) {\n \t\tstruct replay_opts replay = REPLAY_OPTS_INIT;\n \ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex d6225df890..e34edff406 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2727,7 +2727,7 @@ int cmd_receive_pack(int argc,\n \t\tif (auto_gc) {\n \t\t\tstruct child_process proc = CHILD_PROCESS_INIT;\n \n-\t\t\tif (prepare_auto_maintenance(1, &proc)) {\n+\t\t\tif (prepare_auto_maintenance(the_repository, 1, &proc)) {\n \t\t\t\tproc.no_stdin = 1;\n \t\t\t\tproc.stdout_to_stderr = 1;\n \t\t\t\tproc.err = use_sideband ? -1 : 0;\ndiff --git a/run-command.c b/run-command.c\nindex ed5e8be976..38f4c699f8 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -1,4 +1,3 @@\n-#define USE_THE_REPOSITORY_VARIABLE\n #define DISABLE_SIGN_COMPARE_WARNINGS\n \n #include \"git-compat-util.h\"\n@@ -1937,11 +1936,12 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)\n \t\ttrace2_region_leave(tr2_category, tr2_label, NULL);\n }\n \n-int prepare_auto_maintenance(int quiet, struct child_process *maint)\n+int prepare_auto_maintenance(struct repository *r, int quiet,\n+\t\t\t     struct child_process *maint)\n {\n \tint enabled, auto_detach;\n \n-\tif (!repo_config_get_bool(the_repository, \"maintenance.auto\", &enabled) &&\n+\tif (!repo_config_get_bool(r, \"maintenance.auto\", &enabled) &&\n \t    !enabled)\n \t\treturn 0;\n \n@@ -1950,12 +1950,12 @@ int prepare_auto_maintenance(int quiet, struct child_process *maint)\n \t * honoring `gc.autoDetach`. This is somewhat weird, but required to\n \t * retain behaviour from when we used to run git-gc(1) here.\n \t */\n-\tif (repo_config_get_bool(the_repository, \"maintenance.autodetach\", &auto_detach) &&\n-\t    repo_config_get_bool(the_repository, \"gc.autodetach\", &auto_detach))\n+\tif (repo_config_get_bool(r, \"maintenance.autodetach\", &auto_detach) &&\n+\t    repo_config_get_bool(r, \"gc.autodetach\", &auto_detach))\n \t\tauto_detach = git_env_bool(\"GIT_TEST_MAINT_AUTO_DETACH\", true);\n \n \tmaint->git_cmd = 1;\n-\tmaint->odb_to_close = the_repository->objects;\n+\tmaint->odb_to_close = r->objects;\n \tstrvec_pushl(&maint->args, \"maintenance\", \"run\", \"--auto\", NULL);\n \tstrvec_push(&maint->args, quiet ? \"--quiet\" : \"--no-quiet\");\n \tstrvec_push(&maint->args, auto_detach ? \"--detach\" : \"--no-detach\");\n@@ -1963,10 +1963,10 @@ int prepare_auto_maintenance(int quiet, struct child_process *maint)\n \treturn 1;\n }\n \n-int run_auto_maintenance(int quiet)\n+int run_auto_maintenance(struct repository *r, int quiet)\n {\n \tstruct child_process maint = CHILD_PROCESS_INIT;\n-\tif (!prepare_auto_maintenance(quiet, &maint))\n+\tif (!prepare_auto_maintenance(r, quiet, &maint))\n \t\treturn 0;\n \treturn run_command(&maint);\n }\ndiff --git a/run-command.h b/run-command.h\nindex af4c9da279..ad25740fe6 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -5,6 +5,8 @@\n \n #include \"strvec.h\"\n \n+struct repository;\n+\n /**\n  * The run-command API offers a versatile tool to run sub-processes with\n  * redirected input and output as well as with a modified environment\n@@ -227,12 +229,13 @@ int run_command(struct child_process *);\n  * process has been prepared and is ready to run, or 0 in case auto-maintenance\n  * should be skipped.\n  */\n-int prepare_auto_maintenance(int quiet, struct child_process *maint);\n+int prepare_auto_maintenance(struct repository *r, int quiet,\n+\t\t\t     struct child_process *maint);\n \n /*\n  * Trigger an auto-gc\n  */\n-int run_auto_maintenance(int quiet);\n+int run_auto_maintenance(struct repository *r, int quiet);\n \n /**\n  * Execute the given command, sending \"in\" to its stdin, and capturing its\n-- \n2.53.0\n\n"},{"id":"538756","messageId":"xmqqa4wdhxqn.fsf@gitster.g","threadId":"65210","inReplyTo":"20260312144437.626392-1-bkkaracay@gmail.com","subject":"Re: [PATCH v3 0/2] run-command: stop using the_repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-12T15:29:52Z","receivedAt":"2026-03-12T15:29:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Burak Kaan Karaçay <bkkaracay@gmail.com> writes:\n\n> This patch series aims to remove the_repository dependency in\n> 'run-command.c'.\n>\n> The first patch removes the dependency in start_command() by replacing\n> the boolean 'close_object_store' flag with a pointer to the target\n> object store.\n>\n> The second patch handles the prepare_auto_maintenance() and\n> run_auto_maintenance() functions by passing a 'struct repository *'\n> parameter. With no global repository dependencies left, it drops the\n> USE_THE_REPOSITORY_VARIABLE macro from the file.\n>\n> Changes in v3:\n> - Added the second patch at the suggestion of Patrick to fully clean up\n>   the file.\n\n[1/2] is now exactly as expected from the previous discussion.  The\nonly miniscule thing I found in [2/2] was a new blank line\nintroduced here, which seemed unnecessary and not in line with the\nexisting style in that function.\n\nOtherwise, looking very good.  Will queue.  Thanks.\n\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex c487e10907..8c1316db38 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -562,7 +562,9 @@ static int finish_rebase(struct rebase_options *opts)\n \t * We ignore errors in 'git maintenance run --auto', since the\n \t * user should see them.\n \t */\n-\trun_auto_maintenance(!(opts->flags & (REBASE_NO_QUIET|REBASE_VERBOSE)));\n+\trun_auto_maintenance(the_repository,\n+\t\t\t!(opts->flags & (REBASE_NO_QUIET|REBASE_VERBOSE)));\n+\n \tif (opts->type == REBASE_MERGE) {\n \t\tstruct replay_opts replay = REPLAY_OPTS_INIT;\n \n"},{"id":"538848","messageId":"abOtVYg1S_7aNNru@pks.im","threadId":"65210","inReplyTo":"xmqqa4wdhxqn.fsf@gitster.g","subject":"Re: [PATCH v3 0/2] run-command: stop using the_repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-03-13T06:23:17Z","receivedAt":"2026-03-13T06:23:24Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Mar 12, 2026 at 08:29:52AM -0700, Junio C Hamano wrote:\n> Burak Kaan Karaçay <bkkaracay@gmail.com> writes:\n> \n> > This patch series aims to remove the_repository dependency in\n> > 'run-command.c'.\n> >\n> > The first patch removes the dependency in start_command() by replacing\n> > the boolean 'close_object_store' flag with a pointer to the target\n> > object store.\n> >\n> > The second patch handles the prepare_auto_maintenance() and\n> > run_auto_maintenance() functions by passing a 'struct repository *'\n> > parameter. With no global repository dependencies left, it drops the\n> > USE_THE_REPOSITORY_VARIABLE macro from the file.\n> >\n> > Changes in v3:\n> > - Added the second patch at the suggestion of Patrick to fully clean up\n> >   the file.\n> \n> [1/2] is now exactly as expected from the previous discussion.  The\n> only miniscule thing I found in [2/2] was a new blank line\n> introduced here, which seemed unnecessary and not in line with the\n> existing style in that function.\n> \n> Otherwise, looking very good.  Will queue.  Thanks.\n\nAgreed, this looks good to me. Thanks!\n\nPatrick\n"}]}