{"thread":{"id":"65515","subject":"[PATCH 00/18] setup: drop uses of `the_repository`","startedAt":"2026-04-20T08:22:45Z","lastAt":"2026-05-20T03:31:58Z","messageCount":73,"participants":["Patrick Steinhardt","Elijah Newren","Junio C Hamano","Tian Yuchen","Karthik Nayak"],"isPatch":true,"patchVersion":1,"patchTotal":18},"messages":[{"id":"541928","messageId":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":null,"subject":"[PATCH 00/18] setup: drop uses of `the_repository`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:30Z","receivedAt":"2026-04-20T08:22:45Z","isPatch":true,"body":"Hi,\n\nI've had enough of \"setup.c\" and its complexities, so I finally decided\nto take the bullet and start refactoring this subsystem. This here is\nthe first out of the following three steps:\n\n  1. Drop all uses of `the_repository`. This doesn't yet allow us to get\n     rid of `USE_THE_REPOSITORY_VARIABLE`.\n\n  2. Convert a couple of global variables and drop\n     `is_bare_repository_cfg`, which then allows us to drop\n     `USE_THE_REPOSITORY_VARIABLE`.\n\n  3. Refactor the subsystem a bit so that we stop intermixing repository\n     discovery and repository initialization. This is my original\n     motivation as I want to get rid of `odb_prepare_alternates()`, but\n     due to the way we initialize the repository it has proven to be\n     extremely tedious.\n\nMost of the patches in this series here are rather mechanical. There's\nonly a handful of patches that warrant more attention:\n\n  -  2/18: setup: stop using `the_repository` in `is_inside_worktree()`\n  -  3/18: setup: stop using `the_repository` in `is_inside_git_dir()`\n  -  9/18: setup: stop using `the_repository` in `setup_work_tree()`\n  - 10/18: setup: stop using `the_repository` in `set_git_work_tree()`\n\nThose patches don't only mechanical move stuff around, but also change\nsome logic to make it work.\n\nThe series is based on 5361983c07 (The 22nd batch, 2026-03-27). There is\na single merge commit with \"seen\", but it's trivial to resolve.\n\nChanges in v2:\n  - Remove static `initialized` variable in `setup_work_tree()`.\n  - Use enum values to initialize fields.\n  - Fix up a comment.\n  - Link to v1: https://lore.kernel.org/all/20260330-pks-setup-wo-the-repository-v1-0-0d2e822837aa@pks.im/\n\nThanks!\n\nPatrick\n\n---\nPatrick Steinhardt (18):\n      setup: replace use of `the_repository` in static functions\n      setup: stop using `the_repository` in `is_inside_worktree()`\n      setup: stop using `the_repository` in `is_inside_git_dir()`\n      setup: stop using `the_repository` in `prefix_path()`\n      setup: stop using `the_repository` in `path_inside_repo()`\n      setup: stop using `the_repository` in `verify_filename()`\n      setup: stop using `the_repository` in `verify_non_filename()`\n      setup: stop using `the_repository` in `enter_repo()`\n      setup: stop using `the_repository` in `setup_work_tree()`\n      setup: stop using `the_repository` in `set_git_work_tree()`\n      setup: stop using `the_repository` in `setup_git_env()`\n      setup: stop using `the_repository` in `setup_git_directory_gently()`\n      setup: stop using `the_repository` in `setup_git_directory()`\n      setup: stop using `the_repository` in `upgrade_repository_format()`\n      setup: stop using `the_repository` in `check_repository_format()`\n      setup: stop using `the_repository` in `initialize_repository_version()`\n      setup: stop using `the_repository` in `create_reference_database()`\n      setup: stop using `the_repository` in `init_db()`\n\n archive.c                                    |   2 +-\n blame.c                                      |   2 +-\n builtin/blame.c                              |   2 +-\n builtin/check-attr.c                         |   4 +-\n builtin/check-ref-format.c                   |   5 +-\n builtin/checkout-index.c                     |   4 +-\n builtin/checkout.c                           |   2 +-\n builtin/clone.c                              |  12 +-\n builtin/describe.c                           |   2 +-\n builtin/diff-index.c                         |   2 +-\n builtin/diff.c                               |  10 +-\n builtin/difftool.c                           |   2 +-\n builtin/grep.c                               |   8 +-\n builtin/hash-object.c                        |   4 +-\n builtin/help.c                               |   2 +-\n builtin/init-db.c                            |   8 +-\n builtin/ls-files.c                           |   4 +-\n builtin/merge-file.c                         |   2 +-\n builtin/mv.c                                 |   5 +-\n builtin/read-tree.c                          |   2 +-\n builtin/receive-pack.c                       |   2 +-\n builtin/reset.c                              |   6 +-\n builtin/rev-parse.c                          |  14 +-\n builtin/rm.c                                 |   2 +-\n builtin/sparse-checkout.c                    |  19 +-\n builtin/stripspace.c                         |   2 +-\n builtin/submodule--helper.c                  |   2 +-\n builtin/update-index.c                       |  16 +-\n builtin/upload-archive.c                     |   2 +-\n builtin/upload-pack.c                        |   2 +-\n daemon.c                                     |   4 +-\n environment.h                                |   2 -\n git.c                                        |  10 +-\n http-backend.c                               |   2 +-\n http-fetch.c                                 |   2 +-\n http-push.c                                  |   2 +-\n imap-send.c                                  |   2 +-\n line-log.c                                   |   2 +-\n list-objects-filter-options.c                |   2 +-\n object-name.c                                |   4 +-\n pathspec.c                                   |   2 +-\n refs.c                                       |   2 +-\n remote-curl.c                                |   4 +-\n repository.h                                 |   4 +-\n revision.c                                   |   6 +-\n scalar.c                                     |   4 +-\n setup.c                                      | 442 ++++++++++++++-------------\n setup.h                                      |  43 ++-\n submodule.c                                  |   2 +-\n t/helper/test-advise.c                       |   2 +-\n t/helper/test-bitmap.c                       |   2 +-\n t/helper/test-bloom.c                        |   2 +-\n t/helper/test-cache-tree.c                   |   2 +-\n t/helper/test-config.c                       |   2 +-\n t/helper/test-dump-cache-tree.c              |   2 +-\n t/helper/test-dump-fsmonitor.c               |   2 +-\n t/helper/test-dump-split-index.c             |   2 +-\n t/helper/test-dump-untracked-cache.c         |   2 +-\n t/helper/test-find-pack.c                    |   2 +-\n t/helper/test-fsmonitor-client.c             |   2 +-\n t/helper/test-lazy-init-name-hash.c          |   2 +-\n t/helper/test-match-trees.c                  |   2 +-\n t/helper/test-pack-deltas.c                  |   2 +-\n t/helper/test-pack-mtimes.c                  |   2 +-\n t/helper/test-partial-clone.c                |   4 +-\n t/helper/test-path-utils.c                   |   4 +-\n t/helper/test-path-walk.c                    |   2 +-\n t/helper/test-reach.c                        |   2 +-\n t/helper/test-read-cache.c                   |   2 +-\n t/helper/test-read-graph.c                   |   2 +-\n t/helper/test-read-midx.c                    |   2 +-\n t/helper/test-ref-store.c                    |   2 +-\n t/helper/test-revision-walking.c             |   2 +-\n t/helper/test-scrap-cache-tree.c             |   2 +-\n t/helper/test-serve-v2.c                     |   2 +-\n t/helper/test-submodule-config.c             |   2 +-\n t/helper/test-submodule-nested-repo-config.c |   2 +-\n t/helper/test-submodule.c                    |  10 +-\n t/helper/test-subprocess.c                   |   6 +-\n t/helper/test-userdiff.c                     |   2 +-\n t/helper/test-write-cache.c                  |   2 +-\n worktree.c                                   |   2 +-\n wt-status.c                                  |   2 +-\n 83 files changed, 393 insertions(+), 383 deletions(-)\n\n\n---\nbase-commit: 5361983c075154725be47b65cca9a2421789e410\nchange-id: 20260330-pks-setup-wo-the-repository-81e51bc55b91\n\n"},{"id":"541929","messageId":"20260420-pks-setup-wo-the-repository-v1-1-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 01/18] setup: replace use of `the_repository` in static functions","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:31Z","receivedAt":"2026-04-20T08:22:47Z","isPatch":true,"body":"Replace the use of `the_repository` in \"setup.c\" for all static\nfunctions. For now, we simply add `the_repository` to invocations of\nthese functions. This will be addressed in subsequent commits, where\nwe'll move up `the_repository` one more layer to callers of \"setup.c\".\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n setup.c | 188 ++++++++++++++++++++++++++++++++++------------------------------\n 1 file changed, 100 insertions(+), 88 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex 7ec4427368..ba2898473a 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -50,13 +50,13 @@ const char *tmp_original_cwd;\n  * /dir/repolink/file     (repolink points to /dir/repo) -> file\n  * /dir/repo              (exactly equal to work tree)   -> (empty string)\n  */\n-static int abspath_part_inside_repo(char *path)\n+static int abspath_part_inside_repo(struct repository *repo, char *path)\n {\n \tsize_t len;\n \tsize_t wtlen;\n \tchar *path0;\n \tint off;\n-\tconst char *work_tree = precompose_string_if_needed(repo_get_work_tree(the_repository));\n+\tconst char *work_tree = precompose_string_if_needed(repo_get_work_tree(repo));\n \tstruct strbuf realpath = STRBUF_INIT;\n \n \tif (!work_tree)\n@@ -132,7 +132,7 @@ char *prefix_path_gently(const char *prefix, int len,\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n-\t\tif (abspath_part_inside_repo(sanitized)) {\n+\t\tif (abspath_part_inside_repo(the_repository, sanitized)) {\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n@@ -509,7 +509,7 @@ void setup_work_tree(void)\n \tinitialized = 1;\n }\n \n-static void setup_original_cwd(void)\n+static void setup_original_cwd(struct repository *repo)\n {\n \tstruct strbuf tmp = STRBUF_INIT;\n \tconst char *worktree = NULL;\n@@ -535,9 +535,9 @@ static void setup_original_cwd(void)\n \n \t/* Normalize the directory */\n \tif (!strbuf_realpath(&tmp, tmp_original_cwd, 0)) {\n-\t\ttrace2_data_string(\"setup\", the_repository,\n+\t\ttrace2_data_string(\"setup\", repo,\n \t\t\t\t   \"realpath-path\", tmp_original_cwd);\n-\t\ttrace2_data_string(\"setup\", the_repository,\n+\t\ttrace2_data_string(\"setup\", repo,\n \t\t\t\t   \"realpath-failure\", strerror(errno));\n \t\tfree((char*)tmp_original_cwd);\n \t\ttmp_original_cwd = NULL;\n@@ -552,7 +552,7 @@ static void setup_original_cwd(void)\n \t * Get our worktree; we only protect the current working directory\n \t * if it's in the worktree.\n \t */\n-\tworktree = repo_get_work_tree(the_repository);\n+\tworktree = repo_get_work_tree(repo);\n \tif (!worktree)\n \t\tgoto no_prevention_needed;\n \n@@ -747,7 +747,10 @@ static int check_repo_format(const char *var, const char *value,\n \treturn read_worktree_config(var, value, ctx, vdata);\n }\n \n-static int check_repository_format_gently(const char *gitdir, struct repository_format *candidate, int *nongit_ok)\n+static int check_repository_format_gently(struct repository *repo,\n+\t\t\t\t\t  const char *gitdir,\n+\t\t\t\t\t  struct repository_format *candidate,\n+\t\t\t\t\t  int *nongit_ok)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n \tstruct strbuf err = STRBUF_INIT;\n@@ -776,7 +779,7 @@ static int check_repository_format_gently(const char *gitdir, struct repository_\n \t\tdie(\"%s\", err.buf);\n \t}\n \n-\tthe_repository->repository_format_precious_objects = candidate->precious_objects;\n+\trepo->repository_format_precious_objects = candidate->precious_objects;\n \n \tstring_list_clear(&candidate->unknown_extensions, 0);\n \tstring_list_clear(&candidate->v1_only_extensions, 0);\n@@ -1034,7 +1037,8 @@ const char *read_gitfile_gently(const char *path, int *return_error_code)\n \treturn error_code ? NULL : path;\n }\n \n-static void setup_git_env_internal(const char *git_dir,\n+static void setup_git_env_internal(struct repository *repo,\n+\t\t\t\t   const char *git_dir,\n \t\t\t\t   bool skip_initializing_odb)\n {\n \tchar *git_replace_ref_base;\n@@ -1052,7 +1056,7 @@ static void setup_git_env_internal(const char *git_dir,\n \t\targs.disable_ref_updates = true;\n \targs.skip_initializing_odb = skip_initializing_odb;\n \n-\trepo_set_gitdir(the_repository, git_dir, &args);\n+\trepo_set_gitdir(repo, git_dir, &args);\n \tstrvec_clear(&to_free);\n \n \tif (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))\n@@ -1064,7 +1068,7 @@ static void setup_git_env_internal(const char *git_dir,\n \n \tshallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);\n \tif (shallow_file)\n-\t\tset_alternate_shallow_file(the_repository, shallow_file, 0);\n+\t\tset_alternate_shallow_file(repo, shallow_file, 0);\n \n \tif (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0))\n \t\tfetch_if_missing = 0;\n@@ -1072,30 +1076,31 @@ static void setup_git_env_internal(const char *git_dir,\n \n void setup_git_env(const char *git_dir)\n {\n-\tsetup_git_env_internal(git_dir, false);\n+\tsetup_git_env_internal(the_repository, git_dir, false);\n }\n \n-static void set_git_dir_1(const char *path, bool skip_initializing_odb)\n+static void set_git_dir_1(struct repository *repo, const char *path, bool skip_initializing_odb)\n {\n \txsetenv(GIT_DIR_ENVIRONMENT, path, 1);\n-\tsetup_git_env_internal(path, skip_initializing_odb);\n+\tsetup_git_env_internal(repo, path, skip_initializing_odb);\n }\n \n static void update_relative_gitdir(const char *name UNUSED,\n \t\t\t\t   const char *old_cwd,\n \t\t\t\t   const char *new_cwd,\n-\t\t\t\t   void *data UNUSED)\n+\t\t\t\t   void *data)\n {\n+\tstruct repository *repo = data;\n \tchar *path = reparent_relative_path(old_cwd, new_cwd,\n-\t\t\t\t\t    repo_get_git_dir(the_repository));\n+\t\t\t\t\t    repo_get_git_dir(repo));\n \ttrace_printf_key(&trace_setup_key,\n \t\t\t \"setup: move $GIT_DIR to '%s'\",\n \t\t\t path);\n-\tset_git_dir_1(path, true);\n+\tset_git_dir_1(repo, path, true);\n \tfree(path);\n }\n \n-static void set_git_dir(const char *path, int make_realpath)\n+static void set_git_dir(struct repository *repo, const char *path, int make_realpath)\n {\n \tstruct strbuf realpath = STRBUF_INIT;\n \n@@ -1104,14 +1109,15 @@ static void set_git_dir(const char *path, int make_realpath)\n \t\tpath = realpath.buf;\n \t}\n \n-\tset_git_dir_1(path, false);\n+\tset_git_dir_1(repo, path, false);\n \tif (!is_absolute_path(path))\n-\t\tchdir_notify_register(NULL, update_relative_gitdir, NULL);\n+\t\tchdir_notify_register(NULL, update_relative_gitdir, repo);\n \n \tstrbuf_release(&realpath);\n }\n \n-static const char *setup_explicit_git_dir(const char *gitdirenv,\n+static const char *setup_explicit_git_dir(struct repository *repo,\n+\t\t\t\t\t  const char *gitdirenv,\n \t\t\t\t\t  struct strbuf *cwd,\n \t\t\t\t\t  struct repository_format *repo_fmt,\n \t\t\t\t\t  int *nongit_ok)\n@@ -1139,7 +1145,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t\tdie(_(\"not a git repository: '%s'\"), gitdirenv);\n \t}\n \n-\tif (check_repository_format_gently(gitdirenv, repo_fmt, nongit_ok)) {\n+\tif (check_repository_format_gently(repo, gitdirenv, repo_fmt, nongit_ok)) {\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n@@ -1155,7 +1161,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t\t}\n \n \t\t/* #18, #26 */\n-\t\tset_git_dir(gitdirenv, 0);\n+\t\tset_git_dir(repo, gitdirenv, 0);\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n@@ -1177,7 +1183,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t}\n \telse if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) {\n \t\t/* #16d */\n-\t\tset_git_dir(gitdirenv, 0);\n+\t\tset_git_dir(repo, gitdirenv, 0);\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n@@ -1185,18 +1191,18 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t\tset_git_work_tree(\".\");\n \n \t/* set_git_work_tree() must have been called by now */\n-\tworktree = repo_get_work_tree(the_repository);\n+\tworktree = repo_get_work_tree(repo);\n \n \t/* both repo_get_work_tree() and cwd are already normalized */\n \tif (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */\n-\t\tset_git_dir(gitdirenv, 0);\n+\t\tset_git_dir(repo, gitdirenv, 0);\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n \n \toffset = dir_inside_of(cwd->buf, worktree);\n \tif (offset >= 0) {\t/* cwd inside worktree? */\n-\t\tset_git_dir(gitdirenv, 1);\n+\t\tset_git_dir(repo, gitdirenv, 1);\n \t\tif (chdir(worktree))\n \t\t\tdie_errno(_(\"cannot chdir to '%s'\"), worktree);\n \t\tstrbuf_addch(cwd, '/');\n@@ -1205,17 +1211,18 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t}\n \n \t/* cwd outside worktree */\n-\tset_git_dir(gitdirenv, 0);\n+\tset_git_dir(repo, gitdirenv, 0);\n \tfree(gitfile);\n \treturn NULL;\n }\n \n-static const char *setup_discovered_git_dir(const char *gitdir,\n+static const char *setup_discovered_git_dir(struct repository *repo,\n+\t\t\t\t\t    const char *gitdir,\n \t\t\t\t\t    struct strbuf *cwd, int offset,\n \t\t\t\t\t    struct repository_format *repo_fmt,\n \t\t\t\t\t    int *nongit_ok)\n {\n-\tif (check_repository_format_gently(gitdir, repo_fmt, nongit_ok))\n+\tif (check_repository_format_gently(repo, gitdir, repo_fmt, nongit_ok))\n \t\treturn NULL;\n \n \t/* --work-tree is set without --git-dir; use discovered one */\n@@ -1227,14 +1234,14 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n \t\t\tgitdir = to_free = real_pathdup(gitdir, 1);\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n-\t\tret = setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);\n+\t\tret = setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n \t\tfree(to_free);\n \t\treturn ret;\n \t}\n \n \t/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */\n \tif (is_bare_repository_cfg > 0) {\n-\t\tset_git_dir(gitdir, (offset != cwd->len));\n+\t\tset_git_dir(repo, gitdir, (offset != cwd->len));\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n \t\treturn NULL;\n@@ -1243,7 +1250,7 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n \t/* #0, #1, #5, #8, #9, #12, #13 */\n \tset_git_work_tree(\".\");\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n-\t\tset_git_dir(gitdir, 0);\n+\t\tset_git_dir(repo, gitdir, 0);\n \tinside_git_dir = 0;\n \tinside_work_tree = 1;\n \tif (offset >= cwd->len)\n@@ -1258,13 +1265,14 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n }\n \n /* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */\n-static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n+static const char *setup_bare_git_dir(struct repository *repo,\n+\t\t\t\t      struct strbuf *cwd, int offset,\n \t\t\t\t      struct repository_format *repo_fmt,\n \t\t\t\t      int *nongit_ok)\n {\n \tint root_len;\n \n-\tif (check_repository_format_gently(\".\", repo_fmt, nongit_ok))\n+\tif (check_repository_format_gently(repo, \".\", repo_fmt, nongit_ok))\n \t\treturn NULL;\n \n \tsetenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, \"0\", 1);\n@@ -1276,7 +1284,7 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n \t\tgitdir = offset == cwd->len ? \".\" : xmemdupz(cwd->buf, offset);\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n-\t\treturn setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);\n+\t\treturn setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n \t}\n \n \tinside_git_dir = 1;\n@@ -1286,10 +1294,10 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n \t\troot_len = offset_1st_component(cwd->buf);\n \t\tstrbuf_setlen(cwd, offset > root_len ? offset : root_len);\n-\t\tset_git_dir(cwd->buf, 0);\n+\t\tset_git_dir(repo, cwd->buf, 0);\n \t}\n \telse\n-\t\tset_git_dir(\".\", 0);\n+\t\tset_git_dir(repo, \".\", 0);\n \treturn NULL;\n }\n \n@@ -1827,7 +1835,7 @@ const char *enter_repo(const char *path, unsigned flags)\n \t}\n \n \tif (is_git_directory(\".\")) {\n-\t\tset_git_dir(\".\", 0);\n+\t\tset_git_dir(the_repository, \".\", 0);\n \t\tcheck_repository_format(NULL);\n \t\treturn path;\n \t}\n@@ -1891,18 +1899,18 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \n \tswitch (setup_git_directory_gently_1(&dir, &gitdir, &report, 1)) {\n \tcase GIT_DIR_EXPLICIT:\n-\t\tprefix = setup_explicit_git_dir(gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_explicit_git_dir(the_repository, gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_DISCOVERED:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_discovered_git_dir(gitdir.buf, &cwd, dir.len,\n+\t\tprefix = setup_discovered_git_dir(the_repository, gitdir.buf, &cwd, dir.len,\n \t\t\t\t\t\t  &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_BARE:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_bare_git_dir(&cwd, dir.len, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_bare_git_dir(the_repository, &cwd, dir.len, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_HIT_CEILING:\n \t\tif (!nongit_ok)\n@@ -2044,7 +2052,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\tfree(payload);\n \t}\n \n-\tsetup_original_cwd();\n+\tsetup_original_cwd(the_repository);\n \n \tstrbuf_release(&dir);\n \tstrbuf_release(&gitdir);\n@@ -2110,7 +2118,7 @@ void check_repository_format(struct repository_format *fmt)\n \tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n \tif (!fmt)\n \t\tfmt = &repo_fmt;\n-\tcheck_repository_format_gently(repo_get_git_dir(the_repository), fmt, NULL);\n+\tcheck_repository_format_gently(the_repository, repo_get_git_dir(the_repository), fmt, NULL);\n \tstartup_info->have_repository = 1;\n \trepo_set_hash_algo(the_repository, fmt->hash_algo);\n \trepo_set_compat_hash_algo(the_repository, fmt->compat_hash_algo);\n@@ -2239,7 +2247,9 @@ const char *get_template_dir(const char *option_template)\n \n #define GIT_DEFAULT_HASH_ENVIRONMENT \"GIT_DEFAULT_HASH\"\n \n-static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n+static void copy_templates_1(struct repository *repo,\n+\t\t\t     struct strbuf *path,\n+\t\t\t     struct strbuf *template_path,\n \t\t\t     DIR *dir)\n {\n \tsize_t path_baselen = path->len;\n@@ -2253,7 +2263,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n \t * with the way the namespace under .git/ is organized, should\n \t * be really carefully chosen.\n \t */\n-\tsafe_create_dir(the_repository, path->buf, 1);\n+\tsafe_create_dir(repo, path->buf, 1);\n \twhile ((de = readdir(dir)) != NULL) {\n \t\tstruct stat st_git, st_template;\n \t\tint exists = 0;\n@@ -2281,7 +2291,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n \t\t\t\tdie_errno(_(\"cannot opendir '%s'\"), template_path->buf);\n \t\t\tstrbuf_addch(path, '/');\n \t\t\tstrbuf_addch(template_path, '/');\n-\t\t\tcopy_templates_1(path, template_path, subdir);\n+\t\t\tcopy_templates_1(repo, path, template_path, subdir);\n \t\t\tclosedir(subdir);\n \t\t}\n \t\telse if (exists)\n@@ -2306,7 +2316,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n \t}\n }\n \n-static void copy_templates(const char *option_template)\n+static void copy_templates(struct repository *repo, const char *option_template)\n {\n \tconst char *template_dir = get_template_dir(option_template);\n \tstruct strbuf path = STRBUF_INIT;\n@@ -2347,9 +2357,9 @@ static void copy_templates(const char *option_template)\n \t\tgoto close_free_return;\n \t}\n \n-\tstrbuf_addstr(&path, repo_get_common_dir(the_repository));\n+\tstrbuf_addstr(&path, repo_get_common_dir(repo));\n \tstrbuf_complete(&path, '/');\n-\tcopy_templates_1(&path, &template_path, dir);\n+\tcopy_templates_1(repo, &path, &template_path, dir);\n close_free_return:\n \tclosedir(dir);\n free_return:\n@@ -2443,13 +2453,13 @@ void initialize_repository_version(int hash_algo,\n \tstrbuf_release(&repo_version);\n }\n \n-static int is_reinit(void)\n+static int is_reinit(struct repository *repo)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tchar junk[2];\n \tint ret;\n \n-\trepo_git_path_replace(the_repository, &buf, \"HEAD\");\n+\trepo_git_path_replace(repo, &buf, \"HEAD\");\n \tret = !access(buf.buf, R_OK) || readlink(buf.buf, junk, sizeof(junk) - 1) != -1;\n \tstrbuf_release(&buf);\n \treturn ret;\n@@ -2459,7 +2469,7 @@ void create_reference_database(const char *initial_branch, int quiet)\n {\n \tstruct strbuf err = STRBUF_INIT;\n \tchar *to_free = NULL;\n-\tint reinit = is_reinit();\n+\tint reinit = is_reinit(the_repository);\n \n \tif (ref_store_create_on_disk(get_main_ref_store(the_repository), 0, &err))\n \t\tdie(\"failed to set up refs db: %s\", err.buf);\n@@ -2493,7 +2503,8 @@ void create_reference_database(const char *initial_branch, int quiet)\n \tfree(to_free);\n }\n \n-static int create_default_files(const char *template_path,\n+static int create_default_files(struct repository *repo,\n+\t\t\t\tconst char *template_path,\n \t\t\t\tconst char *original_git_dir,\n \t\t\t\tconst struct repository_format *fmt,\n \t\t\t\tint init_shared_repository)\n@@ -2502,7 +2513,7 @@ static int create_default_files(const char *template_path,\n \tstruct strbuf path = STRBUF_INIT;\n \tint reinit;\n \tint filemode;\n-\tconst char *work_tree = repo_get_work_tree(the_repository);\n+\tconst char *work_tree = repo_get_work_tree(repo);\n \n \t/*\n \t * First copy the templates -- we might have the default\n@@ -2513,19 +2524,19 @@ static int create_default_files(const char *template_path,\n \t * values (since we've just potentially changed what's available on\n \t * disk).\n \t */\n-\tcopy_templates(template_path);\n-\trepo_config_clear(the_repository);\n-\trepo_settings_reset_shared_repository(the_repository);\n-\trepo_config(the_repository, git_default_config, NULL);\n+\tcopy_templates(repo, template_path);\n+\trepo_config_clear(repo);\n+\trepo_settings_reset_shared_repository(repo);\n+\trepo_config(repo, git_default_config, NULL);\n \n-\treinit = is_reinit();\n+\treinit = is_reinit(repo);\n \n \t/*\n \t * We must make sure command-line options continue to override any\n \t * values we might have just re-read from the config.\n \t */\n \tif (init_shared_repository != -1)\n-\t\trepo_settings_set_shared_repository(the_repository,\n+\t\trepo_settings_set_shared_repository(repo,\n \t\t\t\t\t\t    init_shared_repository);\n \n \tis_bare_repository_cfg = !work_tree;\n@@ -2534,14 +2545,14 @@ static int create_default_files(const char *template_path,\n \t * We would have created the above under user's umask -- under\n \t * shared-repository settings, we would need to fix them up.\n \t */\n-\tif (repo_settings_get_shared_repository(the_repository)) {\n-\t\tadjust_shared_perm(the_repository, repo_get_git_dir(the_repository));\n+\tif (repo_settings_get_shared_repository(repo)) {\n+\t\tadjust_shared_perm(repo, repo_get_git_dir(repo));\n \t}\n \n \tinitialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, reinit);\n \n \t/* Check filemode trustability */\n-\trepo_git_path_replace(the_repository, &path, \"config\");\n+\trepo_git_path_replace(repo, &path, \"config\");\n \tfilemode = TEST_FILEMODE;\n \tif (TEST_FILEMODE && !lstat(path.buf, &st1)) {\n \t\tstruct stat st2;\n@@ -2552,22 +2563,22 @@ static int create_default_files(const char *template_path,\n \t\tif (filemode && !reinit && (st1.st_mode & S_IXUSR))\n \t\t\tfilemode = 0;\n \t}\n-\trepo_config_set(the_repository, \"core.filemode\", filemode ? \"true\" : \"false\");\n+\trepo_config_set(repo, \"core.filemode\", filemode ? \"true\" : \"false\");\n \n \tif (is_bare_repository())\n-\t\trepo_config_set(the_repository, \"core.bare\", \"true\");\n+\t\trepo_config_set(repo, \"core.bare\", \"true\");\n \telse {\n-\t\trepo_config_set(the_repository, \"core.bare\", \"false\");\n+\t\trepo_config_set(repo, \"core.bare\", \"false\");\n \t\t/* allow template config file to override the default */\n-\t\tif (repo_settings_get_log_all_ref_updates(the_repository) == LOG_REFS_UNSET)\n-\t\t\trepo_config_set(the_repository, \"core.logallrefupdates\", \"true\");\n+\t\tif (repo_settings_get_log_all_ref_updates(repo) == LOG_REFS_UNSET)\n+\t\t\trepo_config_set(repo, \"core.logallrefupdates\", \"true\");\n \t\tif (needs_work_tree_config(original_git_dir, work_tree))\n-\t\t\trepo_config_set(the_repository, \"core.worktree\", work_tree);\n+\t\t\trepo_config_set(repo, \"core.worktree\", work_tree);\n \t}\n \n \tif (!reinit) {\n \t\t/* Check if symlink is supported in the work tree */\n-\t\trepo_git_path_replace(the_repository, &path, \"tXXXXXX\");\n+\t\trepo_git_path_replace(repo, &path, \"tXXXXXX\");\n \t\tif (!close(xmkstemp(path.buf)) &&\n \t\t    !unlink(path.buf) &&\n \t\t    !symlink(\"testing\", path.buf) &&\n@@ -2575,12 +2586,12 @@ static int create_default_files(const char *template_path,\n \t\t    S_ISLNK(st1.st_mode))\n \t\t\tunlink(path.buf); /* good */\n \t\telse\n-\t\t\trepo_config_set(the_repository, \"core.symlinks\", \"false\");\n+\t\t\trepo_config_set(repo, \"core.symlinks\", \"false\");\n \n \t\t/* Check if the filesystem is case-insensitive */\n-\t\trepo_git_path_replace(the_repository, &path, \"CoNfIg\");\n+\t\trepo_git_path_replace(repo, &path, \"CoNfIg\");\n \t\tif (!access(path.buf, F_OK))\n-\t\t\trepo_config_set(the_repository, \"core.ignorecase\", \"true\");\n+\t\t\trepo_config_set(repo, \"core.ignorecase\", \"true\");\n \t\tprobe_utf8_pathname_composition();\n \t}\n \n@@ -2588,23 +2599,23 @@ static int create_default_files(const char *template_path,\n \treturn reinit;\n }\n \n-static void create_object_directory(void)\n+static void create_object_directory(struct repository *repo)\n {\n \tstruct strbuf path = STRBUF_INIT;\n \tsize_t baselen;\n \n-\tstrbuf_addstr(&path, repo_get_object_directory(the_repository));\n+\tstrbuf_addstr(&path, repo_get_object_directory(repo));\n \tbaselen = path.len;\n \n-\tsafe_create_dir(the_repository, path.buf, 1);\n+\tsafe_create_dir(repo, path.buf, 1);\n \n \tstrbuf_setlen(&path, baselen);\n \tstrbuf_addstr(&path, \"/pack\");\n-\tsafe_create_dir(the_repository, path.buf, 1);\n+\tsafe_create_dir(repo, path.buf, 1);\n \n \tstrbuf_setlen(&path, baselen);\n \tstrbuf_addstr(&path, \"/info\");\n-\tsafe_create_dir(the_repository, path.buf, 1);\n+\tsafe_create_dir(repo, path.buf, 1);\n \n \tstrbuf_release(&path);\n }\n@@ -2682,7 +2693,8 @@ static int read_default_format_config(const char *key, const char *value,\n \treturn ret;\n }\n \n-static void repository_format_configure(struct repository_format *repo_fmt,\n+static void repository_format_configure(struct repository *repo,\n+\t\t\t\t\tstruct repository_format *repo_fmt,\n \t\t\t\t\tint hash, enum ref_storage_format ref_format)\n {\n \tstruct default_format_config cfg = {\n@@ -2719,7 +2731,7 @@ static void repository_format_configure(struct repository_format *repo_fmt,\n \t} else if (cfg.hash != GIT_HASH_UNKNOWN) {\n \t\trepo_fmt->hash_algo = cfg.hash;\n \t}\n-\trepo_set_hash_algo(the_repository, repo_fmt->hash_algo);\n+\trepo_set_hash_algo(repo, repo_fmt->hash_algo);\n \n \tenv = getenv(\"GIT_DEFAULT_REF_FORMAT\");\n \tif (repo_fmt->version >= 0 &&\n@@ -2758,7 +2770,7 @@ static void repository_format_configure(struct repository_format *repo_fmt,\n \t\tfree(backend);\n \t}\n \n-\trepo_set_ref_storage_format(the_repository, repo_fmt->ref_storage_format,\n+\trepo_set_ref_storage_format(repo, repo_fmt->ref_storage_format,\n \t\t\t\t    repo_fmt->ref_storage_payload);\n }\n \n@@ -2782,12 +2794,12 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\tif (!exist_ok && !stat(real_git_dir, &st))\n \t\t\tdie(_(\"%s already exists\"), real_git_dir);\n \n-\t\tset_git_dir(real_git_dir, 1);\n+\t\tset_git_dir(the_repository, real_git_dir, 1);\n \t\tgit_dir = repo_get_git_dir(the_repository);\n \t\tseparate_git_dir(git_dir, original_git_dir);\n \t}\n \telse {\n-\t\tset_git_dir(git_dir, 1);\n+\t\tset_git_dir(the_repository, git_dir, 1);\n \t\tgit_dir = repo_get_git_dir(the_repository);\n \t}\n \tstartup_info->have_repository = 1;\n@@ -2800,7 +2812,7 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t */\n \tcheck_repository_format(&repo_fmt);\n \n-\trepository_format_configure(&repo_fmt, hash, ref_storage_format);\n+\trepository_format_configure(the_repository, &repo_fmt, hash, ref_storage_format);\n \n \t/*\n \t * Ensure `core.hidedotfiles` is processed. This must happen after we\n@@ -2811,12 +2823,12 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \n \tsafe_create_dir(the_repository, git_dir, 0);\n \n-\treinit = create_default_files(template_dir, original_git_dir,\n+\treinit = create_default_files(the_repository, template_dir, original_git_dir,\n \t\t\t\t      &repo_fmt, init_shared_repository);\n \n \tif (!(flags & INIT_DB_SKIP_REFDB))\n \t\tcreate_reference_database(initial_branch, flags & INIT_DB_QUIET);\n-\tcreate_object_directory();\n+\tcreate_object_directory(the_repository);\n \n \tif (repo_settings_get_shared_repository(the_repository)) {\n \t\tchar buf[10];\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541930","messageId":"20260420-pks-setup-wo-the-repository-v1-2-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 02/18] setup: stop using `the_repository` in `is_inside_worktree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:32Z","receivedAt":"2026-04-20T08:22:49Z","isPatch":true,"body":"The function `is_inside_worktree()` verifies whether or not the current\nworking directory is located inside the worktree of `the_repository`.\nThis is done by taking the worktree path and verifying that it's a\nprefix of the current working directory.\n\nThis information is cached so that we don't have to re-do this change\nmultiple times. Furthermore, we proactively set the value in multiple\nlocations so that we don't even have to perform the check when we have\ndiscovered the repository.\n\nWhile we could simply move the caching variable into the repository, the\ncurrent layout doesn't really feel sensible in the first place:\n\n  - It can easily lead to false positives or negatives if at any point\n    in time we may switch the current working directory.\n\n  - We don't call the function in a hot loop, and neither is it overly\n    expensive to compute.\n\nDrop the caching infrastructure and instead compute the property ad-hoc\nvia an injected repository.\n\nNote that there is one small gotcha: we sometimes may end up with\nrelative directory paths, and if so `is_inside_dir()` might fail. This\nwasn't an issue before because of how we proactively set the cached\nvalue during repository discovery. Now that we stop doing that it\nbecomes a problem though, but it is worked around by resolving the\nrepository directory via `realpath()`.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/ls-files.c  |  2 +-\n builtin/rev-parse.c |  4 ++--\n object-name.c       |  2 +-\n setup.c             | 18 +++++++-----------\n setup.h             |  2 +-\n submodule.c         |  2 +-\n 6 files changed, 13 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex b148607f7a..09d95111b3 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -703,7 +703,7 @@ int cmd_ls_files(int argc,\n \tif (dir.exclude_per_dir)\n \t\texc_given = 1;\n \n-\tif (require_work_tree && !is_inside_work_tree())\n+\tif (require_work_tree && !is_inside_work_tree(repo))\n \t\tsetup_work_tree();\n \n \tif (recurse_submodules &&\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 01a62800e8..9629e1ccf7 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -1006,7 +1006,7 @@ int cmd_rev_parse(int argc,\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--show-cdup\")) {\n \t\t\t\tconst char *pfx = prefix;\n-\t\t\t\tif (!is_inside_work_tree()) {\n+\t\t\t\tif (!is_inside_work_tree(the_repository)) {\n \t\t\t\t\tconst char *work_tree =\n \t\t\t\t\t\trepo_get_work_tree(the_repository);\n \t\t\t\t\tif (work_tree)\n@@ -1068,7 +1068,7 @@ int cmd_rev_parse(int argc,\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--is-inside-work-tree\")) {\n-\t\t\t\tprintf(\"%s\\n\", is_inside_work_tree() ? \"true\"\n+\t\t\t\tprintf(\"%s\\n\", is_inside_work_tree(the_repository) ? \"true\"\n \t\t\t\t\t\t: \"false\");\n \t\t\t\tcontinue;\n \t\t\t}\ndiff --git a/object-name.c b/object-name.c\nindex e5adec4c9d..7b7e546b1f 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -1990,7 +1990,7 @@ static char *resolve_relative_path(struct repository *r, const char *rel)\n \tif (!starts_with(rel, \"./\") && !starts_with(rel, \"../\"))\n \t\treturn NULL;\n \n-\tif (r != the_repository || !is_inside_work_tree())\n+\tif (r != the_repository || !is_inside_work_tree(the_repository))\n \t\tdie(_(\"relative path syntax can't be used outside working tree\"));\n \n \t/* die() inside prefix_path() if resolved path is outside worktree */\ndiff --git a/setup.c b/setup.c\nindex ba2898473a..4df65ba2e8 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -27,7 +27,6 @@\n #include \"worktree.h\"\n \n static int inside_git_dir = -1;\n-static int inside_work_tree = -1;\n static int work_tree_config_is_bogus;\n enum allowed_bare_repo {\n \tALLOWED_BARE_REPO_EXPLICIT = 0,\n@@ -299,7 +298,7 @@ void verify_filename(const char *prefix,\n  */\n void verify_non_filename(const char *prefix, const char *arg)\n {\n-\tif (!is_inside_work_tree() || is_inside_git_dir())\n+\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir())\n \t\treturn;\n \tif (*arg == '-')\n \t\treturn; /* flag */\n@@ -477,11 +476,13 @@ int is_inside_git_dir(void)\n \treturn inside_git_dir;\n }\n \n-int is_inside_work_tree(void)\n+int is_inside_work_tree(struct repository *repo)\n {\n-\tif (inside_work_tree < 0)\n-\t\tinside_work_tree = is_inside_dir(repo_get_work_tree(the_repository));\n-\treturn inside_work_tree;\n+\tstatic struct strbuf buf = STRBUF_INIT;\n+\tconst char *worktree = repo_get_work_tree(repo);\n+\tif (!worktree)\n+\t\treturn 0;\n+\treturn is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n }\n \n void setup_work_tree(void)\n@@ -798,13 +799,10 @@ static int check_repository_format_gently(struct repository *repo,\n \tif (!has_common) {\n \t\tif (candidate->is_bare != -1) {\n \t\t\tis_bare_repository_cfg = candidate->is_bare;\n-\t\t\tif (is_bare_repository_cfg == 1)\n-\t\t\t\tinside_work_tree = -1;\n \t\t}\n \t\tif (candidate->work_tree) {\n \t\t\tfree(git_work_tree_cfg);\n \t\t\tgit_work_tree_cfg = xstrdup(candidate->work_tree);\n-\t\t\tinside_work_tree = -1;\n \t\t}\n \t}\n \n@@ -1252,7 +1250,6 @@ static const char *setup_discovered_git_dir(struct repository *repo,\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n \t\tset_git_dir(repo, gitdir, 0);\n \tinside_git_dir = 0;\n-\tinside_work_tree = 1;\n \tif (offset >= cwd->len)\n \t\treturn NULL;\n \n@@ -1288,7 +1285,6 @@ static const char *setup_bare_git_dir(struct repository *repo,\n \t}\n \n \tinside_git_dir = 1;\n-\tinside_work_tree = 0;\n \tif (offset != cwd->len) {\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\ndiff --git a/setup.h b/setup.h\nindex 80bc6e5f07..7c0aa75319 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -5,7 +5,7 @@\n #include \"string-list.h\"\n \n int is_inside_git_dir(void);\n-int is_inside_work_tree(void);\n+int is_inside_work_tree(struct repository *repo);\n int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);\n int get_common_dir(struct strbuf *sb, const char *gitdir);\n \ndiff --git a/submodule.c b/submodule.c\nindex e20537ba8d..46116cee88 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -2622,7 +2622,7 @@ int get_superproject_working_tree(struct strbuf *buf)\n \tint code;\n \tssize_t len;\n \n-\tif (!is_inside_work_tree())\n+\tif (!is_inside_work_tree(the_repository))\n \t\t/*\n \t\t * FIXME:\n \t\t * We might have a superproject, but it is harder\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541931","messageId":"20260420-pks-setup-wo-the-repository-v1-3-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 03/18] setup: stop using `the_repository` in `is_inside_git_dir()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:33Z","receivedAt":"2026-04-20T08:22:52Z","isPatch":true,"body":"Similar as with the preceding commit, `is_inside_git_dir()` determines\nwhether the current working directory is located inside the gitdir of\n`the_repository`. Perform the same refactoring by dropping the caching\nmechanism and injecting the repository that shall be checked.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/rev-parse.c |  2 +-\n setup.c             | 12 ++++--------\n setup.h             |  2 +-\n 3 files changed, 6 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 9629e1ccf7..6dd49ae3f4 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -1063,7 +1063,7 @@ int cmd_rev_parse(int argc,\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--is-inside-git-dir\")) {\n-\t\t\t\tprintf(\"%s\\n\", is_inside_git_dir() ? \"true\"\n+\t\t\t\tprintf(\"%s\\n\", is_inside_git_dir(the_repository) ? \"true\"\n \t\t\t\t\t\t: \"false\");\n \t\t\t\tcontinue;\n \t\t\t}\ndiff --git a/setup.c b/setup.c\nindex 4df65ba2e8..864ce41116 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -26,7 +26,6 @@\n #include \"trace2.h\"\n #include \"worktree.h\"\n \n-static int inside_git_dir = -1;\n static int work_tree_config_is_bogus;\n enum allowed_bare_repo {\n \tALLOWED_BARE_REPO_EXPLICIT = 0,\n@@ -298,7 +297,7 @@ void verify_filename(const char *prefix,\n  */\n void verify_non_filename(const char *prefix, const char *arg)\n {\n-\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir())\n+\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir(the_repository))\n \t\treturn;\n \tif (*arg == '-')\n \t\treturn; /* flag */\n@@ -469,11 +468,10 @@ int is_nonbare_repository_dir(struct strbuf *path)\n \treturn ret;\n }\n \n-int is_inside_git_dir(void)\n+int is_inside_git_dir(struct repository *repo)\n {\n-\tif (inside_git_dir < 0)\n-\t\tinside_git_dir = is_inside_dir(repo_get_git_dir(the_repository));\n-\treturn inside_git_dir;\n+\tstatic struct strbuf buf = STRBUF_INIT;\n+\treturn is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));\n }\n \n int is_inside_work_tree(struct repository *repo)\n@@ -1249,7 +1247,6 @@ static const char *setup_discovered_git_dir(struct repository *repo,\n \tset_git_work_tree(\".\");\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n \t\tset_git_dir(repo, gitdir, 0);\n-\tinside_git_dir = 0;\n \tif (offset >= cwd->len)\n \t\treturn NULL;\n \n@@ -1284,7 +1281,6 @@ static const char *setup_bare_git_dir(struct repository *repo,\n \t\treturn setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n \t}\n \n-\tinside_git_dir = 1;\n \tif (offset != cwd->len) {\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\ndiff --git a/setup.h b/setup.h\nindex 7c0aa75319..71d3f91883 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -4,7 +4,7 @@\n #include \"refs.h\"\n #include \"string-list.h\"\n \n-int is_inside_git_dir(void);\n+int is_inside_git_dir(struct repository *repo);\n int is_inside_work_tree(struct repository *repo);\n int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);\n int get_common_dir(struct strbuf *sb, const char *gitdir);\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541932","messageId":"20260420-pks-setup-wo-the-repository-v1-4-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 04/18] setup: stop using `the_repository` in `prefix_path()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:34Z","receivedAt":"2026-04-20T08:22:56Z","isPatch":true,"body":"Stop using `the_repository` in `prefix_path()` and instead accept the\nrepository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/blame.c            |  2 +-\n builtin/check-attr.c       |  2 +-\n builtin/checkout-index.c   |  4 ++--\n builtin/mv.c               |  5 +++--\n builtin/sparse-checkout.c  |  3 ++-\n builtin/update-index.c     |  6 +++---\n line-log.c                 |  2 +-\n object-name.c              |  2 +-\n pathspec.c                 |  2 +-\n setup.c                    | 15 ++++++++-------\n setup.h                    |  4 ++--\n t/helper/test-path-utils.c |  2 +-\n 12 files changed, 26 insertions(+), 23 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex f3a11eff44..ffbd3ce5c5 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -708,7 +708,7 @@ static unsigned parse_score(const char *arg)\n \n static char *add_prefix(const char *prefix, const char *path)\n {\n-\treturn prefix_path(prefix, prefix ? strlen(prefix) : 0, path);\n+\treturn prefix_path(the_repository, prefix, prefix ? strlen(prefix) : 0, path);\n }\n \n static int git_blame_config(const char *var, const char *value,\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 51ed48ce43..04b86e42ae 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -67,7 +67,7 @@ static void check_attr(const char *prefix, struct attr_check *check,\n \n {\n \tchar *full_path =\n-\t\tprefix_path(prefix, prefix ? strlen(prefix) : 0, file);\n+\t\tprefix_path(the_repository, prefix, prefix ? strlen(prefix) : 0, file);\n \n \tif (collect_all) {\n \t\tgit_all_attrs(the_repository->index, full_path, check);\ndiff --git a/builtin/checkout-index.c b/builtin/checkout-index.c\nindex 188128aebd..311b94ff31 100644\n--- a/builtin/checkout-index.c\n+++ b/builtin/checkout-index.c\n@@ -303,7 +303,7 @@ int cmd_checkout_index(int argc,\n \t\t\tdie(\"git checkout-index: don't mix '--all' and explicit filenames\");\n \t\tif (read_from_stdin)\n \t\t\tdie(\"git checkout-index: don't mix '--stdin' and explicit filenames\");\n-\t\tp = prefix_path(prefix, prefix_length, arg);\n+\t\tp = prefix_path(repo, prefix, prefix_length, arg);\n \t\terr |= checkout_file(repo->index, p, prefix);\n \t\tfree(p);\n \t}\n@@ -325,7 +325,7 @@ int cmd_checkout_index(int argc,\n \t\t\t\t\tdie(\"line is badly quoted\");\n \t\t\t\tstrbuf_swap(&buf, &unquoted);\n \t\t\t}\n-\t\t\tp = prefix_path(prefix, prefix_length, buf.buf);\n+\t\t\tp = prefix_path(repo, prefix, prefix_length, buf.buf);\n \t\t\terr |= checkout_file(repo->index, p, prefix);\n \t\t\tfree(p);\n \t\t}\ndiff --git a/builtin/mv.c b/builtin/mv.c\nindex 2215d34e31..948b330639 100644\n--- a/builtin/mv.c\n+++ b/builtin/mv.c\n@@ -71,7 +71,7 @@ static void internal_prefix_pathspec(struct strvec *out,\n \n \t\ttrimmed = xmemdupz(pathspec[i], to_copy);\n \t\tmaybe_basename = (flags & DUP_BASENAME) ? basename(trimmed) : trimmed;\n-\t\tprefixed_path = prefix_path(prefix, prefixlen, maybe_basename);\n+\t\tprefixed_path = prefix_path(the_repository, prefix, prefixlen, maybe_basename);\n \t\tstrvec_push(out, prefixed_path);\n \n \t\tfree(prefixed_path);\n@@ -394,7 +394,8 @@ int cmd_mv(int argc,\n \t\t\tfor (j = 0; j < last - first; j++) {\n \t\t\t\tconst struct cache_entry *ce = the_repository->index->cache[first + j];\n \t\t\t\tconst char *path = ce->name;\n-\t\t\t\tchar *prefixed_path = prefix_path(dst_with_slash, dst_with_slash_len, path + length + 1);\n+\t\t\t\tchar *prefixed_path = prefix_path(the_repository, dst_with_slash,\n+\t\t\t\t\t\t\t\t  dst_with_slash_len, path + length + 1);\n \n \t\t\t\tstrvec_push(&sources, path);\n \t\t\t\tstrvec_push(&destinations, prefixed_path);\ndiff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c\nindex f4aa405da9..2af50fb2f9 100644\n--- a/builtin/sparse-checkout.c\n+++ b/builtin/sparse-checkout.c\n@@ -735,7 +735,8 @@ static void sanitize_paths(struct repository *repo,\n \t\tint prefix_len = strlen(prefix);\n \n \t\tfor (i = 0; i < args->nr; i++) {\n-\t\t\tchar *prefixed_path = prefix_path(prefix, prefix_len, args->v[i]);\n+\t\t\tchar *prefixed_path = prefix_path(the_repository, prefix,\n+\t\t\t\t\t\t\t  prefix_len, args->v[i]);\n \t\t\tstrvec_replace(args, i, prefixed_path);\n \t\t\tfree(prefixed_path);\n \t\t}\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 8a5907767b..7434112b8e 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -655,7 +655,7 @@ static int do_unresolve(int ac, const char **av,\n \n \tfor (i = 1; i < ac; i++) {\n \t\tconst char *arg = av[i];\n-\t\tchar *p = prefix_path(prefix, prefix_length, arg);\n+\t\tchar *p = prefix_path(the_repository, prefix, prefix_length, arg);\n \t\terr |= unresolve_one(p);\n \t\tfree(p);\n \t}\n@@ -1158,7 +1158,7 @@ int cmd_update_index(int argc,\n \t\t\t}\n \n \t\t\tsetup_work_tree();\n-\t\t\tp = prefix_path(prefix, prefix_length, path);\n+\t\t\tp = prefix_path(the_repository, prefix, prefix_length, path);\n \t\t\tupdate_one(p);\n \t\t\tif (set_executable_bit)\n \t\t\t\tchmod_path(set_executable_bit, p);\n@@ -1208,7 +1208,7 @@ int cmd_update_index(int argc,\n \t\t\t\t\tdie(\"line is badly quoted\");\n \t\t\t\tstrbuf_swap(&buf, &unquoted);\n \t\t\t}\n-\t\t\tp = prefix_path(prefix, prefix_length, buf.buf);\n+\t\t\tp = prefix_path(the_repository, prefix, prefix_length, buf.buf);\n \t\t\tupdate_one(p);\n \t\t\tif (set_executable_bit)\n \t\t\t\tchmod_path(set_executable_bit, p);\ndiff --git a/line-log.c b/line-log.c\nindex eeaf68454e..a6fc46d331 100644\n--- a/line-log.c\n+++ b/line-log.c\n@@ -589,7 +589,7 @@ parse_lines(struct repository *r, struct commit *commit,\n \t\trange_part = xstrndup(item->string, name_part - item->string);\n \t\tname_part++;\n \n-\t\tfull_name = prefix_path(prefix, prefix ? strlen(prefix) : 0,\n+\t\tfull_name = prefix_path(r, prefix, prefix ? strlen(prefix) : 0,\n \t\t\t\t\tname_part);\n \n \t\tspec = alloc_filespec(full_name);\ndiff --git a/object-name.c b/object-name.c\nindex 7b7e546b1f..ca5f060a4e 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -1994,7 +1994,7 @@ static char *resolve_relative_path(struct repository *r, const char *rel)\n \t\tdie(_(\"relative path syntax can't be used outside working tree\"));\n \n \t/* die() inside prefix_path() if resolved path is outside worktree */\n-\treturn prefix_path(startup_info->prefix,\n+\treturn prefix_path(the_repository, startup_info->prefix,\n \t\t\t   startup_info->prefix ? strlen(startup_info->prefix) : 0,\n \t\t\t   rel);\n }\ndiff --git a/pathspec.c b/pathspec.c\nindex 5993c4afa0..f78b22709c 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -486,7 +486,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,\n \t\tmatch = xstrdup(copyfrom);\n \t\tprefixlen = 0;\n \t} else {\n-\t\tmatch = prefix_path_gently(prefix, prefixlen,\n+\t\tmatch = prefix_path_gently(the_repository, prefix, prefixlen,\n \t\t\t\t\t   &prefixlen, copyfrom);\n \t\tif (!match) {\n \t\t\tconst char *hint_path;\ndiff --git a/setup.c b/setup.c\nindex 864ce41116..331ea86a40 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -117,7 +117,8 @@ static int abspath_part_inside_repo(struct repository *repo, char *path)\n  *  ../../sub1/sub2/foo -> sub1/sub2/foo (but no remaining prefix)\n  *  `pwd`/../bar -> sub1/bar       (no remaining prefix)\n  */\n-char *prefix_path_gently(const char *prefix, int len,\n+char *prefix_path_gently(struct repository *repo,\n+\t\t\t const char *prefix, int len,\n \t\t\t int *remaining_prefix, const char *path)\n {\n \tconst char *orig = path;\n@@ -130,7 +131,7 @@ char *prefix_path_gently(const char *prefix, int len,\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n-\t\tif (abspath_part_inside_repo(the_repository, sanitized)) {\n+\t\tif (abspath_part_inside_repo(repo, sanitized)) {\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n@@ -146,13 +147,13 @@ char *prefix_path_gently(const char *prefix, int len,\n \treturn sanitized;\n }\n \n-char *prefix_path(const char *prefix, int len, const char *path)\n+char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path)\n {\n-\tchar *r = prefix_path_gently(prefix, len, NULL, path);\n+\tchar *r = prefix_path_gently(repo, prefix, len, NULL, path);\n \tif (!r) {\n-\t\tconst char *hint_path = repo_get_work_tree(the_repository);\n+\t\tconst char *hint_path = repo_get_work_tree(repo);\n \t\tif (!hint_path)\n-\t\t\thint_path = repo_get_git_dir(the_repository);\n+\t\t\thint_path = repo_get_git_dir(repo);\n \t\tdie(_(\"'%s' is outside repository at '%s'\"), path,\n \t\t    absolute_path(hint_path));\n \t}\n@@ -162,7 +163,7 @@ char *prefix_path(const char *prefix, int len, const char *path)\n int path_inside_repo(const char *prefix, const char *path)\n {\n \tint len = prefix ? strlen(prefix) : 0;\n-\tchar *r = prefix_path_gently(prefix, len, NULL, path);\n+\tchar *r = prefix_path_gently(the_repository, prefix, len, NULL, path);\n \tif (r) {\n \t\tfree(r);\n \t\treturn 1;\ndiff --git a/setup.h b/setup.h\nindex 71d3f91883..24034572b1 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -138,8 +138,8 @@ const char *enter_repo(const char *path, unsigned flags);\n \n const char *setup_git_directory_gently(int *);\n const char *setup_git_directory(void);\n-char *prefix_path(const char *prefix, int len, const char *path);\n-char *prefix_path_gently(const char *prefix, int len, int *remaining, const char *path);\n+char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path);\n+char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\n \n int check_filename(const char *prefix, const char *name);\n void verify_filename(const char *prefix,\ndiff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c\nindex 874542ec34..163fdeefb0 100644\n--- a/t/helper/test-path-utils.c\n+++ b/t/helper/test-path-utils.c\n@@ -379,7 +379,7 @@ int cmd__path_utils(int argc, const char **argv)\n \t\tint nongit_ok;\n \t\tsetup_git_directory_gently(&nongit_ok);\n \t\twhile (argc > 3) {\n-\t\t\tchar *pfx = prefix_path(prefix, prefix_len, argv[3]);\n+\t\t\tchar *pfx = prefix_path(the_repository, prefix, prefix_len, argv[3]);\n \n \t\t\tputs(pfx);\n \t\t\tfree(pfx);\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541933","messageId":"20260420-pks-setup-wo-the-repository-v1-5-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 05/18] setup: stop using `the_repository` in `path_inside_repo()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:35Z","receivedAt":"2026-04-20T08:22:59Z","isPatch":true,"body":"Stop using `the_repository` in `path_inside_repo()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/diff.c | 4 ++--\n setup.c        | 4 ++--\n setup.h        | 2 +-\n 3 files changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/diff.c b/builtin/diff.c\nindex 0b23c41456..7ddebce2ac 100644\n--- a/builtin/diff.c\n+++ b/builtin/diff.c\n@@ -471,8 +471,8 @@ int cmd_diff(int argc,\n \t\t * as a colourful \"diff\" replacement.\n \t\t */\n \t\tif (nongit || ((argc == i + 2) &&\n-\t\t\t       (!path_inside_repo(prefix, argv[i]) ||\n-\t\t\t\t!path_inside_repo(prefix, argv[i + 1]))))\n+\t\t\t       (!path_inside_repo(the_repository, prefix, argv[i]) ||\n+\t\t\t\t!path_inside_repo(the_repository, prefix, argv[i + 1]))))\n \t\t\tno_index = DIFF_NO_INDEX_IMPLICIT;\n \t}\n \ndiff --git a/setup.c b/setup.c\nindex 331ea86a40..6cfb05c527 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -160,10 +160,10 @@ char *prefix_path(struct repository *repo, const char *prefix, int len, const ch\n \treturn r;\n }\n \n-int path_inside_repo(const char *prefix, const char *path)\n+int path_inside_repo(struct repository *repo, const char *prefix, const char *path)\n {\n \tint len = prefix ? strlen(prefix) : 0;\n-\tchar *r = prefix_path_gently(the_repository, prefix, len, NULL, path);\n+\tchar *r = prefix_path_gently(repo, prefix, len, NULL, path);\n \tif (r) {\n \t\tfree(r);\n \t\treturn 1;\ndiff --git a/setup.h b/setup.h\nindex 24034572b1..c3247d7fc8 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -146,7 +146,7 @@ void verify_filename(const char *prefix,\n \t\t     const char *name,\n \t\t     int diagnose_misspelt_rev);\n void verify_non_filename(const char *prefix, const char *name);\n-int path_inside_repo(const char *prefix, const char *path);\n+int path_inside_repo(struct repository *repo, const char *prefix, const char *path);\n \n void sanitize_stdfds(void);\n int daemonize(void);\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541934","messageId":"20260420-pks-setup-wo-the-repository-v1-6-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 06/18] setup: stop using `the_repository` in `verify_filename()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:36Z","receivedAt":"2026-04-20T08:23:02Z","isPatch":true,"body":"Stop using `the_repository` in `verify_filename()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/grep.c      | 2 +-\n builtin/reset.c     | 2 +-\n builtin/rev-parse.c | 4 ++--\n revision.c          | 2 +-\n setup.c             | 5 +++--\n setup.h             | 3 ++-\n 6 files changed, 10 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex e33285e5e6..b0e350cf89 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1163,7 +1163,7 @@ int cmd_grep(int argc,\n \tif (!seen_dashdash) {\n \t\tint j;\n \t\tfor (j = i; j < argc; j++)\n-\t\t\tverify_filename(prefix, argv[j], j == i && allow_revs);\n+\t\t\tverify_filename(the_repository, prefix, argv[j], j == i && allow_revs);\n \t}\n \n \tparse_pathspec(&pathspec, 0,\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex 3590be57a5..1ac374d31b 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -285,7 +285,7 @@ static void parse_args(struct pathspec *pathspec,\n \t\t\trev = *argv++;\n \t\t} else {\n \t\t\t/* Otherwise we treat this as a filename */\n-\t\t\tverify_filename(prefix, argv[0], 1);\n+\t\t\tverify_filename(the_repository, prefix, argv[0], 1);\n \t\t}\n \t}\n \ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 6dd49ae3f4..d7c6400ddc 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -749,7 +749,7 @@ int cmd_rev_parse(int argc,\n \n \t\tif (as_is) {\n \t\t\tif (show_file(arg, output_prefix) && as_is < 2)\n-\t\t\t\tverify_filename(prefix, arg, 0);\n+\t\t\t\tverify_filename(the_repository, prefix, arg, 0);\n \t\t\tcontinue;\n \t\t}\n \n@@ -1173,7 +1173,7 @@ int cmd_rev_parse(int argc,\n \t\tas_is = 1;\n \t\tif (!show_file(arg, output_prefix))\n \t\t\tcontinue;\n-\t\tverify_filename(prefix, arg, 1);\n+\t\tverify_filename(the_repository, prefix, arg, 1);\n \t}\n \tstrbuf_release(&buf);\n \tif (verify) {\ndiff --git a/revision.c b/revision.c\nindex 31808e3df0..57cf00ae6b 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -3066,7 +3066,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s\n \t\t\t * but the latter we have checked in the main loop.\n \t\t\t */\n \t\t\tfor (j = i; j < argc; j++)\n-\t\t\t\tverify_filename(revs->prefix, argv[j], j == i);\n+\t\t\t\tverify_filename(the_repository, revs->prefix, argv[j], j == i);\n \n \t\t\tstrvec_pushv(&prune_data, argv + i);\n \t\t\tbreak;\ndiff --git a/setup.c b/setup.c\nindex 6cfb05c527..736f950bd0 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -280,7 +280,8 @@ static int looks_like_pathspec(const char *arg)\n  * diagnose_misspelt_rev == 0 for the next ones (because we already\n  * saw a filename, there's not ambiguity anymore).\n  */\n-void verify_filename(const char *prefix,\n+void verify_filename(struct repository *repo,\n+\t\t     const char *prefix,\n \t\t     const char *arg,\n \t\t     int diagnose_misspelt_rev)\n {\n@@ -288,7 +289,7 @@ void verify_filename(const char *prefix,\n \t\tdie(_(\"option '%s' must come before non-option arguments\"), arg);\n \tif (looks_like_pathspec(arg) || check_filename(prefix, arg))\n \t\treturn;\n-\tdie_verify_filename(the_repository, prefix, arg, diagnose_misspelt_rev);\n+\tdie_verify_filename(repo, prefix, arg, diagnose_misspelt_rev);\n }\n \n /*\ndiff --git a/setup.h b/setup.h\nindex c3247d7fc8..24a6f66629 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -142,7 +142,8 @@ char *prefix_path(struct repository *repo, const char *prefix, int len, const ch\n char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\n \n int check_filename(const char *prefix, const char *name);\n-void verify_filename(const char *prefix,\n+void verify_filename(struct repository *repo,\n+\t\t     const char *prefix,\n \t\t     const char *name,\n \t\t     int diagnose_misspelt_rev);\n void verify_non_filename(const char *prefix, const char *name);\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541935","messageId":"20260420-pks-setup-wo-the-repository-v1-7-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 07/18] setup: stop using `the_repository` in `verify_non_filename()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:37Z","receivedAt":"2026-04-20T08:23:07Z","isPatch":true,"body":"Stop using `the_repository` in `verify_non_filename()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/checkout.c | 2 +-\n builtin/grep.c     | 2 +-\n builtin/reset.c    | 2 +-\n revision.c         | 4 ++--\n setup.c            | 4 ++--\n setup.h            | 2 +-\n 6 files changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex e031e61886..d7069765e7 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -1485,7 +1485,7 @@ static int parse_branchname_arg(int argc, const char **argv,\n \t\t * it would be extremely annoying.\n \t\t */\n \t\tif (argc)\n-\t\t\tverify_non_filename(opts->prefix, arg);\n+\t\t\tverify_non_filename(the_repository, opts->prefix, arg);\n \t} else if (opts->accept_pathspec) {\n \t\targcount++;\n \t\targv++;\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex b0e350cf89..4ec0c016b1 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1151,7 +1151,7 @@ int cmd_grep(int argc,\n \n \t\tobject = parse_object_or_die(the_repository, &oid, arg);\n \t\tif (!seen_dashdash)\n-\t\t\tverify_non_filename(prefix, arg);\n+\t\t\tverify_non_filename(the_repository, prefix, arg);\n \t\tadd_object_array_with_path(object, arg, &list, oc.mode, oc.path);\n \t\tobject_context_release(&oc);\n \t}\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex 1ac374d31b..11f57605b5 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -281,7 +281,7 @@ static void parse_args(struct pathspec *pathspec,\n \t\t\t * Ok, argv[0] looks like a commit/tree; it should not\n \t\t\t * be a filename.\n \t\t\t */\n-\t\t\tverify_non_filename(prefix, argv[0]);\n+\t\t\tverify_non_filename(the_repository, prefix, argv[0]);\n \t\t\trev = *argv++;\n \t\t} else {\n \t\t\t/* Otherwise we treat this as a filename */\ndiff --git a/revision.c b/revision.c\nindex 57cf00ae6b..9071a38b85 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2082,7 +2082,7 @@ static int handle_dotdot_1(const char *arg, char *dotdot,\n \n \tif (!cant_be_filename) {\n \t\t*dotdot = '.';\n-\t\tverify_non_filename(revs->prefix, arg);\n+\t\tverify_non_filename(the_repository, revs->prefix, arg);\n \t\t*dotdot = '\\0';\n \t}\n \n@@ -2227,7 +2227,7 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl\n \t\tgoto out;\n \t}\n \tif (!cant_be_filename)\n-\t\tverify_non_filename(revs->prefix, arg);\n+\t\tverify_non_filename(the_repository, revs->prefix, arg);\n \tobject = get_reference(revs, arg, &oid, flags ^ local_flags);\n \tif (!object) {\n \t\tret = (revs->ignore_missing || revs->do_not_die_on_missing_objects) ? 0 : -1;\ndiff --git a/setup.c b/setup.c\nindex 736f950bd0..c6b5b85f3a 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -297,9 +297,9 @@ void verify_filename(struct repository *repo,\n  * and we parsed the arg as a refname.  It should not be interpretable\n  * as a filename.\n  */\n-void verify_non_filename(const char *prefix, const char *arg)\n+void verify_non_filename(struct repository *repo, const char *prefix, const char *arg)\n {\n-\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir(the_repository))\n+\tif (!is_inside_work_tree(repo) || is_inside_git_dir(repo))\n \t\treturn;\n \tif (*arg == '-')\n \t\treturn; /* flag */\ndiff --git a/setup.h b/setup.h\nindex 24a6f66629..364c2c728a 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -146,7 +146,7 @@ void verify_filename(struct repository *repo,\n \t\t     const char *prefix,\n \t\t     const char *name,\n \t\t     int diagnose_misspelt_rev);\n-void verify_non_filename(const char *prefix, const char *name);\n+void verify_non_filename(struct repository *repo, const char *prefix, const char *name);\n int path_inside_repo(struct repository *repo, const char *prefix, const char *path);\n \n void sanitize_stdfds(void);\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541936","messageId":"20260420-pks-setup-wo-the-repository-v1-8-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 08/18] setup: stop using `the_repository` in `enter_repo()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:38Z","receivedAt":"2026-04-20T08:23:10Z","isPatch":true,"body":"Stop using `the_repository` in `enter_repo()` and instead accept the\nrepository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/receive-pack.c   | 2 +-\n builtin/upload-archive.c | 2 +-\n builtin/upload-pack.c    | 2 +-\n daemon.c                 | 4 ++--\n http-backend.c           | 2 +-\n setup.c                  | 4 ++--\n setup.h                  | 2 +-\n 7 files changed, 9 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex e34edff406..c5f73fff35 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2646,7 +2646,7 @@ int cmd_receive_pack(int argc,\n \n \tsetup_path();\n \n-\tif (!enter_repo(service_dir, 0))\n+\tif (!enter_repo(the_repository, service_dir, 0))\n \t\tdie(\"'%s' does not appear to be a git repository\", service_dir);\n \n \trepo_config(the_repository, receive_pack_config, NULL);\ndiff --git a/builtin/upload-archive.c b/builtin/upload-archive.c\nindex 25312bb2a5..718e74b3ac 100644\n--- a/builtin/upload-archive.c\n+++ b/builtin/upload-archive.c\n@@ -31,7 +31,7 @@ int cmd_upload_archive_writer(int argc,\n \tif (argc != 2)\n \t\tusage(upload_archive_usage);\n \n-\tif (!enter_repo(argv[1], 0))\n+\tif (!enter_repo(the_repository, argv[1], 0))\n \t\tdie(\"'%s' does not appear to be a git repository\", argv[1]);\n \n \tinit_archivers();\ndiff --git a/builtin/upload-pack.c b/builtin/upload-pack.c\nindex 30498fafea..32831fb879 100644\n--- a/builtin/upload-pack.c\n+++ b/builtin/upload-pack.c\n@@ -59,7 +59,7 @@ int cmd_upload_pack(int argc,\n \n \tif (strict)\n \t\tenter_repo_flags |= ENTER_REPO_STRICT;\n-\tif (!enter_repo(dir, enter_repo_flags))\n+\tif (!enter_repo(the_repository, dir, enter_repo_flags))\n \t\tdie(\"'%s' does not appear to be a git repository\", dir);\n \n \tswitch (determine_protocol_version_server()) {\ndiff --git a/daemon.c b/daemon.c\nindex 0a7b1aae44..947dd90655 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -244,14 +244,14 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)\n \t}\n \n \tenter_repo_flags = strict_paths ? ENTER_REPO_STRICT : 0;\n-\tpath = enter_repo(dir, enter_repo_flags);\n+\tpath = enter_repo(the_repository, dir, enter_repo_flags);\n \tif (!path && base_path && base_path_relaxed) {\n \t\t/*\n \t\t * if we fail and base_path_relaxed is enabled, try without\n \t\t * prefixing the base path\n \t\t */\n \t\tdir = directory;\n-\t\tpath = enter_repo(dir, enter_repo_flags);\n+\t\tpath = enter_repo(the_repository, dir, enter_repo_flags);\n \t}\n \n \tif (!path) {\ndiff --git a/http-backend.c b/http-backend.c\nindex 1a171c5c5a..c7566b1d12 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -809,7 +809,7 @@ int cmd_main(int argc UNUSED, const char **argv UNUSED)\n \t\tnot_found(&hdr, \"Request not supported: '%s'\", dir);\n \n \tsetup_path();\n-\tif (!enter_repo(dir, 0))\n+\tif (!enter_repo(the_repository, dir, 0))\n \t\tnot_found(&hdr, \"Not a git repository: '%s'\", dir);\n \tif (!getenv(\"GIT_HTTP_EXPORT_ALL\") &&\n \t    access(\"git-daemon-export-ok\", F_OK) )\ndiff --git a/setup.c b/setup.c\nindex c6b5b85f3a..dca32addae 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1756,7 +1756,7 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir,\n \treturn result;\n }\n \n-const char *enter_repo(const char *path, unsigned flags)\n+const char *enter_repo(struct repository *repo, const char *path, unsigned flags)\n {\n \tstatic struct strbuf validated_path = STRBUF_INIT;\n \tstatic struct strbuf used_path = STRBUF_INIT;\n@@ -1829,7 +1829,7 @@ const char *enter_repo(const char *path, unsigned flags)\n \t}\n \n \tif (is_git_directory(\".\")) {\n-\t\tset_git_dir(the_repository, \".\", 0);\n+\t\tset_git_dir(repo, \".\", 0);\n \t\tcheck_repository_format(NULL);\n \t\treturn path;\n \t}\ndiff --git a/setup.h b/setup.h\nindex 364c2c728a..d0cfdfd44a 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -134,7 +134,7 @@ enum {\n  * links.  User relative paths are also returned as they are given,\n  * except DWIM suffixing.\n  */\n-const char *enter_repo(const char *path, unsigned flags);\n+const char *enter_repo(struct repository *repo, const char *path, unsigned flags);\n \n const char *setup_git_directory_gently(int *);\n const char *setup_git_directory(void);\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541938","messageId":"20260420-pks-setup-wo-the-repository-v1-9-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 09/18] setup: stop using `the_repository` in `setup_work_tree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:39Z","receivedAt":"2026-04-20T08:23:13Z","isPatch":true,"body":"Stop using `the_repository` in `setup_work_tree()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nNote that the function tracks two bits of information via global\nvariables. This of course doesn't make much sense anymore now that we\ncan set up worktrees for arbitrary repositories:\n\n  - We track whether the worktree has already been initialized and, if\n    so, we skip the call to `chdir_notify()` and setenv(3p). It does not\n    make much sense to store this info in the repository, as we _would_\n    want to update the environment when switching between worktrees back\n    and forth.\n\n    So instead of storing this info in the repository, we drop this\n    state entirely and live with the fact that we may execute the logic\n    twice. It should ultimately be idempotent though and thus not be\n    much of a problem.\n\n  - We track whether the worktree configuration is bogus. If so, and if\n    later on some caller tries to setup the worktree, then we'll die\n    instead. This is indeed information that we can move into the\n    repository itself.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n blame.c                     |  2 +-\n builtin/check-attr.c        |  2 +-\n builtin/clone.c             |  2 +-\n builtin/describe.c          |  2 +-\n builtin/diff-index.c        |  2 +-\n builtin/diff.c              |  4 ++--\n builtin/difftool.c          |  2 +-\n builtin/grep.c              |  2 +-\n builtin/ls-files.c          |  2 +-\n builtin/read-tree.c         |  2 +-\n builtin/reset.c             |  2 +-\n builtin/rm.c                |  2 +-\n builtin/sparse-checkout.c   | 16 ++++++++--------\n builtin/submodule--helper.c |  2 +-\n builtin/update-index.c      | 10 +++++-----\n git.c                       |  2 +-\n repository.h                |  1 +\n setup.c                     | 15 ++++-----------\n setup.h                     |  2 +-\n t/helper/test-subprocess.c  |  4 +++-\n wt-status.c                 |  2 +-\n 21 files changed, 38 insertions(+), 42 deletions(-)\n\ndiff --git a/blame.c b/blame.c\nindex a3c49d132e..977cbb7097 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -2813,7 +2813,7 @@ void setup_scoreboard(struct blame_scoreboard *sb,\n \t\t}\n \n \t\tif (!sb->contents_from)\n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \n \t\tsb->final = fake_working_tree_commit(sb->repo,\n \t\t\t\t\t\t     &sb->revs->diffopt,\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 04b86e42ae..98f64d5b92 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -117,7 +117,7 @@ int cmd_check_attr(int argc,\n \tint cnt, i, doubledash, filei;\n \n \tif (!is_bare_repository())\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \trepo_config(the_repository, git_default_config, NULL);\n \ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex fba3c9c508..91b9a105a4 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -668,7 +668,7 @@ static int checkout(int submodule_progress,\n \t}\n \n \t/* We need to be in the new work tree for the checkout */\n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \n \trepo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);\n \ndiff --git a/builtin/describe.c b/builtin/describe.c\nindex bffeed13a3..1c47d7c0b7 100644\n--- a/builtin/describe.c\n+++ b/builtin/describe.c\n@@ -781,7 +781,7 @@ int cmd_describe(int argc,\n \t\t\tstruct rev_info revs;\n \t\t\tint fd;\n \n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \t\t\tprepare_repo_settings(the_repository);\n \t\t\tthe_repository->settings.command_requires_full_index = 0;\n \t\t\trepo_read_index(the_repository);\ndiff --git a/builtin/diff-index.c b/builtin/diff-index.c\nindex 522dacfc4c..3db7cffede 100644\n--- a/builtin/diff-index.c\n+++ b/builtin/diff-index.c\n@@ -69,7 +69,7 @@ int cmd_diff_index(int argc,\n \t    rev.max_count != -1 || rev.min_age != -1 || rev.max_age != -1)\n \t\tusage(diff_cache_usage);\n \tif (!(option & DIFF_INDEX_CACHED)) {\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\tif (repo_read_index_preload(the_repository, &rev.diffopt.pathspec, 0) < 0) {\n \t\t\tperror(\"repo_read_index_preload\");\n \t\t\treturn -1;\ndiff --git a/builtin/diff.c b/builtin/diff.c\nindex 7ddebce2ac..1ede873ac1 100644\n--- a/builtin/diff.c\n+++ b/builtin/diff.c\n@@ -159,7 +159,7 @@ static void builtin_diff_index(struct rev_info *revs,\n \t    revs->max_age != -1)\n \t\tusage(builtin_diff_usage);\n \tif (!(option & DIFF_INDEX_CACHED)) {\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\tif (repo_read_index_preload(the_repository,\n \t\t\t\t\t    &revs->diffopt.pathspec, 0) < 0) {\n \t\t\tdie_errno(\"repo_read_index_preload\");\n@@ -281,7 +281,7 @@ static void builtin_diff_files(struct rev_info *revs, int argc, const char **arg\n \t    (revs->diffopt.output_format & DIFF_FORMAT_PATCH))\n \t\tdiff_merges_set_dense_combined_if_unset(revs);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (repo_read_index_preload(the_repository, &revs->diffopt.pathspec,\n \t\t\t\t    0) < 0) {\n \t\tdie_errno(\"repo_read_index_preload\");\ndiff --git a/builtin/difftool.c b/builtin/difftool.c\nindex e4bc1f8316..2a21005f2e 100644\n--- a/builtin/difftool.c\n+++ b/builtin/difftool.c\n@@ -767,7 +767,7 @@ int cmd_difftool(int argc,\n \t\tdie(_(\"difftool requires worktree or --no-index\"));\n \n \tif (!no_index){\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(repo);\n \t\tsetenv(GIT_DIR_ENVIRONMENT, absolute_path(repo_get_git_dir(repo)), 1);\n \t\tsetenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(repo_get_work_tree(repo)), 1);\n \t} else if (dir_diff)\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 4ec0c016b1..679f8b567a 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1272,7 +1272,7 @@ int cmd_grep(int argc,\n \t\tdie(_(\"--[no-]exclude-standard cannot be used for tracked contents\"));\n \t} else if (!list.nr) {\n \t\tif (!cached)\n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \n \t\thit = grep_cache(&opt, &pathspec, cached);\n \t} else {\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex 09d95111b3..e1a22b41b9 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -704,7 +704,7 @@ int cmd_ls_files(int argc,\n \t\texc_given = 1;\n \n \tif (require_work_tree && !is_inside_work_tree(repo))\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(repo);\n \n \tif (recurse_submodules &&\n \t    (show_deleted || show_others || show_unmerged ||\ndiff --git a/builtin/read-tree.c b/builtin/read-tree.c\nindex 460b21e40a..999a82ecdf 100644\n--- a/builtin/read-tree.c\n+++ b/builtin/read-tree.c\n@@ -229,7 +229,7 @@ int cmd_read_tree(int argc,\n \t\topts.preserve_ignored = 0;\n \t/* otherwise, opts.preserve_ignored is irrelevant */\n \tif (opts.merge && !opts.index_only)\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \tif (opts.skip_sparse_checkout)\n \t\tensure_full_index(the_repository->index);\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex 11f57605b5..3be6bd0121 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -468,7 +468,7 @@ int cmd_reset(int argc,\n \t\ttrace2_cmd_mode(reset_type_names[reset_type]);\n \n \tif (reset_type != SOFT && (reset_type != MIXED || repo_get_work_tree(the_repository)))\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \tif (reset_type == MIXED && is_bare_repository())\n \t\tdie(_(\"%s reset is not allowed in a bare repository\"),\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex 05d89e98c3..081d0bc375 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -296,7 +296,7 @@ int cmd_rm(int argc,\n \t\tdie(_(\"No pathspec was given. Which files should I remove?\"));\n \n \tif (!index_only)\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \tprepare_repo_settings(the_repository);\n \tthe_repository->settings.command_requires_full_index = 0;\ndiff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c\nindex 2af50fb2f9..d89acbeb53 100644\n--- a/builtin/sparse-checkout.c\n+++ b/builtin/sparse-checkout.c\n@@ -63,7 +63,7 @@ static int sparse_checkout_list(int argc, const char **argv, const char *prefix,\n \tint res;\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"this worktree is not sparse\"));\n \n@@ -229,7 +229,7 @@ static int update_working_directory(struct repository *r,\n \to.dst_index = r->index;\n \to.skip_sparse_checkout = 0;\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \n \trepo_hold_locked_index(r, &lock_file, LOCK_DIE_ON_ERROR);\n \n@@ -468,7 +468,7 @@ static int sparse_checkout_init(int argc, const char **argv, const char *prefix,\n \t\tOPT_END(),\n \t};\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \trepo_read_index(repo);\n \n \tinit_opts.cone_mode = -1;\n@@ -802,7 +802,7 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix,\n \tint ret;\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"no sparse-checkout to add to\"));\n \n@@ -856,7 +856,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix,\n \tstruct strvec patterns = STRVEC_INIT;\n \tint ret;\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \trepo_read_index(repo);\n \n \tset_opts.cone_mode = -1;\n@@ -912,7 +912,7 @@ static int sparse_checkout_reapply(int argc, const char **argv,\n \t};\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"must be in a sparse-checkout to reapply sparsity patterns\"));\n \n@@ -975,7 +975,7 @@ static int sparse_checkout_clean(int argc, const char **argv,\n \t\tOPT_END(),\n \t};\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"must be in a sparse-checkout to clean directories\"));\n \tif (!core_sparse_checkout_cone)\n@@ -1053,7 +1053,7 @@ static int sparse_checkout_disable(int argc, const char **argv,\n \t * forcibly return to a dense checkout regardless of initial state.\n \t */\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \targc = parse_options(argc, argv, prefix,\n \t\t\t     builtin_sparse_checkout_disable_options,\n \t\t\t     builtin_sparse_checkout_disable_usage, 0);\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 2f589e3b37..1cc82a134d 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1250,7 +1250,7 @@ static int compute_summary_module_list(struct object_id *head_oid,\n \n \tif (!info->cached) {\n \t\tif (diff_cmd == DIFF_INDEX)\n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \t\tif (repo_read_index_preload(the_repository, &rev.diffopt.pathspec, 0) < 0) {\n \t\t\tperror(\"repo_read_index_preload\");\n \t\t\tret = -1;\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 7434112b8e..d6dabacfd1 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -732,7 +732,7 @@ struct refresh_params {\n \n static int refresh(struct refresh_params *o, unsigned int flag)\n {\n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \trepo_read_index(the_repository);\n \t*o->has_errors |= refresh_index(the_repository->index, o->flags | flag, NULL,\n \t\t\t\t\tNULL, NULL);\n@@ -901,7 +901,7 @@ static enum parse_opt_result reupdate_callback(\n \tBUG_ON_OPT_ARG(arg);\n \n \t/* consume remaining arguments. */\n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \t*has_errors = do_reupdate(ctx->argv + 1, prefix);\n \tif (*has_errors)\n \t\tthe_repository->index->cache_changed = 0;\n@@ -1157,7 +1157,7 @@ int cmd_update_index(int argc,\n \t\t\t\ttransaction = NULL;\n \t\t\t}\n \n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \t\t\tp = prefix_path(the_repository, prefix, prefix_length, path);\n \t\t\tupdate_one(p);\n \t\t\tif (set_executable_bit)\n@@ -1199,7 +1199,7 @@ int cmd_update_index(int argc,\n \t\tstruct strbuf buf = STRBUF_INIT;\n \t\tstruct strbuf unquoted = STRBUF_INIT;\n \n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\twhile (getline_fn(&buf, stdin) != EOF) {\n \t\t\tchar *p;\n \t\t\tif (!nul_term_line && buf.buf[0] == '\"') {\n@@ -1253,7 +1253,7 @@ int cmd_update_index(int argc,\n \t\treport(_(\"Untracked cache disabled\"));\n \t\tbreak;\n \tcase UC_TEST:\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\treturn !test_if_untracked_cache_is_supported();\n \tcase UC_ENABLE:\n \tcase UC_FORCE:\ndiff --git a/git.c b/git.c\nindex 2b212e6675..c146eaa20b 100644\n--- a/git.c\n+++ b/git.c\n@@ -497,7 +497,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct\n \tcommit_pager_choice();\n \n \tif (!help && p->option & NEED_WORK_TREE)\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \ttrace_argv_printf(argv, \"trace: built-in: git\");\n \ttrace2_cmd_name(p->cmd);\ndiff --git a/repository.h b/repository.h\nindex 078059a6e0..abeef3129e 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -113,6 +113,7 @@ struct repository {\n \t * A NULL value indicates that there is no working directory.\n \t */\n \tchar *worktree;\n+\tbool worktree_config_is_bogus;\n \n \t/*\n \t * Path from the root of the top-level superproject down to this\ndiff --git a/setup.c b/setup.c\nindex dca32addae..80dd94b261 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -26,7 +26,6 @@\n #include \"trace2.h\"\n #include \"worktree.h\"\n \n-static int work_tree_config_is_bogus;\n enum allowed_bare_repo {\n \tALLOWED_BARE_REPO_EXPLICIT = 0,\n \tALLOWED_BARE_REPO_ALL,\n@@ -485,18 +484,14 @@ int is_inside_work_tree(struct repository *repo)\n \treturn is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n }\n \n-void setup_work_tree(void)\n+void setup_work_tree(struct repository *repo)\n {\n \tconst char *work_tree;\n-\tstatic int initialized = 0;\n \n-\tif (initialized)\n-\t\treturn;\n-\n-\tif (work_tree_config_is_bogus)\n+\tif (repo->worktree_config_is_bogus)\n \t\tdie(_(\"unable to set up work tree using invalid config\"));\n \n-\twork_tree = repo_get_work_tree(the_repository);\n+\twork_tree = repo_get_work_tree(repo);\n \tif (!work_tree || chdir_notify(work_tree))\n \t\tdie(_(\"this operation must be run in a work tree\"));\n \n@@ -506,8 +501,6 @@ void setup_work_tree(void)\n \t */\n \tif (getenv(GIT_WORK_TREE_ENVIRONMENT))\n \t\tsetenv(GIT_WORK_TREE_ENVIRONMENT, \".\", 1);\n-\n-\tinitialized = 1;\n }\n \n static void setup_original_cwd(struct repository *repo)\n@@ -1155,7 +1148,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t\tif (git_work_tree_cfg) {\n \t\t\t/* #22.2, #30 */\n \t\t\twarning(\"core.bare and core.worktree do not make sense\");\n-\t\t\twork_tree_config_is_bogus = 1;\n+\t\t\trepo->worktree_config_is_bogus = true;\n \t\t}\n \n \t\t/* #18, #26 */\ndiff --git a/setup.h b/setup.h\nindex d0cfdfd44a..8fed365637 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -56,7 +56,7 @@ const char *resolve_gitdir_gently(const char *suspect, int *return_error_code);\n void die_upon_dubious_ownership(const char *gitfile, const char *worktree,\n \t\t\t\tconst char *gitdir);\n \n-void setup_work_tree(void);\n+void setup_work_tree(struct repository *repo);\n \n /*\n  * discover_git_directory_reason() is similar to discover_git_directory(),\ndiff --git a/t/helper/test-subprocess.c b/t/helper/test-subprocess.c\nindex c344f1694d..8a070e47cd 100644\n--- a/t/helper/test-subprocess.c\n+++ b/t/helper/test-subprocess.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"run-command.h\"\n #include \"setup.h\"\n@@ -11,7 +13,7 @@ int cmd__subprocess(int argc, const char **argv)\n \tif (nogit)\n \t\tdie(\"No git repo found\");\n \tif (argc > 1 && !strcmp(argv[1], \"--setup-work-tree\")) {\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\targv++;\n \t}\n \tcp.git_cmd = 1;\ndiff --git a/wt-status.c b/wt-status.c\nindex 479ccc3304..6cc77ba68c 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1206,7 +1206,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)\n \t\tstatus_printf_ln(s, c,\n \t\t\t\"--------------------------------------------------\");\n \t\tstatus_printf_ln(s, c, _(\"Changes not staged for commit:\"));\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\trev.diffopt.a_prefix = \"i/\";\n \t\trev.diffopt.b_prefix = \"w/\";\n \t\trun_diff_files(&rev, 0);\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541937","messageId":"20260420-pks-setup-wo-the-repository-v1-10-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 10/18] setup: stop using `the_repository` in `set_git_work_tree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:40Z","receivedAt":"2026-04-20T08:23:16Z","isPatch":true,"body":"Stop using `the_repository` in `set_git_work_tree()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSimilar as with the preceding commit, we track whether the worktree has\nbeen initialized already via a global variable so that we can die in\ncase the repository is re-initialized with a different worktree path.\nStore this info in the `struct repository` instead so that we correctly\nhandle this per repository.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c   |  2 +-\n builtin/init-db.c |  6 +++---\n repository.h      |  1 +\n setup.c           | 24 +++++++++++-------------\n setup.h           |  2 +-\n 5 files changed, 17 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 91b9a105a4..16cd7b029b 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1114,7 +1114,7 @@ int cmd_clone(int argc,\n \t\t\tdie_errno(_(\"could not create work tree dir '%s'\"),\n \t\t\t\t  work_tree);\n \t\tjunk_work_tree = work_tree;\n-\t\tset_git_work_tree(work_tree);\n+\t\tset_git_work_tree(the_repository, work_tree);\n \t}\n \n \tif (real_git_dir) {\ndiff --git a/builtin/init-db.c b/builtin/init-db.c\nindex bb853e69f5..e626b0d8b7 100644\n--- a/builtin/init-db.c\n+++ b/builtin/init-db.c\n@@ -237,9 +237,9 @@ int cmd_init_db(int argc,\n \t\tif (!git_work_tree_cfg)\n \t\t\tgit_work_tree_cfg = xgetcwd();\n \t\tif (work_tree)\n-\t\t\tset_git_work_tree(work_tree);\n+\t\t\tset_git_work_tree(the_repository, work_tree);\n \t\telse\n-\t\t\tset_git_work_tree(git_work_tree_cfg);\n+\t\t\tset_git_work_tree(the_repository, git_work_tree_cfg);\n \t\tif (access(repo_get_work_tree(the_repository), X_OK))\n \t\t\tdie_errno (_(\"Cannot access work tree '%s'\"),\n \t\t\t\t   repo_get_work_tree(the_repository));\n@@ -248,7 +248,7 @@ int cmd_init_db(int argc,\n \t\tif (real_git_dir)\n \t\t\tdie(_(\"--separate-git-dir incompatible with bare repository\"));\n \t\tif (work_tree)\n-\t\t\tset_git_work_tree(work_tree);\n+\t\t\tset_git_work_tree(the_repository, work_tree);\n \t}\n \n \tflags |= INIT_DB_EXIST_OK;\ndiff --git a/repository.h b/repository.h\nindex abeef3129e..7ae3d34484 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -113,6 +113,7 @@ struct repository {\n \t * A NULL value indicates that there is no working directory.\n \t */\n \tchar *worktree;\n+\tbool worktree_initialized;\n \tbool worktree_config_is_bogus;\n \n \t/*\ndiff --git a/setup.c b/setup.c\nindex 80dd94b261..fa9bb39cdf 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1143,7 +1143,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \n \t/* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */\n \tif (work_tree_env)\n-\t\tset_git_work_tree(work_tree_env);\n+\t\tset_git_work_tree(repo, work_tree_env);\n \telse if (is_bare_repository_cfg > 0) {\n \t\tif (git_work_tree_cfg) {\n \t\t\t/* #22.2, #30 */\n@@ -1158,7 +1158,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t}\n \telse if (git_work_tree_cfg) { /* #6, #14 */\n \t\tif (is_absolute_path(git_work_tree_cfg))\n-\t\t\tset_git_work_tree(git_work_tree_cfg);\n+\t\t\tset_git_work_tree(repo, git_work_tree_cfg);\n \t\telse {\n \t\t\tchar *core_worktree;\n \t\t\tif (chdir(gitdirenv))\n@@ -1168,7 +1168,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t\t\tcore_worktree = xgetcwd();\n \t\t\tif (chdir(cwd->buf))\n \t\t\t\tdie_errno(_(\"cannot come back to cwd\"));\n-\t\t\tset_git_work_tree(core_worktree);\n+\t\t\tset_git_work_tree(repo, core_worktree);\n \t\t\tfree(core_worktree);\n \t\t}\n \t}\n@@ -1179,7 +1179,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t\treturn NULL;\n \t}\n \telse /* #2, #10 */\n-\t\tset_git_work_tree(\".\");\n+\t\tset_git_work_tree(repo, \".\");\n \n \t/* set_git_work_tree() must have been called by now */\n \tworktree = repo_get_work_tree(repo);\n@@ -1239,7 +1239,7 @@ static const char *setup_discovered_git_dir(struct repository *repo,\n \t}\n \n \t/* #0, #1, #5, #8, #9, #12, #13 */\n-\tset_git_work_tree(\".\");\n+\tset_git_work_tree(repo, \".\");\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n \t\tset_git_dir(repo, gitdir, 0);\n \tif (offset >= cwd->len)\n@@ -1830,29 +1830,27 @@ const char *enter_repo(struct repository *repo, const char *path, unsigned flags\n \treturn NULL;\n }\n \n-static int git_work_tree_initialized;\n-\n /*\n  * Note.  This works only before you used a work tree.  This was added\n  * primarily to support git-clone to work in a new repository it just\n  * created, and is not meant to flip between different work trees.\n  */\n-void set_git_work_tree(const char *new_work_tree)\n+void set_git_work_tree(struct repository *repo, const char *new_work_tree)\n {\n-\tif (git_work_tree_initialized) {\n+\tif (repo->worktree_initialized) {\n \t\tstruct strbuf realpath = STRBUF_INIT;\n \n \t\tstrbuf_realpath(&realpath, new_work_tree, 1);\n \t\tnew_work_tree = realpath.buf;\n-\t\tif (strcmp(new_work_tree, the_repository->worktree))\n+\t\tif (strcmp(new_work_tree, repo->worktree))\n \t\t\tdie(\"internal error: work tree has already been set\\n\"\n \t\t\t    \"Current worktree: %s\\nNew worktree: %s\",\n-\t\t\t    the_repository->worktree, new_work_tree);\n+\t\t\t    repo->worktree, new_work_tree);\n \t\tstrbuf_release(&realpath);\n \t\treturn;\n \t}\n-\tgit_work_tree_initialized = 1;\n-\trepo_set_worktree(the_repository, new_work_tree);\n+\trepo->worktree_initialized = true;\n+\trepo_set_worktree(repo, new_work_tree);\n }\n \n const char *setup_git_directory_gently(int *nongit_ok)\ndiff --git a/setup.h b/setup.h\nindex 8fed365637..1a37089fa0 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -96,7 +96,7 @@ static inline int discover_git_directory(struct strbuf *commondir,\n \treturn 0;\n }\n \n-void set_git_work_tree(const char *tree);\n+void set_git_work_tree(struct repository *repo, const char *tree);\n \n /* Flags that can be passed to `enter_repo()`. */\n enum {\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541939","messageId":"20260420-pks-setup-wo-the-repository-v1-11-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 11/18] setup: stop using `the_repository` in `setup_git_env()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:41Z","receivedAt":"2026-04-20T08:23:20Z","isPatch":true,"body":"Stop using `the_repository` in `setup_git_env()` and instead accept the\nrepository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nFurthermore, the function is never used outside of \"setup.c\". Drop the\ndeclaration in \"environment.h\" and make it static.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n environment.h | 2 --\n setup.c       | 6 +++---\n 2 files changed, 3 insertions(+), 5 deletions(-)\n\ndiff --git a/environment.h b/environment.h\nindex 123a71cdc8..9eb97b3869 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -147,8 +147,6 @@ void repo_config_values_init(struct repo_config_values *cfg);\n  * Please do not add new global config variables here.\n  */\n # ifdef USE_THE_REPOSITORY_VARIABLE\n-void setup_git_env(const char *git_dir);\n-\n /*\n  * Returns true iff we have a configured git repository (either via\n  * setup_git_directory, or in the environment via $GIT_DIR).\ndiff --git a/setup.c b/setup.c\nindex fa9bb39cdf..24f230567c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1065,9 +1065,9 @@ static void setup_git_env_internal(struct repository *repo,\n \t\tfetch_if_missing = 0;\n }\n \n-void setup_git_env(const char *git_dir)\n+static void setup_git_env(struct repository *repo, const char *git_dir)\n {\n-\tsetup_git_env_internal(the_repository, git_dir, false);\n+\tsetup_git_env_internal(repo, git_dir, false);\n }\n \n static void set_git_dir_1(struct repository *repo, const char *path, bool skip_initializing_odb)\n@@ -1979,7 +1979,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\t\tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n \t\t\tif (!gitdir)\n \t\t\t\tgitdir = DEFAULT_GIT_DIR_ENVIRONMENT;\n-\t\t\tsetup_git_env(gitdir);\n+\t\t\tsetup_git_env(the_repository, gitdir);\n \t\t}\n \t\tif (startup_info->have_repository) {\n \t\t\trepo_set_hash_algo(the_repository, repo_fmt.hash_algo);\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541940","messageId":"20260420-pks-setup-wo-the-repository-v1-12-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 12/18] setup: stop using `the_repository` in `setup_git_directory_gently()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:42Z","receivedAt":"2026-04-20T08:23:23Z","isPatch":true,"body":"Stop using `the_repository` in `setup_git_directory_gently()` and\ninstead accept the repository as a parameter. The injection of\n`the_repository` is thus bumped one level higher, where callers now pass\nit in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/check-ref-format.c |  5 ++++-\n builtin/diff.c             |  2 +-\n builtin/hash-object.c      |  2 +-\n builtin/help.c             |  2 +-\n builtin/stripspace.c       |  2 +-\n git.c                      |  6 +++---\n http-fetch.c               |  2 +-\n imap-send.c                |  2 +-\n remote-curl.c              |  4 ++--\n setup.c                    | 36 ++++++++++++++++++------------------\n setup.h                    |  2 +-\n t/helper/test-path-utils.c |  2 +-\n t/helper/test-subprocess.c |  2 +-\n 13 files changed, 36 insertions(+), 33 deletions(-)\n\ndiff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c\nindex 5d80afeec0..e42b0444ea 100644\n--- a/builtin/check-ref-format.c\n+++ b/builtin/check-ref-format.c\n@@ -1,6 +1,9 @@\n /*\n  * GIT - The information manager from hell\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"builtin.h\"\n #include \"refs.h\"\n #include \"setup.h\"\n@@ -41,7 +44,7 @@ static int check_ref_format_branch(const char *arg)\n \tconst char *name;\n \tint nongit;\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \tif (check_branch_ref(&sb, arg) ||\n \t    !skip_prefix(sb.buf, \"refs/heads/\", &name))\n \t\tdie(\"'%s' is not a valid branch name\", arg);\ndiff --git a/builtin/diff.c b/builtin/diff.c\nindex 1ede873ac1..4b46e394ce 100644\n--- a/builtin/diff.c\n+++ b/builtin/diff.c\n@@ -455,7 +455,7 @@ int cmd_diff(int argc,\n \t\t\tbreak;\n \t}\n \n-\tprefix = setup_git_directory_gently(&nongit);\n+\tprefix = setup_git_directory_gently(the_repository, &nongit);\n \n \tif (!nongit) {\n \t\tprepare_repo_settings(the_repository);\ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex 5d900a6b8c..d7905bedc2 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -102,7 +102,7 @@ int cmd_hash_object(int argc,\n \tif (flags & INDEX_WRITE_OBJECT)\n \t\tprefix = setup_git_directory();\n \telse\n-\t\tprefix = setup_git_directory_gently(&nongit);\n+\t\tprefix = setup_git_directory_gently(the_repository, &nongit);\n \n \tif (nongit && !the_hash_algo)\n \t\trepo_set_hash_algo(the_repository, GIT_HASH_DEFAULT);\ndiff --git a/builtin/help.c b/builtin/help.c\nindex c0aece4da3..a140339999 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -740,7 +740,7 @@ int cmd_help(int argc,\n \t\treturn 0;\n \t}\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \trepo_config(the_repository, git_help_config, NULL);\n \n \tif (parsed_help_format != HELP_FORMAT_NONE)\ndiff --git a/builtin/stripspace.c b/builtin/stripspace.c\nindex 4a566cbc5d..18705f1a5b 100644\n--- a/builtin/stripspace.c\n+++ b/builtin/stripspace.c\n@@ -54,7 +54,7 @@ int cmd_stripspace(int argc,\n \t\tusage_with_options(stripspace_usage, options);\n \n \tif (mode == STRIP_COMMENTS || mode == COMMENT_LINES) {\n-\t\tsetup_git_directory_gently(&nongit);\n+\t\tsetup_git_directory_gently(the_repository, &nongit);\n \t\trepo_config(the_repository, git_default_config, NULL);\n \t}\n \ndiff --git a/git.c b/git.c\nindex c146eaa20b..0df36c9b9d 100644\n--- a/git.c\n+++ b/git.c\n@@ -84,7 +84,7 @@ static int list_cmds(const char *spec)\n \t* Set up the repository so we can pick up any repo-level config (like\n \t* completion.commands).\n \t*/\n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \n \twhile (*spec) {\n \t\tconst char *sep = strchrnul(spec, ',');\n@@ -386,7 +386,7 @@ static int handle_alias(struct strvec *args, struct string_list *expanded_aliase\n \t\t\tint nongit_ok;\n \n \t\t\t/* Aliases expect GIT_PREFIX, GIT_DIR etc to be set */\n-\t\t\tsetup_git_directory_gently(&nongit_ok);\n+\t\t\tsetup_git_directory_gently(the_repository, &nongit_ok);\n \n \t\t\tcommit_pager_choice();\n \n@@ -480,7 +480,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct\n \t\tprefix = setup_git_directory();\n \t\tno_repo = 0;\n \t} else if (run_setup & RUN_SETUP_GENTLY) {\n-\t\tprefix = setup_git_directory_gently(&no_repo);\n+\t\tprefix = setup_git_directory_gently(the_repository, &no_repo);\n \t} else {\n \t\tprefix = NULL;\n \t}\ndiff --git a/http-fetch.c b/http-fetch.c\nindex 1922e23fcd..f9b6ecb061 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -109,7 +109,7 @@ int cmd_main(int argc, const char **argv)\n \tstruct strvec index_pack_args = STRVEC_INIT;\n \tint ret;\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \n \twhile (arg < argc && argv[arg][0] == '-') {\n \t\tconst char *p;\ndiff --git a/imap-send.c b/imap-send.c\nindex af02c6a689..cfd6a5120c 100644\n--- a/imap-send.c\n+++ b/imap-send.c\n@@ -1799,7 +1799,7 @@ int cmd_main(int argc, const char **argv)\n \tint nongit_ok;\n \tint ret;\n \n-\tsetup_git_directory_gently(&nongit_ok);\n+\tsetup_git_directory_gently(the_repository, &nongit_ok);\n \trepo_config(the_repository, git_imap_config, &server);\n \n \targc = parse_options(argc, (const char **)argv, \"\", imap_send_options, imap_send_usage, 0);\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 92e40bb682..454283c43f 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -1546,7 +1546,7 @@ int cmd_main(int argc, const char **argv)\n \tint nongit;\n \tint ret = 1;\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \tif (argc < 2) {\n \t\terror(_(\"remote-curl: usage: git remote-curl <remote> [<url>]\"));\n \t\tgoto cleanup;\n@@ -1587,7 +1587,7 @@ int cmd_main(int argc, const char **argv)\n \t\t\tbreak;\n \t\tif (starts_with(buf.buf, \"fetch \")) {\n \t\t\tif (nongit) {\n-\t\t\t\tsetup_git_directory_gently(&nongit);\n+\t\t\t\tsetup_git_directory_gently(the_repository, &nongit);\n \t\t\t\tif (nongit)\n \t\t\t\t\tdie(_(\"remote-curl: fetch attempted without a local repo\"));\n \t\t\t}\ndiff --git a/setup.c b/setup.c\nindex 24f230567c..7242a18740 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1853,7 +1853,7 @@ void set_git_work_tree(struct repository *repo, const char *new_work_tree)\n \trepo_set_worktree(repo, new_work_tree);\n }\n \n-const char *setup_git_directory_gently(int *nongit_ok)\n+const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)\n {\n \tstatic struct strbuf cwd = STRBUF_INIT;\n \tstruct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT, report = STRBUF_INIT;\n@@ -1868,7 +1868,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t * configuration (including the per-repo config file that we\n \t * ignored previously).\n \t */\n-\trepo_config_clear(the_repository);\n+\trepo_config_clear(repo);\n \n \t/*\n \t * Let's assume that we are in a git repository.\n@@ -1884,18 +1884,18 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \n \tswitch (setup_git_directory_gently_1(&dir, &gitdir, &report, 1)) {\n \tcase GIT_DIR_EXPLICIT:\n-\t\tprefix = setup_explicit_git_dir(the_repository, gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_explicit_git_dir(repo, gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_DISCOVERED:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_discovered_git_dir(the_repository, gitdir.buf, &cwd, dir.len,\n+\t\tprefix = setup_discovered_git_dir(repo, gitdir.buf, &cwd, dir.len,\n \t\t\t\t\t\t  &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_BARE:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_bare_git_dir(the_repository, &cwd, dir.len, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_bare_git_dir(repo, &cwd, dir.len, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_HIT_CEILING:\n \t\tif (!nongit_ok)\n@@ -1975,30 +1975,30 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t    startup_info->have_repository ||\n \t    /* GIT_DIR_EXPLICIT */\n \t    getenv(GIT_DIR_ENVIRONMENT)) {\n-\t\tif (!the_repository->gitdir) {\n+\t\tif (!repo->gitdir) {\n \t\t\tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n \t\t\tif (!gitdir)\n \t\t\t\tgitdir = DEFAULT_GIT_DIR_ENVIRONMENT;\n-\t\t\tsetup_git_env(the_repository, gitdir);\n+\t\t\tsetup_git_env(repo, gitdir);\n \t\t}\n \t\tif (startup_info->have_repository) {\n-\t\t\trepo_set_hash_algo(the_repository, repo_fmt.hash_algo);\n-\t\t\trepo_set_compat_hash_algo(the_repository,\n+\t\t\trepo_set_hash_algo(repo, repo_fmt.hash_algo);\n+\t\t\trepo_set_compat_hash_algo(repo,\n \t\t\t\t\t\t  repo_fmt.compat_hash_algo);\n-\t\t\trepo_set_ref_storage_format(the_repository,\n+\t\t\trepo_set_ref_storage_format(repo,\n \t\t\t\t\t\t    repo_fmt.ref_storage_format,\n \t\t\t\t\t\t    repo_fmt.ref_storage_payload);\n-\t\t\tthe_repository->repository_format_worktree_config =\n+\t\t\trepo->repository_format_worktree_config =\n \t\t\t\trepo_fmt.worktree_config;\n-\t\t\tthe_repository->repository_format_relative_worktrees =\n+\t\t\trepo->repository_format_relative_worktrees =\n \t\t\t\trepo_fmt.relative_worktrees;\n-\t\t\tthe_repository->repository_format_submodule_path_cfg =\n+\t\t\trepo->repository_format_submodule_path_cfg =\n \t\t\t\trepo_fmt.submodule_path_cfg;\n \t\t\t/* take ownership of repo_fmt.partial_clone */\n-\t\t\tthe_repository->repository_format_partial_clone =\n+\t\t\trepo->repository_format_partial_clone =\n \t\t\t\trepo_fmt.partial_clone;\n \t\t\trepo_fmt.partial_clone = NULL;\n-\t\t\tthe_repository->repository_format_precious_objects =\n+\t\t\trepo->repository_format_precious_objects =\n \t\t\t\trepo_fmt.precious_objects;\n \t\t}\n \t}\n@@ -2031,13 +2031,13 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\tformat = ref_storage_format_by_name(backend);\n \t\tif (format == REF_STORAGE_FORMAT_UNKNOWN)\n \t\t\tdie(_(\"unknown ref storage format: '%s'\"), backend);\n-\t\trepo_set_ref_storage_format(the_repository, format, payload);\n+\t\trepo_set_ref_storage_format(repo, format, payload);\n \n \t\tfree(backend);\n \t\tfree(payload);\n \t}\n \n-\tsetup_original_cwd(the_repository);\n+\tsetup_original_cwd(repo);\n \n \tstrbuf_release(&dir);\n \tstrbuf_release(&gitdir);\n@@ -2129,7 +2129,7 @@ void check_repository_format(struct repository_format *fmt)\n  */\n const char *setup_git_directory(void)\n {\n-\treturn setup_git_directory_gently(NULL);\n+\treturn setup_git_directory_gently(the_repository, NULL);\n }\n \n const char *resolve_gitdir_gently(const char *suspect, int *return_error_code)\ndiff --git a/setup.h b/setup.h\nindex 1a37089fa0..18092fbf16 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -136,7 +136,7 @@ enum {\n  */\n const char *enter_repo(struct repository *repo, const char *path, unsigned flags);\n \n-const char *setup_git_directory_gently(int *);\n+const char *setup_git_directory_gently(struct repository *repo, int *);\n const char *setup_git_directory(void);\n char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path);\n char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\ndiff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c\nindex 163fdeefb0..15eb44485c 100644\n--- a/t/helper/test-path-utils.c\n+++ b/t/helper/test-path-utils.c\n@@ -377,7 +377,7 @@ int cmd__path_utils(int argc, const char **argv)\n \t\tconst char *prefix = argv[2];\n \t\tint prefix_len = strlen(prefix);\n \t\tint nongit_ok;\n-\t\tsetup_git_directory_gently(&nongit_ok);\n+\t\tsetup_git_directory_gently(the_repository, &nongit_ok);\n \t\twhile (argc > 3) {\n \t\t\tchar *pfx = prefix_path(the_repository, prefix, prefix_len, argv[3]);\n \ndiff --git a/t/helper/test-subprocess.c b/t/helper/test-subprocess.c\nindex 8a070e47cd..a8194d24b3 100644\n--- a/t/helper/test-subprocess.c\n+++ b/t/helper/test-subprocess.c\n@@ -9,7 +9,7 @@ int cmd__subprocess(int argc, const char **argv)\n \tstruct child_process cp = CHILD_PROCESS_INIT;\n \tint nogit = 0;\n \n-\tsetup_git_directory_gently(&nogit);\n+\tsetup_git_directory_gently(the_repository, &nogit);\n \tif (nogit)\n \t\tdie(\"No git repo found\");\n \tif (argc > 1 && !strcmp(argv[1], \"--setup-work-tree\")) {\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541941","messageId":"20260420-pks-setup-wo-the-repository-v1-13-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 13/18] setup: stop using `the_repository` in `setup_git_directory()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:43Z","receivedAt":"2026-04-20T08:23:25Z","isPatch":true,"body":"Stop using `the_repository` in `setup_git_directory()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n archive.c                                    |  2 +-\n builtin/grep.c                               |  2 +-\n builtin/hash-object.c                        |  2 +-\n builtin/merge-file.c                         |  2 +-\n builtin/rev-parse.c                          |  4 ++--\n git.c                                        |  2 +-\n http-push.c                                  |  2 +-\n scalar.c                                     |  4 ++--\n setup.c                                      |  4 ++--\n setup.h                                      |  2 +-\n t/helper/test-advise.c                       |  2 +-\n t/helper/test-bitmap.c                       |  2 +-\n t/helper/test-bloom.c                        |  2 +-\n t/helper/test-cache-tree.c                   |  2 +-\n t/helper/test-config.c                       |  2 +-\n t/helper/test-dump-cache-tree.c              |  2 +-\n t/helper/test-dump-fsmonitor.c               |  2 +-\n t/helper/test-dump-split-index.c             |  2 +-\n t/helper/test-dump-untracked-cache.c         |  2 +-\n t/helper/test-find-pack.c                    |  2 +-\n t/helper/test-fsmonitor-client.c             |  2 +-\n t/helper/test-lazy-init-name-hash.c          |  2 +-\n t/helper/test-match-trees.c                  |  2 +-\n t/helper/test-pack-deltas.c                  |  2 +-\n t/helper/test-pack-mtimes.c                  |  2 +-\n t/helper/test-partial-clone.c                |  4 +++-\n t/helper/test-path-walk.c                    |  2 +-\n t/helper/test-reach.c                        |  2 +-\n t/helper/test-read-cache.c                   |  2 +-\n t/helper/test-read-graph.c                   |  2 +-\n t/helper/test-read-midx.c                    |  2 +-\n t/helper/test-ref-store.c                    |  2 +-\n t/helper/test-revision-walking.c             |  2 +-\n t/helper/test-scrap-cache-tree.c             |  2 +-\n t/helper/test-serve-v2.c                     |  2 +-\n t/helper/test-submodule-config.c             |  2 +-\n t/helper/test-submodule-nested-repo-config.c |  2 +-\n t/helper/test-submodule.c                    | 10 +++++-----\n t/helper/test-userdiff.c                     |  2 +-\n t/helper/test-write-cache.c                  |  2 +-\n 40 files changed, 49 insertions(+), 47 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex fcd474c682..51229107a5 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -786,7 +786,7 @@ int write_archive(int argc, const char **argv, const char *prefix,\n \t\t * die ourselves; but its error message will be more specific\n \t\t * than what we could write here.\n \t\t */\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \t}\n \n \tparse_treeish_arg(argv, &args, remote);\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 679f8b567a..560133feb8 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1064,7 +1064,7 @@ int cmd_grep(int argc,\n \t\t\tuse_index = 0;\n \t\telse\n \t\t\t/* die the same way as if we did it at the beginning */\n-\t\t\tsetup_git_directory();\n+\t\t\tsetup_git_directory(the_repository);\n \t}\n \t/* Ignore --recurse-submodules if --no-index is given or implied */\n \tif (!use_index)\ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex d7905bedc2..f306b0643f 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -100,7 +100,7 @@ int cmd_hash_object(int argc,\n \t\t\t     hash_object_usage, 0);\n \n \tif (flags & INDEX_WRITE_OBJECT)\n-\t\tprefix = setup_git_directory();\n+\t\tprefix = setup_git_directory(the_repository);\n \telse\n \t\tprefix = setup_git_directory_gently(the_repository, &nongit);\n \ndiff --git a/builtin/merge-file.c b/builtin/merge-file.c\nindex 59a9792208..8fa5765239 100644\n--- a/builtin/merge-file.c\n+++ b/builtin/merge-file.c\n@@ -110,7 +110,7 @@ int cmd_merge_file(int argc,\n \n \tif (!repo && object_id)\n \t\t/* emit the correct \"not a git repo\" error in this case */\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \n \tfor (i = 0; i < 3; i++) {\n \t\tchar *fname;\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex d7c6400ddc..426a3c5676 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -739,7 +739,7 @@ int cmd_rev_parse(int argc,\n \n \t/* No options; just report on whether we're in a git repo or not. */\n \tif (argc == 1) {\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \t\trepo_config(the_repository, git_default_config, NULL);\n \t\treturn 0;\n \t}\n@@ -774,7 +774,7 @@ int cmd_rev_parse(int argc,\n \n \t\t/* The rest of the options require a git repository. */\n \t\tif (!did_repo_setup) {\n-\t\t\tprefix = setup_git_directory();\n+\t\t\tprefix = setup_git_directory(the_repository);\n \t\t\trepo_config(the_repository, git_default_config, NULL);\n \t\t\tdid_repo_setup = 1;\n \ndiff --git a/git.c b/git.c\nindex 0df36c9b9d..78bd607e2f 100644\n--- a/git.c\n+++ b/git.c\n@@ -477,7 +477,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct\n \t\trun_setup = RUN_SETUP_GENTLY;\n \n \tif (run_setup & RUN_SETUP) {\n-\t\tprefix = setup_git_directory();\n+\t\tprefix = setup_git_directory(the_repository);\n \t\tno_repo = 0;\n \t} else if (run_setup & RUN_SETUP_GENTLY) {\n \t\tprefix = setup_git_directory_gently(the_repository, &no_repo);\ndiff --git a/http-push.c b/http-push.c\nindex 9ae6062198..ee66813012 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1788,7 +1788,7 @@ int cmd_main(int argc, const char **argv)\n \tif (delete_branch && rs.nr != 1)\n \t\tdie(\"You must specify only one branch name when deleting a remote branch\");\n \n-\tgitdir = setup_git_directory();\n+\tgitdir = setup_git_directory(the_repository);\n \n \tmemset(remote_dir_exists, -1, 256);\n \ndiff --git a/scalar.c b/scalar.c\nindex 4efb6ac36d..a80d8ee3ff 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -58,7 +58,7 @@ static void setup_enlistment_directory(int argc, const char **argv,\n \t}\n \tstrbuf_setlen(&path, len);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (!the_repository->worktree)\n \t\tdie(_(\"Scalar enlistments require a worktree\"));\n@@ -514,7 +514,7 @@ static int cmd_clone(int argc, const char **argv)\n \t\tgoto cleanup;\n \t}\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \t/* common-main already logs `argv` */\n \ttrace2_def_repo(the_repository);\ndiff --git a/setup.c b/setup.c\nindex 7242a18740..4d4b43ab28 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2127,9 +2127,9 @@ void check_repository_format(struct repository_format *fmt)\n  * directory is not a strict subdirectory of the work tree root. The\n  * prefix always ends with a '/' character.\n  */\n-const char *setup_git_directory(void)\n+const char *setup_git_directory(struct repository *repo)\n {\n-\treturn setup_git_directory_gently(the_repository, NULL);\n+\treturn setup_git_directory_gently(repo, NULL);\n }\n \n const char *resolve_gitdir_gently(const char *suspect, int *return_error_code)\ndiff --git a/setup.h b/setup.h\nindex 18092fbf16..b779661ce7 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -137,7 +137,7 @@ enum {\n const char *enter_repo(struct repository *repo, const char *path, unsigned flags);\n \n const char *setup_git_directory_gently(struct repository *repo, int *);\n-const char *setup_git_directory(void);\n+const char *setup_git_directory(struct repository *repo);\n char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path);\n char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\n \ndiff --git a/t/helper/test-advise.c b/t/helper/test-advise.c\nindex 81ed93a05c..8f9db2693e 100644\n--- a/t/helper/test-advise.c\n+++ b/t/helper/test-advise.c\n@@ -11,7 +11,7 @@ int cmd__advise_if_enabled(int argc, const char **argv)\n \tif (argc != 2)\n \t\tdie(\"usage: %s <advice>\", argv[0]);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_config(the_repository, git_default_config, NULL);\n \n \t/*\ndiff --git a/t/helper/test-bitmap.c b/t/helper/test-bitmap.c\nindex 16a01669e4..d9b9a83b8f 100644\n--- a/t/helper/test-bitmap.c\n+++ b/t/helper/test-bitmap.c\n@@ -37,7 +37,7 @@ static int bitmap_dump_pseudo_merge_objects(uint32_t n)\n \n int cmd__bitmap(int argc, const char **argv)\n {\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 2 && !strcmp(argv[1], \"list-commits\"))\n \t\treturn bitmap_list_commits();\ndiff --git a/t/helper/test-bloom.c b/t/helper/test-bloom.c\nindex 3283544bd3..0c65befbf0 100644\n--- a/t/helper/test-bloom.c\n+++ b/t/helper/test-bloom.c\n@@ -52,7 +52,7 @@ static const char *const bloom_usage = \"\\n\"\n \n int cmd__bloom(int argc, const char **argv)\n {\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc < 2)\n \t\tusage(bloom_usage);\ndiff --git a/t/helper/test-cache-tree.c b/t/helper/test-cache-tree.c\nindex ff61d0ca7e..d42e260092 100644\n--- a/t/helper/test-cache-tree.c\n+++ b/t/helper/test-cache-tree.c\n@@ -33,7 +33,7 @@ int cmd__cache_tree(int argc, const char **argv)\n \t\tOPT_END()\n \t};\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \targc = parse_options(argc, argv, NULL, options, test_cache_tree_usage, 0);\n \ndiff --git a/t/helper/test-config.c b/t/helper/test-config.c\nindex 9f8cca7c48..cfb3f4b111 100644\n--- a/t/helper/test-config.c\n+++ b/t/helper/test-config.c\n@@ -102,7 +102,7 @@ int cmd__config(int argc, const char **argv)\n \t\treturn 0;\n \t}\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tgit_configset_init(&cs);\n \ndiff --git a/t/helper/test-dump-cache-tree.c b/t/helper/test-dump-cache-tree.c\nindex 3f0c7d0ed0..ccb41a4239 100644\n--- a/t/helper/test-dump-cache-tree.c\n+++ b/t/helper/test-dump-cache-tree.c\n@@ -66,7 +66,7 @@ int cmd__dump_cache_tree(int ac UNUSED, const char **av UNUSED)\n \tstruct cache_tree *another = cache_tree();\n \tint ret;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tif (repo_read_index(the_repository) < 0)\n \t\tdie(\"unable to read index file\");\n \tistate = *the_repository->index;\ndiff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c\nindex efd017ca35..c991cbbb8a 100644\n--- a/t/helper/test-dump-fsmonitor.c\n+++ b/t/helper/test-dump-fsmonitor.c\n@@ -9,7 +9,7 @@ int cmd__dump_fsmonitor(int ac UNUSED, const char **av UNUSED)\n {\n \tstruct index_state *istate = the_repository->index;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tif (do_read_index(istate, the_repository->index_file, 0) < 0)\n \t\tdie(\"unable to read index file\");\n \tif (!istate->fsmonitor_last_update) {\ndiff --git a/t/helper/test-dump-split-index.c b/t/helper/test-dump-split-index.c\nindex f855a3862c..aae0a40a74 100644\n--- a/t/helper/test-dump-split-index.c\n+++ b/t/helper/test-dump-split-index.c\n@@ -17,7 +17,7 @@ int cmd__dump_split_index(int ac UNUSED, const char **av)\n {\n \tstruct split_index *si;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tdo_read_index(the_repository->index, av[1], 1);\n \tprintf(\"own %s\\n\", oid_to_hex(&the_repository->index->oid));\ndiff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c\nindex 01a109496b..24308bd371 100644\n--- a/t/helper/test-dump-untracked-cache.c\n+++ b/t/helper/test-dump-untracked-cache.c\n@@ -54,7 +54,7 @@ int cmd__dump_untracked_cache(int ac UNUSED, const char **av UNUSED)\n \txsetenv(\"GIT_CONFIG_KEY_0\", \"core.untrackedCache\", 1);\n \txsetenv(\"GIT_CONFIG_VALUE_0\", \"keep\", 1);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tif (repo_read_index(the_repository) < 0)\n \t\tdie(\"unable to read index file\");\n \tuc = the_repository->index->untracked;\ndiff --git a/t/helper/test-find-pack.c b/t/helper/test-find-pack.c\nindex fc4b8a77b3..28d5b1fe09 100644\n--- a/t/helper/test-find-pack.c\n+++ b/t/helper/test-find-pack.c\n@@ -25,7 +25,7 @@ int cmd__find_pack(int argc, const char **argv)\n \tstruct object_id oid;\n \tstruct packed_git *p;\n \tint count = -1, actual_count = 0;\n-\tconst char *prefix = setup_git_directory();\n+\tconst char *prefix = setup_git_directory(the_repository);\n \n \tstruct option options[] = {\n \t\tOPT_INTEGER('c', \"check-count\", &count, \"expected number of packs\"),\ndiff --git a/t/helper/test-fsmonitor-client.c b/t/helper/test-fsmonitor-client.c\nindex 02bfe92e8d..dc1dff23fb 100644\n--- a/t/helper/test-fsmonitor-client.c\n+++ b/t/helper/test-fsmonitor-client.c\n@@ -210,7 +210,7 @@ int cmd__fsmonitor_client(int argc, const char **argv)\n \n \tsubcmd = argv[0];\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (!strcmp(subcmd, \"query\"))\n \t\treturn !!do_send_query(token);\ndiff --git a/t/helper/test-lazy-init-name-hash.c b/t/helper/test-lazy-init-name-hash.c\nindex 40f5df4412..e542985c94 100644\n--- a/t/helper/test-lazy-init-name-hash.c\n+++ b/t/helper/test-lazy-init-name-hash.c\n@@ -211,7 +211,7 @@ int cmd__lazy_init_name_hash(int argc, const char **argv)\n \tconst char *prefix;\n \tuint64_t avg_single, avg_multi;\n \n-\tprefix = setup_git_directory();\n+\tprefix = setup_git_directory(the_repository);\n \n \targc = parse_options(argc, argv, prefix, options, usage, 0);\n \ndiff --git a/t/helper/test-match-trees.c b/t/helper/test-match-trees.c\nindex 2ed064b971..006ce5278e 100644\n--- a/t/helper/test-match-trees.c\n+++ b/t/helper/test-match-trees.c\n@@ -13,7 +13,7 @@ int cmd__match_trees(int ac UNUSED, const char **av)\n \tstruct object_id hash1, hash2, shifted;\n \tstruct tree *one, *two;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (repo_get_oid(the_repository, av[1], &hash1))\n \t\tdie(\"cannot parse %s as an object name\", av[1]);\ndiff --git a/t/helper/test-pack-deltas.c b/t/helper/test-pack-deltas.c\nindex 4981401eaa..c493b75e02 100644\n--- a/t/helper/test-pack-deltas.c\n+++ b/t/helper/test-pack-deltas.c\n@@ -95,7 +95,7 @@ int cmd__pack_deltas(int argc, const char **argv)\n \tif (argc || num_objects < 0)\n \t\tusage_with_options(usage_str, options);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tf = hashfd(the_repository->hash_algo, 1, \"<stdout>\");\n \twrite_pack_header(f, num_objects);\ndiff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c\nindex 7a8ee1de24..b774056799 100644\n--- a/t/helper/test-pack-mtimes.c\n+++ b/t/helper/test-pack-mtimes.c\n@@ -32,7 +32,7 @@ int cmd__pack_mtimes(int argc, const char **argv)\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct packed_git *p;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc != 2)\n \t\tusage(pack_mtimes_usage);\ndiff --git a/t/helper/test-partial-clone.c b/t/helper/test-partial-clone.c\nindex d848800749..a7aab426d0 100644\n--- a/t/helper/test-partial-clone.c\n+++ b/t/helper/test-partial-clone.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"repository.h\"\n@@ -32,7 +34,7 @@ static void object_info(const char *gitdir, const char *oid_hex)\n \n int cmd__partial_clone(int argc, const char **argv)\n {\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc < 4)\n \t\tdie(\"too few arguments\");\ndiff --git a/t/helper/test-path-walk.c b/t/helper/test-path-walk.c\nindex fe63002c2b..69676b15a5 100644\n--- a/t/helper/test-path-walk.c\n+++ b/t/helper/test-path-walk.c\n@@ -89,7 +89,7 @@ int cmd__path_walk(int argc, const char **argv)\n \t\tOPT_END(),\n \t};\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trevs.repo = the_repository;\n \n \targc = parse_options(argc, argv, NULL,\ndiff --git a/t/helper/test-reach.c b/t/helper/test-reach.c\nindex 3131b54a87..5d86a96c17 100644\n--- a/t/helper/test-reach.c\n+++ b/t/helper/test-reach.c\n@@ -39,7 +39,7 @@ int cmd__reach(int ac, const char **av)\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct repository *r = the_repository;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (ac < 2)\n \t\texit(1);\ndiff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c\nindex 9ae71cefb3..6b08ba8f07 100644\n--- a/t/helper/test-read-cache.c\n+++ b/t/helper/test-read-cache.c\n@@ -19,7 +19,7 @@ int cmd__read_cache(int argc, const char **argv)\n \n \tif (argc == 2)\n \t\tcnt = strtol(argv[1], NULL, 0);\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_config(the_repository, git_default_config, NULL);\n \n \tfor (i = 0; i < cnt; i++) {\ndiff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c\nindex 6a5f64e473..9f07b9c25a 100644\n--- a/t/helper/test-read-graph.c\n+++ b/t/helper/test-read-graph.c\n@@ -76,7 +76,7 @@ int cmd__read_graph(int argc, const char **argv)\n \tstruct odb_source *source;\n \tint ret = 0;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tsource = the_repository->objects->sources;\n \n \tprepare_repo_settings(the_repository);\ndiff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c\nindex 388d29e2b5..790000fb26 100644\n--- a/t/helper/test-read-midx.c\n+++ b/t/helper/test-read-midx.c\n@@ -14,7 +14,7 @@\n static struct multi_pack_index *setup_midx(const char *object_dir)\n {\n \tstruct odb_source *source;\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tsource = odb_find_source(the_repository->objects, object_dir);\n \tif (!source)\n \t\tsource = odb_add_to_alternates_memory(the_repository->objects,\ndiff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c\nindex 74edf2029a..3866d0aca4 100644\n--- a/t/helper/test-ref-store.c\n+++ b/t/helper/test-ref-store.c\n@@ -340,7 +340,7 @@ int cmd__ref_store(int argc UNUSED, const char **argv)\n \tconst char *func;\n \tstruct command *cmd;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \targv = get_store(argv + 1, &refs);\n \ndiff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c\nindex 071f5bd1e2..70051eeaf8 100644\n--- a/t/helper/test-revision-walking.c\n+++ b/t/helper/test-revision-walking.c\n@@ -56,7 +56,7 @@ int cmd__revision_walking(int argc, const char **argv)\n \tif (argc < 2)\n \t\treturn 1;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (!strcmp(argv[1], \"run-twice\")) {\n \t\tprintf(\"1st\\n\");\ndiff --git a/t/helper/test-scrap-cache-tree.c b/t/helper/test-scrap-cache-tree.c\nindex 64fff6e9e3..7b5ce501d9 100644\n--- a/t/helper/test-scrap-cache-tree.c\n+++ b/t/helper/test-scrap-cache-tree.c\n@@ -12,7 +12,7 @@ int cmd__scrap_cache_tree(int ac UNUSED, const char **av UNUSED)\n {\n \tstruct lock_file index_lock = LOCK_INIT;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_hold_locked_index(the_repository, &index_lock, LOCK_DIE_ON_ERROR);\n \tif (repo_read_index(the_repository) < 0)\n \t\tdie(\"unable to read index file\");\ndiff --git a/t/helper/test-serve-v2.c b/t/helper/test-serve-v2.c\nindex 63a200b8d4..27f3ed8947 100644\n--- a/t/helper/test-serve-v2.c\n+++ b/t/helper/test-serve-v2.c\n@@ -23,7 +23,7 @@ int cmd__serve_v2(int argc, const char **argv)\n \t\t\t N_(\"exit immediately after advertising capabilities\")),\n \t\tOPT_END()\n \t};\n-\tconst char *prefix = setup_git_directory();\n+\tconst char *prefix = setup_git_directory(the_repository);\n \n \t/* ignore all unknown cmdline switches for now */\n \targc = parse_options(argc, argv, prefix, options, serve_usage,\ndiff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c\nindex cbe93f2f9e..3f30292179 100644\n--- a/t/helper/test-submodule-config.c\n+++ b/t/helper/test-submodule-config.c\n@@ -34,7 +34,7 @@ int cmd__submodule_config(int argc, const char **argv)\n \tif (my_argc % 2 != 0)\n \t\tdie_usage(argc, argv, \"Wrong number of arguments.\");\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \twhile (*arg) {\n \t\tstruct object_id commit_oid;\ndiff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c\nindex 2710341cd5..7e31d3fe47 100644\n--- a/t/helper/test-submodule-nested-repo-config.c\n+++ b/t/helper/test-submodule-nested-repo-config.c\n@@ -19,7 +19,7 @@ int cmd__submodule_nested_repo_config(int argc, const char **argv)\n \tif (argc < 3)\n \t\tdie_usage(argv, \"Wrong number of arguments.\");\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (repo_submodule_init(&subrepo, the_repository, argv[1], null_oid(the_hash_algo))) {\n \t\tdie_usage(argv, \"Submodule not found.\");\ndiff --git a/t/helper/test-submodule.c b/t/helper/test-submodule.c\nindex 0133852e1e..3c5c4c4a09 100644\n--- a/t/helper/test-submodule.c\n+++ b/t/helper/test-submodule.c\n@@ -99,7 +99,7 @@ static int cmd__submodule_is_active(int argc, const char **argv)\n \tif (argc != 1)\n \t\tusage_with_options(submodule_is_active_usage, options);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \treturn !is_submodule_active(the_repository, argv[0]);\n }\n@@ -142,7 +142,7 @@ static int cmd__submodule_config_list(int argc, const char **argv)\n \targc = parse_options(argc, argv, \"test-tools\", options, usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 2)\n \t\treturn print_config_from_gitmodules(the_repository, argv[1]);\n@@ -161,7 +161,7 @@ static int cmd__submodule_config_set(int argc, const char **argv)\n \targc = parse_options(argc, argv, \"test-tools\", options, usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \t/* Equivalent to ACTION_SET in builtin/config.c */\n \tif (argc == 3) {\n@@ -183,7 +183,7 @@ static int cmd__submodule_config_unset(int argc, const char **argv)\n \t\tNULL\n \t};\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 2) {\n \t\tif (!is_writing_gitmodules_ok())\n@@ -202,7 +202,7 @@ static int cmd__submodule_config_writeable(int argc, const char **argv UNUSED)\n \t\t\"test-tool submodule config-writeable\",\n \t\tNULL\n \t};\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 1)\n \t\treturn is_writing_gitmodules_ok() ? 0 : -1;\ndiff --git a/t/helper/test-userdiff.c b/t/helper/test-userdiff.c\nindex aa3a9894d2..fc34c589b3 100644\n--- a/t/helper/test-userdiff.c\n+++ b/t/helper/test-userdiff.c\n@@ -40,7 +40,7 @@ int cmd__userdiff(int argc, const char **argv)\n \t\treturn error(\"unknown argument %s\", argv[1]);\n \n \tif (want & USERDIFF_DRIVER_TYPE_CUSTOM) {\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \t\trepo_config(the_repository, cmd__userdiff_config, NULL);\n \t}\n \ndiff --git a/t/helper/test-write-cache.c b/t/helper/test-write-cache.c\nindex b37dd2c5d6..98e1477c98 100644\n--- a/t/helper/test-write-cache.c\n+++ b/t/helper/test-write-cache.c\n@@ -12,7 +12,7 @@ int cmd__write_cache(int argc, const char **argv)\n \tint i, cnt = 1;\n \tif (argc == 2)\n \t\tcnt = strtol(argv[1], NULL, 0);\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_read_index(the_repository);\n \tfor (i = 0; i < cnt; i++) {\n \t\trepo_hold_locked_index(the_repository, &index_lock,\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541942","messageId":"20260420-pks-setup-wo-the-repository-v1-14-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 14/18] setup: stop using `the_repository` in `upgrade_repository_format()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:44Z","receivedAt":"2026-04-20T08:23:30Z","isPatch":true,"body":"Stop using `the_repository` in `upgrade_repository_format()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n list-objects-filter-options.c | 2 +-\n repository.h                  | 2 +-\n setup.c                       | 6 +++---\n worktree.c                    | 2 +-\n 4 files changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/list-objects-filter-options.c b/list-objects-filter-options.c\nindex cef67e5919..bc5d98f9e6 100644\n--- a/list-objects-filter-options.c\n+++ b/list-objects-filter-options.c\n@@ -378,7 +378,7 @@ void partial_clone_register(\n \t\t\t */\n \t\t\treturn;\n \t} else {\n-\t\tif (upgrade_repository_format(1) < 0)\n+\t\tif (upgrade_repository_format(the_repository, 1) < 0)\n \t\t\tdie(_(\"unable to upgrade repository format to support partial clone\"));\n \n \t\t/* Add promisor config for the remote */\ndiff --git a/repository.h b/repository.h\nindex 7ae3d34484..bb83d03bbf 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -271,6 +271,6 @@ void repo_update_index_if_able(struct repository *, struct lock_file *);\n  * Return 1 if upgrade repository format to target_version succeeded,\n  * 0 if no upgrade is necessary, and -1 when upgrade is not possible.\n  */\n-int upgrade_repository_format(int target_version);\n+int upgrade_repository_format(struct repository *repo, int target_version);\n \n #endif /* REPOSITORY_H */\ndiff --git a/setup.c b/setup.c\nindex 4d4b43ab28..a4e294b096 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -802,7 +802,7 @@ static int check_repository_format_gently(struct repository *repo,\n \treturn 0;\n }\n \n-int upgrade_repository_format(int target_version)\n+int upgrade_repository_format(struct repository *repo, int target_version)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n \tstruct strbuf err = STRBUF_INIT;\n@@ -810,7 +810,7 @@ int upgrade_repository_format(int target_version)\n \tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n \tint ret;\n \n-\trepo_common_path_append(the_repository, &sb, \"config\");\n+\trepo_common_path_append(repo, &sb, \"config\");\n \tread_repository_format(&repo_fmt, sb.buf);\n \tstrbuf_release(&sb);\n \n@@ -832,7 +832,7 @@ int upgrade_repository_format(int target_version)\n \t}\n \n \tstrbuf_addf(&repo_version, \"%d\", target_version);\n-\trepo_config_set(the_repository, \"core.repositoryformatversion\", repo_version.buf);\n+\trepo_config_set(repo, \"core.repositoryformatversion\", repo_version.buf);\n \n \tret = 1;\n \ndiff --git a/worktree.c b/worktree.c\nindex 56732f8f33..8ca0a172c6 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -1104,7 +1104,7 @@ void write_worktree_linking_files(const char *dotgit, const char *gitdir,\n \tstrbuf_realpath(&repo, repo.buf, 1);\n \n \tif (use_relative_paths && !the_repository->repository_format_relative_worktrees) {\n-\t\tif (upgrade_repository_format(1) < 0)\n+\t\tif (upgrade_repository_format(the_repository, 1) < 0)\n \t\t\tdie(_(\"unable to upgrade repository format to support relative worktrees\"));\n \t\tif (repo_config_set_gently(the_repository, \"extensions.relativeWorktrees\", \"true\"))\n \t\t\tdie(_(\"unable to set extensions.relativeWorktrees setting\"));\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541943","messageId":"20260420-pks-setup-wo-the-repository-v1-15-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 15/18] setup: stop using `the_repository` in `check_repository_format()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:45Z","receivedAt":"2026-04-20T08:23:32Z","isPatch":true,"body":"Stop using `the_repository` in `check_repository_format()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nFurthermore, the function is never used outside \"setup.c\". Drop its\ndeclaration in \"setup.h\" and make it static. Note that this requires us\nto reorder the function.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n setup.c | 58 +++++++++++++++++++++++++++++++++-------------------------\n setup.h | 10 ----------\n 2 files changed, 33 insertions(+), 35 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex a4e294b096..803d482849 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1749,6 +1749,37 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir,\n \treturn result;\n }\n \n+/*\n+ * Check the repository format version in the path found in repo_get_git_dir(repo),\n+ * and die if it is a version we don't understand. Generally one would\n+ * set_git_dir() before calling this, and use it only for \"are we in a valid\n+ * repo?\".\n+ *\n+ * If successful and fmt is not NULL, fill fmt with data.\n+ */\n+static void check_repository_format(struct repository *repo, struct repository_format *fmt)\n+{\n+\tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n+\tif (!fmt)\n+\t\tfmt = &repo_fmt;\n+\tcheck_repository_format_gently(repo, repo_get_git_dir(repo), fmt, NULL);\n+\tstartup_info->have_repository = 1;\n+\trepo_set_hash_algo(repo, fmt->hash_algo);\n+\trepo_set_compat_hash_algo(repo, fmt->compat_hash_algo);\n+\trepo_set_ref_storage_format(repo,\n+\t\t\t\t    fmt->ref_storage_format,\n+\t\t\t\t    fmt->ref_storage_payload);\n+\trepo->repository_format_worktree_config =\n+\t\tfmt->worktree_config;\n+\trepo->repository_format_submodule_path_cfg =\n+\t\tfmt->submodule_path_cfg;\n+\trepo->repository_format_relative_worktrees =\n+\t\tfmt->relative_worktrees;\n+\trepo->repository_format_partial_clone =\n+\t\txstrdup_or_null(fmt->partial_clone);\n+\tclear_repository_format(&repo_fmt);\n+}\n+\n const char *enter_repo(struct repository *repo, const char *path, unsigned flags)\n {\n \tstatic struct strbuf validated_path = STRBUF_INIT;\n@@ -1823,7 +1854,7 @@ const char *enter_repo(struct repository *repo, const char *path, unsigned flags\n \n \tif (is_git_directory(\".\")) {\n \t\tset_git_dir(repo, \".\", 0);\n-\t\tcheck_repository_format(NULL);\n+\t\tcheck_repository_format(repo, NULL);\n \t\treturn path;\n \t}\n \n@@ -2098,29 +2129,6 @@ int git_config_perm(const char *var, const char *value)\n \treturn -(i & 0666);\n }\n \n-void check_repository_format(struct repository_format *fmt)\n-{\n-\tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n-\tif (!fmt)\n-\t\tfmt = &repo_fmt;\n-\tcheck_repository_format_gently(the_repository, repo_get_git_dir(the_repository), fmt, NULL);\n-\tstartup_info->have_repository = 1;\n-\trepo_set_hash_algo(the_repository, fmt->hash_algo);\n-\trepo_set_compat_hash_algo(the_repository, fmt->compat_hash_algo);\n-\trepo_set_ref_storage_format(the_repository,\n-\t\t\t\t    fmt->ref_storage_format,\n-\t\t\t\t    fmt->ref_storage_payload);\n-\tthe_repository->repository_format_worktree_config =\n-\t\tfmt->worktree_config;\n-\tthe_repository->repository_format_submodule_path_cfg =\n-\t\tfmt->submodule_path_cfg;\n-\tthe_repository->repository_format_relative_worktrees =\n-\t\tfmt->relative_worktrees;\n-\tthe_repository->repository_format_partial_clone =\n-\t\txstrdup_or_null(fmt->partial_clone);\n-\tclear_repository_format(&repo_fmt);\n-}\n-\n /*\n  * Returns the \"prefix\", a path to the current working directory\n  * relative to the work tree root, or NULL, if the current working\n@@ -2795,7 +2803,7 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t * config file, so this will not fail.  What we are catching\n \t * is an attempt to reinitialize new repository with an old tool.\n \t */\n-\tcheck_repository_format(&repo_fmt);\n+\tcheck_repository_format(the_repository, &repo_fmt);\n \n \trepository_format_configure(the_repository, &repo_fmt, hash, ref_storage_format);\n \ndiff --git a/setup.h b/setup.h\nindex b779661ce7..a820041af0 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -221,16 +221,6 @@ void clear_repository_format(struct repository_format *format);\n int verify_repository_format(const struct repository_format *format,\n \t\t\t     struct strbuf *err);\n \n-/*\n- * Check the repository format version in the path found in repo_get_git_dir(the_repository),\n- * and die if it is a version we don't understand. Generally one would\n- * set_git_dir() before calling this, and use it only for \"are we in a valid\n- * repo?\".\n- *\n- * If successful and fmt is not NULL, fill fmt with data.\n- */\n-void check_repository_format(struct repository_format *fmt);\n-\n const char *get_template_dir(const char *option_template);\n \n #define INIT_DB_QUIET      (1 << 0)\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541944","messageId":"20260420-pks-setup-wo-the-repository-v1-16-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 16/18] setup: stop using `the_repository` in `initialize_repository_version()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:46Z","receivedAt":"2026-04-20T08:23:36Z","isPatch":true,"body":"Stop using `the_repository` in `initialize_repository_version()` and\ninstead accept the repository as a parameter. The injection of\n`the_repository` is thus bumped one level higher, where callers now pass\nit in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c |  4 ++--\n refs.c          |  2 +-\n setup.c         | 29 +++++++++++++++--------------\n setup.h         |  3 ++-\n 4 files changed, 20 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 16cd7b029b..663ef0b524 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1227,7 +1227,7 @@ int cmd_clone(int argc,\n \t *\n \t * This is sufficient for Git commands to discover the Git directory.\n \t */\n-\tinitialize_repository_version(GIT_HASH_UNKNOWN,\n+\tinitialize_repository_version(the_repository, GIT_HASH_UNKNOWN,\n \t\t\t\t      the_repository->ref_storage_format, 1);\n \n \trefs_create_refdir_stubs(the_repository, git_dir, NULL);\n@@ -1440,7 +1440,7 @@ int cmd_clone(int argc,\n \t * ours to the same thing.\n \t */\n \thash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));\n-\tinitialize_repository_version(hash_algo, the_repository->ref_storage_format, 1);\n+\tinitialize_repository_version(the_repository, hash_algo, the_repository->ref_storage_format, 1);\n \trepo_set_hash_algo(the_repository, hash_algo);\n \tcreate_reference_database(NULL, 1);\n \ndiff --git a/refs.c b/refs.c\nindex e66cf4861d..6a49ef8a1c 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -3450,7 +3450,7 @@ int repo_migrate_ref_storage_format(struct repository *repo,\n \t * repository format so that clients will use the new ref store.\n \t * We also need to swap out the repository's main ref store.\n \t */\n-\tinitialize_repository_version(hash_algo_by_ptr(repo->hash_algo), format, 1);\n+\tinitialize_repository_version(the_repository, hash_algo_by_ptr(repo->hash_algo), format, 1);\n \n \t/*\n \t * Unset the old ref store and release it. `get_main_ref_store()` will\ndiff --git a/setup.c b/setup.c\nindex 803d482849..f1d640ea74 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2376,7 +2376,8 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree)\n \treturn 1;\n }\n \n-void initialize_repository_version(int hash_algo,\n+void initialize_repository_version(struct repository *repo,\n+\t\t\t\t   int hash_algo,\n \t\t\t\t   enum ref_storage_format ref_storage_format,\n \t\t\t\t   int reinit)\n {\n@@ -2393,35 +2394,35 @@ void initialize_repository_version(int hash_algo,\n \t */\n \tif (hash_algo != GIT_HASH_SHA1_LEGACY ||\n \t    ref_storage_format != REF_STORAGE_FORMAT_FILES ||\n-\t    the_repository->ref_storage_payload)\n+\t    repo->ref_storage_payload)\n \t\ttarget_version = GIT_REPO_VERSION_READ;\n \n \tif (hash_algo != GIT_HASH_SHA1_LEGACY && hash_algo != GIT_HASH_UNKNOWN)\n-\t\trepo_config_set(the_repository, \"extensions.objectformat\",\n+\t\trepo_config_set(repo, \"extensions.objectformat\",\n \t\t\t\thash_algos[hash_algo].name);\n \telse if (reinit)\n-\t\trepo_config_set_gently(the_repository, \"extensions.objectformat\", NULL);\n+\t\trepo_config_set_gently(repo, \"extensions.objectformat\", NULL);\n \n-\tif (the_repository->ref_storage_payload) {\n+\tif (repo->ref_storage_payload) {\n \t\tstruct strbuf ref_uri = STRBUF_INIT;\n \n \t\tstrbuf_addf(&ref_uri, \"%s://%s\",\n \t\t\t    ref_storage_format_to_name(ref_storage_format),\n-\t\t\t    the_repository->ref_storage_payload);\n-\t\trepo_config_set(the_repository, \"extensions.refstorage\", ref_uri.buf);\n+\t\t\t    repo->ref_storage_payload);\n+\t\trepo_config_set(repo, \"extensions.refstorage\", ref_uri.buf);\n \t\tstrbuf_release(&ref_uri);\n \t} else if (ref_storage_format != REF_STORAGE_FORMAT_FILES) {\n-\t\trepo_config_set(the_repository, \"extensions.refstorage\",\n+\t\trepo_config_set(repo, \"extensions.refstorage\",\n \t\t\t\tref_storage_format_to_name(ref_storage_format));\n \t} else if (reinit) {\n-\t\trepo_config_set_gently(the_repository, \"extensions.refstorage\", NULL);\n+\t\trepo_config_set_gently(repo, \"extensions.refstorage\", NULL);\n \t}\n \n \tif (reinit) {\n \t\tstruct strbuf config = STRBUF_INIT;\n \t\tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n \n-\t\trepo_common_path_append(the_repository, &config, \"config\");\n+\t\trepo_common_path_append(repo, &config, \"config\");\n \t\tread_repository_format(&repo_fmt, config.buf);\n \n \t\tif (repo_fmt.v1_only_extensions.nr)\n@@ -2431,17 +2432,17 @@ void initialize_repository_version(int hash_algo,\n \t\tclear_repository_format(&repo_fmt);\n \t}\n \n-\trepo_config_get_bool(the_repository, \"init.defaultSubmodulePathConfig\",\n+\trepo_config_get_bool(repo, \"init.defaultSubmodulePathConfig\",\n \t\t\t     &default_submodule_path_config);\n \tif (default_submodule_path_config) {\n \t\t/* extensions.submodulepathconfig requires at least version 1 */\n \t\tif (target_version == 0)\n \t\t\ttarget_version = 1;\n-\t\trepo_config_set(the_repository, \"extensions.submodulepathconfig\", \"true\");\n+\t\trepo_config_set(repo, \"extensions.submodulepathconfig\", \"true\");\n \t}\n \n \tstrbuf_addf(&repo_version, \"%d\", target_version);\n-\trepo_config_set(the_repository, \"core.repositoryformatversion\", repo_version.buf);\n+\trepo_config_set(repo, \"core.repositoryformatversion\", repo_version.buf);\n \n \tstrbuf_release(&repo_version);\n }\n@@ -2542,7 +2543,7 @@ static int create_default_files(struct repository *repo,\n \t\tadjust_shared_perm(repo, repo_get_git_dir(repo));\n \t}\n \n-\tinitialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, reinit);\n+\tinitialize_repository_version(repo, fmt->hash_algo, fmt->ref_storage_format, reinit);\n \n \t/* Check filemode trustability */\n \trepo_git_path_replace(repo, &path, \"config\");\ndiff --git a/setup.h b/setup.h\nindex a820041af0..c33b675ccf 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -232,7 +232,8 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t    enum ref_storage_format ref_storage_format,\n \t    const char *initial_branch, int init_shared_repository,\n \t    unsigned int flags);\n-void initialize_repository_version(int hash_algo,\n+void initialize_repository_version(struct repository *repo,\n+\t\t\t\t   int hash_algo,\n \t\t\t\t   enum ref_storage_format ref_storage_format,\n \t\t\t\t   int reinit);\n void create_reference_database(const char *initial_branch, int quiet);\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541945","messageId":"20260420-pks-setup-wo-the-repository-v1-17-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 17/18] setup: stop using `the_repository` in `create_reference_database()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:47Z","receivedAt":"2026-04-20T08:23:39Z","isPatch":true,"body":"Stop using `the_repository` in `create_reference_database()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c |  2 +-\n setup.c         | 13 +++++++------\n setup.h         |  2 +-\n 3 files changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 663ef0b524..d864022214 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1442,7 +1442,7 @@ int cmd_clone(int argc,\n \thash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));\n \tinitialize_repository_version(the_repository, hash_algo, the_repository->ref_storage_format, 1);\n \trepo_set_hash_algo(the_repository, hash_algo);\n-\tcreate_reference_database(NULL, 1);\n+\tcreate_reference_database(the_repository, NULL, 1);\n \n \t/*\n \t * Before fetching from the remote, download and install bundle\ndiff --git a/setup.c b/setup.c\nindex f1d640ea74..8616f5e619 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2459,13 +2459,14 @@ static int is_reinit(struct repository *repo)\n \treturn ret;\n }\n \n-void create_reference_database(const char *initial_branch, int quiet)\n+void create_reference_database(struct repository *repo,\n+\t\t\t       const char *initial_branch, int quiet)\n {\n \tstruct strbuf err = STRBUF_INIT;\n \tchar *to_free = NULL;\n-\tint reinit = is_reinit(the_repository);\n+\tint reinit = is_reinit(repo);\n \n-\tif (ref_store_create_on_disk(get_main_ref_store(the_repository), 0, &err))\n+\tif (ref_store_create_on_disk(get_main_ref_store(repo), 0, &err))\n \t\tdie(\"failed to set up refs db: %s\", err.buf);\n \n \t/*\n@@ -2477,14 +2478,14 @@ void create_reference_database(const char *initial_branch, int quiet)\n \n \t\tif (!initial_branch)\n \t\t\tinitial_branch = to_free =\n-\t\t\t\trepo_default_branch_name(the_repository, quiet);\n+\t\t\t\trepo_default_branch_name(repo, quiet);\n \n \t\tref = xstrfmt(\"refs/heads/%s\", initial_branch);\n \t\tif (check_refname_format(ref, 0) < 0)\n \t\t\tdie(_(\"invalid initial branch name: '%s'\"),\n \t\t\t    initial_branch);\n \n-\t\tif (refs_update_symref(get_main_ref_store(the_repository), \"HEAD\", ref, NULL) < 0)\n+\t\tif (refs_update_symref(get_main_ref_store(repo), \"HEAD\", ref, NULL) < 0)\n \t\t\texit(1);\n \t\tfree(ref);\n \t}\n@@ -2821,7 +2822,7 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\t\t\t      &repo_fmt, init_shared_repository);\n \n \tif (!(flags & INIT_DB_SKIP_REFDB))\n-\t\tcreate_reference_database(initial_branch, flags & INIT_DB_QUIET);\n+\t\tcreate_reference_database(the_repository, initial_branch, flags & INIT_DB_QUIET);\n \tcreate_object_directory(the_repository);\n \n \tif (repo_settings_get_shared_repository(the_repository)) {\ndiff --git a/setup.h b/setup.h\nindex c33b675ccf..21737e9bd6 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -236,7 +236,7 @@ void initialize_repository_version(struct repository *repo,\n \t\t\t\t   int hash_algo,\n \t\t\t\t   enum ref_storage_format ref_storage_format,\n \t\t\t\t   int reinit);\n-void create_reference_database(const char *initial_branch, int quiet);\n+void create_reference_database(struct repository *repo, const char *initial_branch, int quiet);\n \n /*\n  * NOTE NOTE NOTE!!\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541946","messageId":"20260420-pks-setup-wo-the-repository-v1-18-f4a81c4988e8@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH 18/18] setup: stop using `the_repository` in `init_db()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-20T08:22:48Z","receivedAt":"2026-04-20T08:23:42Z","isPatch":true,"body":"Stop using `the_repository` in `init_db()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c   |  2 +-\n builtin/init-db.c |  2 +-\n setup.c           | 43 ++++++++++++++++++++++---------------------\n setup.h           |  3 ++-\n 4 files changed, 26 insertions(+), 24 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex d864022214..bc35a3c0b1 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1184,7 +1184,7 @@ int cmd_clone(int argc,\n \t * repository, and reference backends may persist that information into\n \t * their on-disk data structures.\n \t */\n-\tinit_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,\n+\tinit_db(the_repository, git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,\n \t\tref_storage_format, NULL,\n \t\tdo_not_override_repo_unix_permissions, INIT_DB_QUIET | INIT_DB_SKIP_REFDB);\n \ndiff --git a/builtin/init-db.c b/builtin/init-db.c\nindex e626b0d8b7..c55517ad94 100644\n--- a/builtin/init-db.c\n+++ b/builtin/init-db.c\n@@ -252,7 +252,7 @@ int cmd_init_db(int argc,\n \t}\n \n \tflags |= INIT_DB_EXIST_OK;\n-\tret = init_db(git_dir, real_git_dir, template_dir, hash_algo,\n+\tret = init_db(the_repository, git_dir, real_git_dir, template_dir, hash_algo,\n \t\t      ref_storage_format, initial_branch,\n \t\t      init_shared_repository, flags);\n \ndiff --git a/setup.c b/setup.c\nindex 8616f5e619..1847111616 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2769,7 +2769,8 @@ static void repository_format_configure(struct repository *repo,\n \t\t\t\t    repo_fmt->ref_storage_payload);\n }\n \n-int init_db(const char *git_dir, const char *real_git_dir,\n+int init_db(struct repository *repo,\n+\t    const char *git_dir, const char *real_git_dir,\n \t    const char *template_dir, int hash,\n \t    enum ref_storage_format ref_storage_format,\n \t    const char *initial_branch,\n@@ -2789,13 +2790,13 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\tif (!exist_ok && !stat(real_git_dir, &st))\n \t\t\tdie(_(\"%s already exists\"), real_git_dir);\n \n-\t\tset_git_dir(the_repository, real_git_dir, 1);\n-\t\tgit_dir = repo_get_git_dir(the_repository);\n+\t\tset_git_dir(repo, real_git_dir, 1);\n+\t\tgit_dir = repo_get_git_dir(repo);\n \t\tseparate_git_dir(git_dir, original_git_dir);\n \t}\n \telse {\n-\t\tset_git_dir(the_repository, git_dir, 1);\n-\t\tgit_dir = repo_get_git_dir(the_repository);\n+\t\tset_git_dir(repo, git_dir, 1);\n+\t\tgit_dir = repo_get_git_dir(repo);\n \t}\n \tstartup_info->have_repository = 1;\n \n@@ -2805,27 +2806,27 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t * config file, so this will not fail.  What we are catching\n \t * is an attempt to reinitialize new repository with an old tool.\n \t */\n-\tcheck_repository_format(the_repository, &repo_fmt);\n+\tcheck_repository_format(repo, &repo_fmt);\n \n-\trepository_format_configure(the_repository, &repo_fmt, hash, ref_storage_format);\n+\trepository_format_configure(repo, &repo_fmt, hash, ref_storage_format);\n \n \t/*\n \t * Ensure `core.hidedotfiles` is processed. This must happen after we\n \t * have set up the repository format such that we can evaluate\n \t * includeIf conditions correctly in the case of re-initialization.\n \t */\n-\trepo_config(the_repository, git_default_core_config, NULL);\n+\trepo_config(repo, git_default_core_config, NULL);\n \n-\tsafe_create_dir(the_repository, git_dir, 0);\n+\tsafe_create_dir(repo, git_dir, 0);\n \n-\treinit = create_default_files(the_repository, template_dir, original_git_dir,\n+\treinit = create_default_files(repo, template_dir, original_git_dir,\n \t\t\t\t      &repo_fmt, init_shared_repository);\n \n \tif (!(flags & INIT_DB_SKIP_REFDB))\n-\t\tcreate_reference_database(the_repository, initial_branch, flags & INIT_DB_QUIET);\n-\tcreate_object_directory(the_repository);\n+\t\tcreate_reference_database(repo, initial_branch, flags & INIT_DB_QUIET);\n+\tcreate_object_directory(repo);\n \n-\tif (repo_settings_get_shared_repository(the_repository)) {\n+\tif (repo_settings_get_shared_repository(repo)) {\n \t\tchar buf[10];\n \t\t/* We do not spell \"group\" and such, so that\n \t\t * the configuration can be read by older version\n@@ -2833,29 +2834,29 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\t * and compatibility values for PERM_GROUP and\n \t\t * PERM_EVERYBODY.\n \t\t */\n-\t\tif (repo_settings_get_shared_repository(the_repository) < 0)\n+\t\tif (repo_settings_get_shared_repository(repo) < 0)\n \t\t\t/* force to the mode value */\n-\t\t\txsnprintf(buf, sizeof(buf), \"0%o\", -repo_settings_get_shared_repository(the_repository));\n-\t\telse if (repo_settings_get_shared_repository(the_repository) == PERM_GROUP)\n+\t\t\txsnprintf(buf, sizeof(buf), \"0%o\", -repo_settings_get_shared_repository(repo));\n+\t\telse if (repo_settings_get_shared_repository(repo) == PERM_GROUP)\n \t\t\txsnprintf(buf, sizeof(buf), \"%d\", OLD_PERM_GROUP);\n-\t\telse if (repo_settings_get_shared_repository(the_repository) == PERM_EVERYBODY)\n+\t\telse if (repo_settings_get_shared_repository(repo) == PERM_EVERYBODY)\n \t\t\txsnprintf(buf, sizeof(buf), \"%d\", OLD_PERM_EVERYBODY);\n \t\telse\n \t\t\tBUG(\"invalid value for shared_repository\");\n-\t\trepo_config_set(the_repository, \"core.sharedrepository\", buf);\n-\t\trepo_config_set(the_repository, \"receive.denyNonFastforwards\", \"true\");\n+\t\trepo_config_set(repo, \"core.sharedrepository\", buf);\n+\t\trepo_config_set(repo, \"receive.denyNonFastforwards\", \"true\");\n \t}\n \n \tif (!(flags & INIT_DB_QUIET)) {\n \t\tint len = strlen(git_dir);\n \n \t\tif (reinit)\n-\t\t\tprintf(repo_settings_get_shared_repository(the_repository)\n+\t\t\tprintf(repo_settings_get_shared_repository(repo)\n \t\t\t       ? _(\"Reinitialized existing shared Git repository in %s%s\\n\")\n \t\t\t       : _(\"Reinitialized existing Git repository in %s%s\\n\"),\n \t\t\t       git_dir, len && git_dir[len-1] != '/' ? \"/\" : \"\");\n \t\telse\n-\t\t\tprintf(repo_settings_get_shared_repository(the_repository)\n+\t\t\tprintf(repo_settings_get_shared_repository(repo)\n \t\t\t       ? _(\"Initialized empty shared Git repository in %s%s\\n\")\n \t\t\t       : _(\"Initialized empty Git repository in %s%s\\n\"),\n \t\t\t       git_dir, len && git_dir[len-1] != '/' ? \"/\" : \"\");\ndiff --git a/setup.h b/setup.h\nindex 21737e9bd6..9409326fe4 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -227,7 +227,8 @@ const char *get_template_dir(const char *option_template);\n #define INIT_DB_EXIST_OK   (1 << 1)\n #define INIT_DB_SKIP_REFDB (1 << 2)\n \n-int init_db(const char *git_dir, const char *real_git_dir,\n+int init_db(struct repository *repo,\n+\t    const char *git_dir, const char *real_git_dir,\n \t    const char *template_dir, int hash_algo,\n \t    enum ref_storage_format ref_storage_format,\n \t    const char *initial_branch, int init_shared_repository,\n\n-- \n2.54.0.rc2.529.gd9106f7525.dirty\n\n"},{"id":"541980","messageId":"CABPp-BHOVhQPL4ScA+sJCvE2OYXjLJSyDim5AocbcqoxzObGxQ@mail.gmail.com","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"Re: [PATCH 00/18] setup: drop uses of `the_repository`","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2026-04-20T15:50:45Z","receivedAt":"2026-04-20T15:50:58Z","isPatch":true,"body":"On Mon, Apr 20, 2026 at 1:22 AM Patrick Steinhardt <ps@pks.im> wrote:\n>\n> Hi,\n>\n> I've had enough of \"setup.c\" and its complexities, so I finally decided\n> to take the bullet and start refactoring this subsystem. This here is\n> the first out of the following three steps:\n>\n>   1. Drop all uses of `the_repository`. This doesn't yet allow us to get\n>      rid of `USE_THE_REPOSITORY_VARIABLE`.\n>\n>   2. Convert a couple of global variables and drop\n>      `is_bare_repository_cfg`, which then allows us to drop\n>      `USE_THE_REPOSITORY_VARIABLE`.\n>\n>   3. Refactor the subsystem a bit so that we stop intermixing repository\n>      discovery and repository initialization. This is my original\n>      motivation as I want to get rid of `odb_prepare_alternates()`, but\n>      due to the way we initialize the repository it has proven to be\n>      extremely tedious.\n>\n> Most of the patches in this series here are rather mechanical. There's\n> only a handful of patches that warrant more attention:\n>\n>   -  2/18: setup: stop using `the_repository` in `is_inside_worktree()`\n>   -  3/18: setup: stop using `the_repository` in `is_inside_git_dir()`\n>   -  9/18: setup: stop using `the_repository` in `setup_work_tree()`\n>   - 10/18: setup: stop using `the_repository` in `set_git_work_tree()`\n>\n> Those patches don't only mechanical move stuff around, but also change\n> some logic to make it work.\n>\n> The series is based on 5361983c07 (The 22nd batch, 2026-03-27). There is\n> a single merge commit with \"seen\", but it's trivial to resolve.\n>\n> Changes in v2:\n>   - Remove static `initialized` variable in `setup_work_tree()`.\n>   - Use enum values to initialize fields.\n>   - Fix up a comment.\n>   - Link to v1: https://lore.kernel.org/all/20260330-pks-setup-wo-the-repository-v1-0-0d2e822837aa@pks.im/\n\nThanks, I would have preferred this series to have used the \"PATCH v2\"\nprefix and for its cover letter to be sent in-response-to the cover\nletter of v1, but those are nitpicks that don't affect the overall\nseries.\n\nI thought to check one additional thing I didn't check when reviewing\nv1.  I looked for all cases where this series added \"the_repository\"\nto some function between the beginning and end of the series, and for\nwhich the function where the code was found already had a\nrepo/repository parameter.  There were several of these in builtins,\nbut those are already littered with cases where cmd_foo() has a\nrepository parameter declared UNUSED and where we use the_repository\nanyway.  Those should be cleaned up, but that's outside the scope of\nthis series.  However, I did spot one non-builtin case: in patch 16,\nrepo_migrate_ref_storage_format() already has a repo parameter, so\nyour call to initialize_repository_version() can use it instead of\nthe_repository.\n\nOther than that small issue, I think this series is ready.\n"},{"id":"541988","messageId":"xmqqy0ihpnf6.fsf@gitster.g","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"Re: [PATCH 00/18] setup: drop uses of `the_repository`","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-20T17:11:09Z","receivedAt":"2026-04-20T17:11:11Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Message-Id: <20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im>\n\nThere seem to be some tool errors that made this marked as v1 (hence\nno References/In-Reply-To).\n\n>   -  9/18: setup: stop using `the_repository` in `setup_work_tree()`\n\n> diff --git a/setup.c b/setup.c\n> index dca32addae..80dd94b261 100644\n> --- a/setup.c\n> +++ b/setup.c\n> @@ -26,7 +26,6 @@\n>  #include \"trace2.h\"\n>  #include \"worktree.h\"\n>  \n> -static int work_tree_config_is_bogus;\n\nOnce we start \"setting up\" more than one instance of \"struct\nrepository\", \"the worktree configuration given to us is bogus\" bit\ncannot be a singleton global that applies across repositories.\n\nHopefully nobody sets core.bare and core.worktree in configuration\nfiles other than the repository local one.  Otherwise a lot of\ninteresting would break ;-)\n\nI am not quite sure the reasoning behind removing \"initialized\"\nglobal without any replacement was properly explained, with \"should\nultimately be idempotent\".  This can give us a huge performance\nregression, if the callers have been relying on setup_work_tree() to\nbe _cheap_ when they call it \"just in case\" no other potential\ncallsites have called it, even though all of them know that the\ncurrent code works only with the_repository (in other words, they\ncall because the switched into the_repository---they do not know for\nsure if other call sites have called it).\n\nOr does the current code never call setup_work_tree() twice, because\neverybody knows that we never work with anything other than\nthe_repository?\n\nOther than that, the [09/18] step looks sensible to me.\n\nThanks.\n\n"},{"id":"542033","messageId":"aedGO_FGV94tMvu6@pks.im","threadId":"65515","inReplyTo":"CABPp-BHOVhQPL4ScA+sJCvE2OYXjLJSyDim5AocbcqoxzObGxQ@mail.gmail.com","subject":"Re: [PATCH 00/18] setup: drop uses of `the_repository`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-21T09:41:15Z","receivedAt":"2026-04-21T09:41:29Z","isPatch":true,"body":"On Mon, Apr 20, 2026 at 08:50:45AM -0700, Elijah Newren wrote:\n> Thanks, I would have preferred this series to have used the \"PATCH v2\"\n> prefix and for its cover letter to be sent in-response-to the cover\n> letter of v1, but those are nitpicks that don't affect the overall\n> series.\n\nYeah, true. I noticed that b4 didn't quite do its thing, but too late. I\nthink this happens when b4 is still busy sending out mails from the\npreceding version, but I already switch branches.\n\n> I thought to check one additional thing I didn't check when reviewing\n> v1.  I looked for all cases where this series added \"the_repository\"\n> to some function between the beginning and end of the series, and for\n> which the function where the code was found already had a\n> repo/repository parameter.  There were several of these in builtins,\n> but those are already littered with cases where cmd_foo() has a\n> repository parameter declared UNUSED and where we use the_repository\n> anyway.  Those should be cleaned up, but that's outside the scope of\n> this series.  However, I did spot one non-builtin case: in patch 16,\n> repo_migrate_ref_storage_format() already has a repo parameter, so\n> your call to initialize_repository_version() can use it instead of\n> the_repository.\n\nThis is something I'm always torn on. The problem here is that more\noften than not, series like this end up touching lots and lots of places\nthroughout the code base.\n\nOn the one hand this means that I'd have to reason through every\ncallsite to figure out whether any repo that is available in the\ncaller's context is the correct repository to use, or if it's even set\nat all (e.g. in the case of `cmd_foo()`). On the other hand, even if I\ndo so, I cannot trivially prove that the refactoring is equivalent, and\nthe refactoring may introduce bugs at the callsites I'm adapting because\nof it.\n\nSo that's why I typically lean towards fixing the subsystem itself, but\ndoing the trivial swap for callers so that we only have to worry about\none part. The only exception is callers where we don't have\nUSE_THE_REPOSITORY_VARIABLE defined anymore.\n\nPatrick\n"},{"id":"542034","messageId":"aedFNjsLDsFj_InR@pks.im","threadId":"65515","inReplyTo":"xmqqy0ihpnf6.fsf@gitster.g","subject":"Re: [PATCH 00/18] setup: drop uses of `the_repository`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-21T09:41:28Z","receivedAt":"2026-04-21T09:41:34Z","isPatch":true,"body":"On Mon, Apr 20, 2026 at 10:11:09AM -0700, Junio C Hamano wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > Message-Id: <20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im>\n> \n> There seem to be some tool errors that made this marked as v1 (hence\n> no References/In-Reply-To).\n\nYeah, I noticed this, too. As mentioned in the mail to Elijah, I think\nthis happens when I'm overeager and already switch branches while b4 is\nstill busy sending out mails. In that case, it doesn't update the series\nto vN+1 :/\n\n> >   -  9/18: setup: stop using `the_repository` in `setup_work_tree()`\n> \n> > diff --git a/setup.c b/setup.c\n> > index dca32addae..80dd94b261 100644\n> > --- a/setup.c\n> > +++ b/setup.c\n> > @@ -26,7 +26,6 @@\n> >  #include \"trace2.h\"\n> >  #include \"worktree.h\"\n> >  \n> > -static int work_tree_config_is_bogus;\n> \n> Once we start \"setting up\" more than one instance of \"struct\n> repository\", \"the worktree configuration given to us is bogus\" bit\n> cannot be a singleton global that applies across repositories.\n> \n> Hopefully nobody sets core.bare and core.worktree in configuration\n> files other than the repository local one.  Otherwise a lot of\n> interesting would break ;-)\n> \n> I am not quite sure the reasoning behind removing \"initialized\"\n> global without any replacement was properly explained, with \"should\n> ultimately be idempotent\".  This can give us a huge performance\n> regression, if the callers have been relying on setup_work_tree() to\n> be _cheap_ when they call it \"just in case\" no other potential\n> callsites have called it, even though all of them know that the\n> current code works only with the_repository (in other words, they\n> call because the switched into the_repository---they do not know for\n> sure if other call sites have called it).\n> \n> Or does the current code never call setup_work_tree() twice, because\n> everybody knows that we never work with anything other than\n> the_repository?\n\n`setup_work_tree()` is typically executed via \"git.c\" in case\nNEED_WORK_TREE is set. Some other top-level commands end up executing it\nmanually in case the bit is not set.\n\nOther than that it's called in a couple more sites:\n\n  - \"builtin/check-attr.c\", \"builtin/clone.c\", \"builtin/describe.c\",\n    \"builtin/diff-index.c\", \"builtin/diff.c\", \"builtin/difftool.c\",\n    \"builtin/grep.c\", \"builtin/ls-files.c\", \"builtin/read-tree.c\",\n    \"builtin/reset.c\", \"builtin/rm.c\", \"builtin/submodule--helper.c\", :\n    Not marked with NEED_WORK_TREE, executed exactly once.\n\n  - \"builtin/sparse-checkout.c\": we have multiple callsites here for the\n    subcommands, but also call it via `update_working_directory()`. We\n    execute it a fixed number of times only though, but I doubt that the\n    performance overhead of this matters in practice. That being said,\n    all sites leading up to this have already called `setup_work_tree()`\n    beforehand, so it would be trivial to fix.\n\n  - \"builtin/update-index.c\": it may be executed multiple times via\n    command line options, e.g. in case you execute `git update-index\n    --refresh --refresh`. Again, I doubt this matters.\n\n  - \"blame.c\": executed exactly once via `setup_scoreboard()`, which in\n    turn is executed once only via \"builtin/blame.c\", which is not\n    marked with NEED_WORK_TREE. So this is fine.\n\n  - \"wt-status.c\": executed once when printing a verbose status. This\n    will result in a second invocation for git-status(1) and\n    git-commit(1), but again it's bounded.\n\n  - \"t/helper/test-subprocess.c\": executed exactly once, but doesn't\n    matter much anyway.\n\nSo overall I think it's fine as in most cases we really only execute it\nonce, and in the remaining cases we only execute it a limited amount of\ntimes (twice or thrice). In addition to that, getenv(3p) and setenv(3p)\nshouldn't be inherently expensive, and the chnotify callbacks we\nregister are all rather cheap, too.\n\nWe _could_ prepare git-sparse-checkout(1) and git-update-index(1) to\nhandle this, but I'm not sure this is really needed. All the other\ncallsites are fine, as far as I can see.\n\nThanks!\n\nPatrick\n"},{"id":"543481","messageId":"4d9604e2-036b-485e-aa93-53c35d539bed@malon.dev","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-2-f4a81c4988e8@pks.im","subject":"Re: [PATCH 02/18] setup: stop using `the_repository` in `is_inside_worktree()`","fromName":"Tian Yuchen","fromEmail":"cat@malon.dev","sentAt":"2026-05-17T16:18:36Z","receivedAt":"2026-05-17T16:18:54Z","isPatch":true,"body":"On 4/20/26 16:22, Patrick Steinhardt wrote:\n\nI've noticed something that does not entirely convince me:\n\n> @@ -477,11 +476,13 @@ int is_inside_git_dir(void)\n>  \treturn inside_git_dir;\n>  }\n>  \n> -int is_inside_work_tree(void)\n> +int is_inside_work_tree(struct repository *repo)\n>  {\n> -\tif (inside_work_tree < 0)\n> -\t\tinside_work_tree = is_inside_dir(repo_get_work_tree(the_repository));\n> -\treturn inside_work_tree;\n> +\tstatic struct strbuf buf = STRBUF_INIT;\n> +\tconst char *worktree = repo_get_work_tree(repo);\n> +\tif (!worktree)\n> +\t\treturn 0;\n> +\treturn is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n>  }\n> \n\nIs it correct to statically allocate memory for the cache here? Could \nthis lead\nto memory overwriting issues in a multi-threaded environment?\n\np.s. I'm not sure if this one is better:\n\n> \n> int is_inside_work_tree(struct repository *repo)\n> {\n> \tstruct strbuf buf = STRBUF_INIT;\n> \tconst char *worktree = repo_get_work_tree(repo);\n> \tint ret;\n> \n> \tif (!worktree)\n> \t\treturn 0;\n> \n> \tret = is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n> \tstrbuf_release(&buf);\n> \treturn ret;\n> }\n\nThanks! yuchen\n\n\n"},{"id":"543493","messageId":"xmqqa4txd2p5.fsf@gitster.g","threadId":"65515","inReplyTo":"4d9604e2-036b-485e-aa93-53c35d539bed@malon.dev","subject":"Re: [PATCH 02/18] setup: stop using `the_repository` in `is_inside_worktree()`","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-05-17T23:41:10Z","receivedAt":"2026-05-17T23:41:12Z","isPatch":true,"body":"Tian Yuchen <cat@malon.dev> writes:\n\n> On 4/20/26 16:22, Patrick Steinhardt wrote:\n>\n> I've noticed something that does not entirely convince me:\n>\n>> @@ -477,11 +476,13 @@ int is_inside_git_dir(void)\n>>  \treturn inside_git_dir;\n>>  }\n>>  \n>> -int is_inside_work_tree(void)\n>> +int is_inside_work_tree(struct repository *repo)\n>>  {\n>> -\tif (inside_work_tree < 0)\n>> -\t\tinside_work_tree = is_inside_dir(repo_get_work_tree(the_repository));\n>> -\treturn inside_work_tree;\n>> +\tstatic struct strbuf buf = STRBUF_INIT;\n>> +\tconst char *worktree = repo_get_work_tree(repo);\n>> +\tif (!worktree)\n>> +\t\treturn 0;\n>> +\treturn is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n>>  }\n>> \n>\n> Is it correct to statically allocate memory for the cache here? Could \n> this lead\n> to memory overwriting issues in a multi-threaded environment?\n\nI do not offhand know if other code paths that are called from this\nfunction are thread-safe, but yeah, this use of file-scope static is\nnot a safe thing to do.\n"},{"id":"543501","messageId":"agrD4p1AIPtwa5gW@pks.im","threadId":"65515","inReplyTo":"xmqqa4txd2p5.fsf@gitster.g","subject":"Re: [PATCH 02/18] setup: stop using `the_repository` in `is_inside_worktree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T07:46:42Z","receivedAt":"2026-05-18T07:46:49Z","isPatch":true,"body":"On Mon, May 18, 2026 at 08:41:10AM +0900, Junio C Hamano wrote:\n> Tian Yuchen <cat@malon.dev> writes:\n> \n> > On 4/20/26 16:22, Patrick Steinhardt wrote:\n> >\n> > I've noticed something that does not entirely convince me:\n> >\n> >> @@ -477,11 +476,13 @@ int is_inside_git_dir(void)\n> >>  \treturn inside_git_dir;\n> >>  }\n> >>  \n> >> -int is_inside_work_tree(void)\n> >> +int is_inside_work_tree(struct repository *repo)\n> >>  {\n> >> -\tif (inside_work_tree < 0)\n> >> -\t\tinside_work_tree = is_inside_dir(repo_get_work_tree(the_repository));\n> >> -\treturn inside_work_tree;\n> >> +\tstatic struct strbuf buf = STRBUF_INIT;\n> >> +\tconst char *worktree = repo_get_work_tree(repo);\n> >> +\tif (!worktree)\n> >> +\t\treturn 0;\n> >> +\treturn is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n> >>  }\n> >> \n> >\n> > Is it correct to statically allocate memory for the cache here? Could \n> > this lead\n> > to memory overwriting issues in a multi-threaded environment?\n> \n> I do not offhand know if other code paths that are called from this\n> function are thread-safe, but yeah, this use of file-scope static is\n> not a safe thing to do.\n\nIn the current status quo this is a safe conversion to do, as we still\nhave the assumption ingrained that this only works for a single repo.\nWe were using static variables before, and we're still using static\nvariables now.\n\nThat being said, I wouldn't mind dropping the static variable if this is\nsomething we'd rather want to get rid of. It's a smell that I'm not\nparticularly happy about myself.\n\nI'll send a revised version in a bit, thanks!\n\nPatrick\n"},{"id":"543506","messageId":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH v2 00/18] setup: drop uses of `the_repository`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:30:51Z","receivedAt":"2026-05-18T09:31:10Z","isPatch":true,"body":"Hi,\n\nI've had enough of \"setup.c\" and its complexities, so I finally decided\nto take the bullet and start refactoring this subsystem. This here is\nthe first out of the following three steps:\n\n  1. Drop all uses of `the_repository`. This doesn't yet allow us to get\n     rid of `USE_THE_REPOSITORY_VARIABLE`.\n\n  2. Convert a couple of global variables and drop\n     `is_bare_repository_cfg`, which then allows us to drop\n     `USE_THE_REPOSITORY_VARIABLE`.\n\n  3. Refactor the subsystem a bit so that we stop intermixing repository\n     discovery and repository initialization. This is my original\n     motivation as I want to get rid of `odb_prepare_alternates()`, but\n     due to the way we initialize the repository it has proven to be\n     extremely tedious.\n\nMost of the patches in this series here are rather mechanical. There's\nonly a handful of patches that warrant more attention:\n\n  -  2/18: setup: stop using `the_repository` in `is_inside_worktree()`\n  -  3/18: setup: stop using `the_repository` in `is_inside_git_dir()`\n  -  9/18: setup: stop using `the_repository` in `setup_work_tree()`\n  - 10/18: setup: stop using `the_repository` in `set_git_work_tree()`\n\nThose patches don't only mechanical move stuff around, but also change\nsome logic to make it work.\n\nChanges in v2:\n  - Drop some static variables.\n  - Rebase on top of origin/master at 59ff4886a5 (Merge branch\n    'ps/clang-w-glibc-2.43-and-_Generic', 2026-05-13). This resolves a\n    single conflict, but more importantly the rebase fixes CI.\n  - Link to v1: https://patch.msgid.link/20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im\n\nChanges in v1 (relative to the botched-up [1]):\n  - Remove static `initialized` variable in `setup_work_tree()`.\n  - Use enum values to initialize fields.\n  - Fix up a comment.\n  - Link to v1: https://lore.kernel.org/all/20260330-pks-setup-wo-the-repository-v1-0-0d2e822837aa@pks.im/\n\nThanks!\n\nPatrick\n\n[1]: <20260330-pks-setup-wo-the-repository-v1-0-0d2e822837aa@pks.im>\n\n---\nPatrick Steinhardt (18):\n      setup: replace use of `the_repository` in static functions\n      setup: stop using `the_repository` in `is_inside_worktree()`\n      setup: stop using `the_repository` in `is_inside_git_dir()`\n      setup: stop using `the_repository` in `prefix_path()`\n      setup: stop using `the_repository` in `path_inside_repo()`\n      setup: stop using `the_repository` in `verify_filename()`\n      setup: stop using `the_repository` in `verify_non_filename()`\n      setup: stop using `the_repository` in `enter_repo()`\n      setup: stop using `the_repository` in `setup_work_tree()`\n      setup: stop using `the_repository` in `set_git_work_tree()`\n      setup: stop using `the_repository` in `setup_git_env()`\n      setup: stop using `the_repository` in `setup_git_directory_gently()`\n      setup: stop using `the_repository` in `setup_git_directory()`\n      setup: stop using `the_repository` in `upgrade_repository_format()`\n      setup: stop using `the_repository` in `check_repository_format()`\n      setup: stop using `the_repository` in `initialize_repository_version()`\n      setup: stop using `the_repository` in `create_reference_database()`\n      setup: stop using `the_repository` in `init_db()`\n\n archive.c                                    |   2 +-\n blame.c                                      |   2 +-\n builtin/blame.c                              |   2 +-\n builtin/check-attr.c                         |   4 +-\n builtin/check-ref-format.c                   |   5 +-\n builtin/checkout-index.c                     |   4 +-\n builtin/checkout.c                           |   2 +-\n builtin/clone.c                              |  12 +-\n builtin/describe.c                           |   2 +-\n builtin/diff-index.c                         |   2 +-\n builtin/diff.c                               |  10 +-\n builtin/difftool.c                           |   2 +-\n builtin/grep.c                               |   8 +-\n builtin/hash-object.c                        |   4 +-\n builtin/help.c                               |   2 +-\n builtin/init-db.c                            |   8 +-\n builtin/ls-files.c                           |   4 +-\n builtin/merge-file.c                         |   2 +-\n builtin/mv.c                                 |   5 +-\n builtin/read-tree.c                          |   2 +-\n builtin/receive-pack.c                       |   2 +-\n builtin/reset.c                              |   6 +-\n builtin/rev-parse.c                          |  14 +-\n builtin/rm.c                                 |   2 +-\n builtin/sparse-checkout.c                    |  19 +-\n builtin/stripspace.c                         |   2 +-\n builtin/submodule--helper.c                  |   2 +-\n builtin/update-index.c                       |  16 +-\n builtin/upload-archive.c                     |   2 +-\n builtin/upload-pack.c                        |   2 +-\n daemon.c                                     |   4 +-\n environment.h                                |   2 -\n git.c                                        |  10 +-\n http-backend.c                               |   2 +-\n http-fetch.c                                 |   2 +-\n http-push.c                                  |   2 +-\n imap-send.c                                  |   2 +-\n line-log.c                                   |   2 +-\n list-objects-filter-options.c                |   2 +-\n object-name.c                                |   4 +-\n pathspec.c                                   |   2 +-\n refs.c                                       |   2 +-\n remote-curl.c                                |   4 +-\n repository.h                                 |   4 +-\n revision.c                                   |   6 +-\n scalar.c                                     |   4 +-\n setup.c                                      | 451 ++++++++++++++-------------\n setup.h                                      |  43 ++-\n submodule.c                                  |   2 +-\n t/helper/test-advise.c                       |   2 +-\n t/helper/test-bitmap.c                       |   2 +-\n t/helper/test-bloom.c                        |   2 +-\n t/helper/test-cache-tree.c                   |   2 +-\n t/helper/test-config.c                       |   2 +-\n t/helper/test-dump-cache-tree.c              |   2 +-\n t/helper/test-dump-fsmonitor.c               |   2 +-\n t/helper/test-dump-split-index.c             |   2 +-\n t/helper/test-dump-untracked-cache.c         |   2 +-\n t/helper/test-find-pack.c                    |   2 +-\n t/helper/test-fsmonitor-client.c             |   2 +-\n t/helper/test-lazy-init-name-hash.c          |   2 +-\n t/helper/test-match-trees.c                  |   2 +-\n t/helper/test-pack-deltas.c                  |   2 +-\n t/helper/test-pack-mtimes.c                  |   2 +-\n t/helper/test-partial-clone.c                |   4 +-\n t/helper/test-path-utils.c                   |   4 +-\n t/helper/test-path-walk.c                    |   2 +-\n t/helper/test-reach.c                        |   2 +-\n t/helper/test-read-cache.c                   |   2 +-\n t/helper/test-read-graph.c                   |   2 +-\n t/helper/test-read-midx.c                    |   2 +-\n t/helper/test-ref-store.c                    |   2 +-\n t/helper/test-revision-walking.c             |   2 +-\n t/helper/test-scrap-cache-tree.c             |   2 +-\n t/helper/test-serve-v2.c                     |   2 +-\n t/helper/test-submodule-config.c             |   2 +-\n t/helper/test-submodule-nested-repo-config.c |   2 +-\n t/helper/test-submodule.c                    |  10 +-\n t/helper/test-subprocess.c                   |   6 +-\n t/helper/test-userdiff.c                     |   2 +-\n t/helper/test-write-cache.c                  |   2 +-\n worktree.c                                   |   2 +-\n wt-status.c                                  |   2 +-\n 83 files changed, 402 insertions(+), 383 deletions(-)\n\nRange-diff versus v1:\n\n 1:  2bdd6dfead =  1:  275a0e45a3 setup: replace use of `the_repository` in static functions\n 2:  e38c29bd25 !  2:  d748d28abe setup: stop using `the_repository` in `is_inside_worktree()`\n    @@ setup.c: int is_inside_git_dir(void)\n     -\tif (inside_work_tree < 0)\n     -\t\tinside_work_tree = is_inside_dir(repo_get_work_tree(the_repository));\n     -\treturn inside_work_tree;\n    -+\tstatic struct strbuf buf = STRBUF_INIT;\n    -+\tconst char *worktree = repo_get_work_tree(repo);\n    ++\tstruct strbuf buf = STRBUF_INIT;\n    ++\tconst char *worktree;\n    ++\tint ret;\n    ++\n    ++\tworktree = repo_get_work_tree(repo);\n     +\tif (!worktree)\n     +\t\treturn 0;\n    -+\treturn is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n    ++\n    ++\tret = is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n    ++\n    ++\tstrbuf_release(&buf);\n    ++\treturn ret;\n      }\n      \n      void setup_work_tree(void)\n 3:  184b1f2331 !  3:  3f1da8a163 setup: stop using `the_repository` in `is_inside_git_dir()`\n    @@ setup.c: int is_nonbare_repository_dir(struct strbuf *path)\n     -\tif (inside_git_dir < 0)\n     -\t\tinside_git_dir = is_inside_dir(repo_get_git_dir(the_repository));\n     -\treturn inside_git_dir;\n    -+\tstatic struct strbuf buf = STRBUF_INIT;\n    -+\treturn is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));\n    ++\tstruct strbuf buf = STRBUF_INIT;\n    ++\tint ret = is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));\n    ++\tstrbuf_release(&buf);\n    ++\treturn ret;\n      }\n      \n      int is_inside_work_tree(struct repository *repo)\n 4:  c178fb7f3d =  4:  59426f6dbc setup: stop using `the_repository` in `prefix_path()`\n 5:  e408ba2332 =  5:  aae9034d31 setup: stop using `the_repository` in `path_inside_repo()`\n 6:  b43251adcb =  6:  b8d6abd41f setup: stop using `the_repository` in `verify_filename()`\n 7:  e489b6f84e !  7:  e6ecd9ea0d setup: stop using `the_repository` in `verify_non_filename()`\n    @@ builtin/reset.c: static void parse_args(struct pathspec *pathspec,\n      \t\t\t/* Otherwise we treat this as a filename */\n     \n      ## revision.c ##\n    -@@ revision.c: static int handle_dotdot_1(const char *arg, char *dotdot,\n    +@@ revision.c: static int handle_dotdot_1(const char *a_name, const char *b_name,\n    + \t\treturn -1;\n      \n      \tif (!cant_be_filename) {\n    - \t\t*dotdot = '.';\n    --\t\tverify_non_filename(revs->prefix, arg);\n    -+\t\tverify_non_filename(the_repository, revs->prefix, arg);\n    - \t\t*dotdot = '\\0';\n    +-\t\tverify_non_filename(revs->prefix, full_name);\n    ++\t\tverify_non_filename(the_repository, revs->prefix, full_name);\n      \t}\n      \n    + \ta_obj = parse_object(revs->repo, &a_oid);\n     @@ revision.c: static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl\n      \t\tgoto out;\n      \t}\n 8:  54192c579e =  8:  87fe43bf7c setup: stop using `the_repository` in `enter_repo()`\n 9:  78ae1d0845 !  9:  897a0ac4a6 setup: stop using `the_repository` in `setup_work_tree()`\n    @@ Commit message\n         the repository as a parameter. The injection of `the_repository` is thus\n         bumped one level higher, where callers now pass it in explicitly.\n     \n    -    Note that the function tracks bogus worktree configuration via a global\n    -    variable. If we have bogus configuration, and if later on some caller\n    -    tries to setup a worktree, then we'll die instead.\n    +    Note that the function tracks two bits of information via global\n    +    variables. This of course doesn't make much sense anymore now that we\n    +    can set up worktrees for arbitrary repositories:\n     \n    -    Of course, tracking this as a global variable doesn't make sense anymore\n    -    now that we can set up worktrees for arbitrary repositories. Move the\n    -    variable into `struct repository` instead.\n    +      - We track whether the worktree has already been initialized and, if\n    +        so, we skip the call to `chdir_notify()` and setenv(3p). It does not\n    +        make much sense to store this info in the repository, as we _would_\n    +        want to update the environment when switching between worktrees back\n    +        and forth.\n    +\n    +        So instead of storing this info in the repository, we drop this\n    +        state entirely and live with the fact that we may execute the logic\n    +        twice. It should ultimately be idempotent though and thus not be\n    +        much of a problem.\n    +\n    +      - We track whether the worktree configuration is bogus. If so, and if\n    +        later on some caller tries to setup the worktree, then we'll die\n    +        instead. This is indeed information that we can move into the\n    +        repository itself.\n     \n         Signed-off-by: Patrick Steinhardt <ps@pks.im>\n     \n    @@ setup.c\n      \tALLOWED_BARE_REPO_EXPLICIT = 0,\n      \tALLOWED_BARE_REPO_ALL,\n     @@ setup.c: int is_inside_work_tree(struct repository *repo)\n    - \treturn is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n    + \treturn ret;\n      }\n      \n     -void setup_work_tree(void)\n     +void setup_work_tree(struct repository *repo)\n      {\n      \tconst char *work_tree;\n    - \tstatic int initialized = 0;\n    -@@ setup.c: void setup_work_tree(void)\n    - \tif (initialized)\n    - \t\treturn;\n    +-\tstatic int initialized = 0;\n      \n    +-\tif (initialized)\n    +-\t\treturn;\n    +-\n     -\tif (work_tree_config_is_bogus)\n     +\tif (repo->worktree_config_is_bogus)\n      \t\tdie(_(\"unable to set up work tree using invalid config\"));\n    @@ setup.c: void setup_work_tree(void)\n      \tif (!work_tree || chdir_notify(work_tree))\n      \t\tdie(_(\"this operation must be run in a work tree\"));\n      \n    +@@ setup.c: void setup_work_tree(void)\n    + \t */\n    + \tif (getenv(GIT_WORK_TREE_ENVIRONMENT))\n    + \t\tsetenv(GIT_WORK_TREE_ENVIRONMENT, \".\", 1);\n    +-\n    +-\tinitialized = 1;\n    + }\n    + \n    + static void setup_original_cwd(struct repository *repo)\n     @@ setup.c: static const char *setup_explicit_git_dir(struct repository *repo,\n      \t\tif (git_work_tree_cfg) {\n      \t\t\t/* #22.2, #30 */\n10:  f2f0c80991 ! 10:  f1ceac2491 setup: stop using `the_repository` in `set_git_work_tree()`\n    @@ setup.c: const char *enter_repo(struct repository *repo, const char *path, unsig\n      \t}\n     -\tgit_work_tree_initialized = 1;\n     -\trepo_set_worktree(the_repository, new_work_tree);\n    -+\trepo->worktree_initialized = 1;\n    ++\trepo->worktree_initialized = true;\n     +\trepo_set_worktree(repo, new_work_tree);\n      }\n      \n11:  0c72972ba4 = 11:  f7de435b86 setup: stop using `the_repository` in `setup_git_env()`\n12:  7a758cf4de = 12:  aea92d5f0a setup: stop using `the_repository` in `setup_git_directory_gently()`\n13:  7485a9e031 = 13:  4981d7d67d setup: stop using `the_repository` in `setup_git_directory()`\n14:  5397aac8e7 = 14:  046de3ad97 setup: stop using `the_repository` in `upgrade_repository_format()`\n15:  f713bdb472 ! 15:  905b7dbb89 setup: stop using `the_repository` in `check_repository_format()`\n    @@ setup.c: enum discovery_result discover_git_directory_reason(struct strbuf *comm\n      }\n      \n     +/*\n    -+ * Check the repository format version in the path found in repo_get_git_dir(the_repository),\n    ++ * Check the repository format version in the path found in repo_get_git_dir(repo),\n     + * and die if it is a version we don't understand. Generally one would\n     + * set_git_dir() before calling this, and use it only for \"are we in a valid\n     + * repo?\".\n16:  0e1931e40f = 16:  bdf0a02c59 setup: stop using `the_repository` in `initialize_repository_version()`\n17:  9cddc161a6 = 17:  74bd848268 setup: stop using `the_repository` in `create_reference_database()`\n18:  996771094d = 18:  6fa2476a01 setup: stop using `the_repository` in `init_db()`\n\n---\nbase-commit: 59ff4886a579f4bc91e976fe18590b9ae02c7a08\nchange-id: 20260330-pks-setup-wo-the-repository-81e51bc55b91\n\n"},{"id":"543507","messageId":"20260518-pks-setup-wo-the-repository-v2-1-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 01/18] setup: replace use of `the_repository` in static functions","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:30:52Z","receivedAt":"2026-05-18T09:31:11Z","isPatch":true,"body":"Replace the use of `the_repository` in \"setup.c\" for all static\nfunctions. For now, we simply add `the_repository` to invocations of\nthese functions. This will be addressed in subsequent commits, where\nwe'll move up `the_repository` one more layer to callers of \"setup.c\".\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n setup.c | 188 ++++++++++++++++++++++++++++++++++------------------------------\n 1 file changed, 100 insertions(+), 88 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex 7ec4427368..ba2898473a 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -50,13 +50,13 @@ const char *tmp_original_cwd;\n  * /dir/repolink/file     (repolink points to /dir/repo) -> file\n  * /dir/repo              (exactly equal to work tree)   -> (empty string)\n  */\n-static int abspath_part_inside_repo(char *path)\n+static int abspath_part_inside_repo(struct repository *repo, char *path)\n {\n \tsize_t len;\n \tsize_t wtlen;\n \tchar *path0;\n \tint off;\n-\tconst char *work_tree = precompose_string_if_needed(repo_get_work_tree(the_repository));\n+\tconst char *work_tree = precompose_string_if_needed(repo_get_work_tree(repo));\n \tstruct strbuf realpath = STRBUF_INIT;\n \n \tif (!work_tree)\n@@ -132,7 +132,7 @@ char *prefix_path_gently(const char *prefix, int len,\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n-\t\tif (abspath_part_inside_repo(sanitized)) {\n+\t\tif (abspath_part_inside_repo(the_repository, sanitized)) {\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n@@ -509,7 +509,7 @@ void setup_work_tree(void)\n \tinitialized = 1;\n }\n \n-static void setup_original_cwd(void)\n+static void setup_original_cwd(struct repository *repo)\n {\n \tstruct strbuf tmp = STRBUF_INIT;\n \tconst char *worktree = NULL;\n@@ -535,9 +535,9 @@ static void setup_original_cwd(void)\n \n \t/* Normalize the directory */\n \tif (!strbuf_realpath(&tmp, tmp_original_cwd, 0)) {\n-\t\ttrace2_data_string(\"setup\", the_repository,\n+\t\ttrace2_data_string(\"setup\", repo,\n \t\t\t\t   \"realpath-path\", tmp_original_cwd);\n-\t\ttrace2_data_string(\"setup\", the_repository,\n+\t\ttrace2_data_string(\"setup\", repo,\n \t\t\t\t   \"realpath-failure\", strerror(errno));\n \t\tfree((char*)tmp_original_cwd);\n \t\ttmp_original_cwd = NULL;\n@@ -552,7 +552,7 @@ static void setup_original_cwd(void)\n \t * Get our worktree; we only protect the current working directory\n \t * if it's in the worktree.\n \t */\n-\tworktree = repo_get_work_tree(the_repository);\n+\tworktree = repo_get_work_tree(repo);\n \tif (!worktree)\n \t\tgoto no_prevention_needed;\n \n@@ -747,7 +747,10 @@ static int check_repo_format(const char *var, const char *value,\n \treturn read_worktree_config(var, value, ctx, vdata);\n }\n \n-static int check_repository_format_gently(const char *gitdir, struct repository_format *candidate, int *nongit_ok)\n+static int check_repository_format_gently(struct repository *repo,\n+\t\t\t\t\t  const char *gitdir,\n+\t\t\t\t\t  struct repository_format *candidate,\n+\t\t\t\t\t  int *nongit_ok)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n \tstruct strbuf err = STRBUF_INIT;\n@@ -776,7 +779,7 @@ static int check_repository_format_gently(const char *gitdir, struct repository_\n \t\tdie(\"%s\", err.buf);\n \t}\n \n-\tthe_repository->repository_format_precious_objects = candidate->precious_objects;\n+\trepo->repository_format_precious_objects = candidate->precious_objects;\n \n \tstring_list_clear(&candidate->unknown_extensions, 0);\n \tstring_list_clear(&candidate->v1_only_extensions, 0);\n@@ -1034,7 +1037,8 @@ const char *read_gitfile_gently(const char *path, int *return_error_code)\n \treturn error_code ? NULL : path;\n }\n \n-static void setup_git_env_internal(const char *git_dir,\n+static void setup_git_env_internal(struct repository *repo,\n+\t\t\t\t   const char *git_dir,\n \t\t\t\t   bool skip_initializing_odb)\n {\n \tchar *git_replace_ref_base;\n@@ -1052,7 +1056,7 @@ static void setup_git_env_internal(const char *git_dir,\n \t\targs.disable_ref_updates = true;\n \targs.skip_initializing_odb = skip_initializing_odb;\n \n-\trepo_set_gitdir(the_repository, git_dir, &args);\n+\trepo_set_gitdir(repo, git_dir, &args);\n \tstrvec_clear(&to_free);\n \n \tif (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))\n@@ -1064,7 +1068,7 @@ static void setup_git_env_internal(const char *git_dir,\n \n \tshallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);\n \tif (shallow_file)\n-\t\tset_alternate_shallow_file(the_repository, shallow_file, 0);\n+\t\tset_alternate_shallow_file(repo, shallow_file, 0);\n \n \tif (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0))\n \t\tfetch_if_missing = 0;\n@@ -1072,30 +1076,31 @@ static void setup_git_env_internal(const char *git_dir,\n \n void setup_git_env(const char *git_dir)\n {\n-\tsetup_git_env_internal(git_dir, false);\n+\tsetup_git_env_internal(the_repository, git_dir, false);\n }\n \n-static void set_git_dir_1(const char *path, bool skip_initializing_odb)\n+static void set_git_dir_1(struct repository *repo, const char *path, bool skip_initializing_odb)\n {\n \txsetenv(GIT_DIR_ENVIRONMENT, path, 1);\n-\tsetup_git_env_internal(path, skip_initializing_odb);\n+\tsetup_git_env_internal(repo, path, skip_initializing_odb);\n }\n \n static void update_relative_gitdir(const char *name UNUSED,\n \t\t\t\t   const char *old_cwd,\n \t\t\t\t   const char *new_cwd,\n-\t\t\t\t   void *data UNUSED)\n+\t\t\t\t   void *data)\n {\n+\tstruct repository *repo = data;\n \tchar *path = reparent_relative_path(old_cwd, new_cwd,\n-\t\t\t\t\t    repo_get_git_dir(the_repository));\n+\t\t\t\t\t    repo_get_git_dir(repo));\n \ttrace_printf_key(&trace_setup_key,\n \t\t\t \"setup: move $GIT_DIR to '%s'\",\n \t\t\t path);\n-\tset_git_dir_1(path, true);\n+\tset_git_dir_1(repo, path, true);\n \tfree(path);\n }\n \n-static void set_git_dir(const char *path, int make_realpath)\n+static void set_git_dir(struct repository *repo, const char *path, int make_realpath)\n {\n \tstruct strbuf realpath = STRBUF_INIT;\n \n@@ -1104,14 +1109,15 @@ static void set_git_dir(const char *path, int make_realpath)\n \t\tpath = realpath.buf;\n \t}\n \n-\tset_git_dir_1(path, false);\n+\tset_git_dir_1(repo, path, false);\n \tif (!is_absolute_path(path))\n-\t\tchdir_notify_register(NULL, update_relative_gitdir, NULL);\n+\t\tchdir_notify_register(NULL, update_relative_gitdir, repo);\n \n \tstrbuf_release(&realpath);\n }\n \n-static const char *setup_explicit_git_dir(const char *gitdirenv,\n+static const char *setup_explicit_git_dir(struct repository *repo,\n+\t\t\t\t\t  const char *gitdirenv,\n \t\t\t\t\t  struct strbuf *cwd,\n \t\t\t\t\t  struct repository_format *repo_fmt,\n \t\t\t\t\t  int *nongit_ok)\n@@ -1139,7 +1145,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t\tdie(_(\"not a git repository: '%s'\"), gitdirenv);\n \t}\n \n-\tif (check_repository_format_gently(gitdirenv, repo_fmt, nongit_ok)) {\n+\tif (check_repository_format_gently(repo, gitdirenv, repo_fmt, nongit_ok)) {\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n@@ -1155,7 +1161,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t\t}\n \n \t\t/* #18, #26 */\n-\t\tset_git_dir(gitdirenv, 0);\n+\t\tset_git_dir(repo, gitdirenv, 0);\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n@@ -1177,7 +1183,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t}\n \telse if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) {\n \t\t/* #16d */\n-\t\tset_git_dir(gitdirenv, 0);\n+\t\tset_git_dir(repo, gitdirenv, 0);\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n@@ -1185,18 +1191,18 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t\tset_git_work_tree(\".\");\n \n \t/* set_git_work_tree() must have been called by now */\n-\tworktree = repo_get_work_tree(the_repository);\n+\tworktree = repo_get_work_tree(repo);\n \n \t/* both repo_get_work_tree() and cwd are already normalized */\n \tif (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */\n-\t\tset_git_dir(gitdirenv, 0);\n+\t\tset_git_dir(repo, gitdirenv, 0);\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n \n \toffset = dir_inside_of(cwd->buf, worktree);\n \tif (offset >= 0) {\t/* cwd inside worktree? */\n-\t\tset_git_dir(gitdirenv, 1);\n+\t\tset_git_dir(repo, gitdirenv, 1);\n \t\tif (chdir(worktree))\n \t\t\tdie_errno(_(\"cannot chdir to '%s'\"), worktree);\n \t\tstrbuf_addch(cwd, '/');\n@@ -1205,17 +1211,18 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t}\n \n \t/* cwd outside worktree */\n-\tset_git_dir(gitdirenv, 0);\n+\tset_git_dir(repo, gitdirenv, 0);\n \tfree(gitfile);\n \treturn NULL;\n }\n \n-static const char *setup_discovered_git_dir(const char *gitdir,\n+static const char *setup_discovered_git_dir(struct repository *repo,\n+\t\t\t\t\t    const char *gitdir,\n \t\t\t\t\t    struct strbuf *cwd, int offset,\n \t\t\t\t\t    struct repository_format *repo_fmt,\n \t\t\t\t\t    int *nongit_ok)\n {\n-\tif (check_repository_format_gently(gitdir, repo_fmt, nongit_ok))\n+\tif (check_repository_format_gently(repo, gitdir, repo_fmt, nongit_ok))\n \t\treturn NULL;\n \n \t/* --work-tree is set without --git-dir; use discovered one */\n@@ -1227,14 +1234,14 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n \t\t\tgitdir = to_free = real_pathdup(gitdir, 1);\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n-\t\tret = setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);\n+\t\tret = setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n \t\tfree(to_free);\n \t\treturn ret;\n \t}\n \n \t/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */\n \tif (is_bare_repository_cfg > 0) {\n-\t\tset_git_dir(gitdir, (offset != cwd->len));\n+\t\tset_git_dir(repo, gitdir, (offset != cwd->len));\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n \t\treturn NULL;\n@@ -1243,7 +1250,7 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n \t/* #0, #1, #5, #8, #9, #12, #13 */\n \tset_git_work_tree(\".\");\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n-\t\tset_git_dir(gitdir, 0);\n+\t\tset_git_dir(repo, gitdir, 0);\n \tinside_git_dir = 0;\n \tinside_work_tree = 1;\n \tif (offset >= cwd->len)\n@@ -1258,13 +1265,14 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n }\n \n /* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */\n-static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n+static const char *setup_bare_git_dir(struct repository *repo,\n+\t\t\t\t      struct strbuf *cwd, int offset,\n \t\t\t\t      struct repository_format *repo_fmt,\n \t\t\t\t      int *nongit_ok)\n {\n \tint root_len;\n \n-\tif (check_repository_format_gently(\".\", repo_fmt, nongit_ok))\n+\tif (check_repository_format_gently(repo, \".\", repo_fmt, nongit_ok))\n \t\treturn NULL;\n \n \tsetenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, \"0\", 1);\n@@ -1276,7 +1284,7 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n \t\tgitdir = offset == cwd->len ? \".\" : xmemdupz(cwd->buf, offset);\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n-\t\treturn setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);\n+\t\treturn setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n \t}\n \n \tinside_git_dir = 1;\n@@ -1286,10 +1294,10 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n \t\troot_len = offset_1st_component(cwd->buf);\n \t\tstrbuf_setlen(cwd, offset > root_len ? offset : root_len);\n-\t\tset_git_dir(cwd->buf, 0);\n+\t\tset_git_dir(repo, cwd->buf, 0);\n \t}\n \telse\n-\t\tset_git_dir(\".\", 0);\n+\t\tset_git_dir(repo, \".\", 0);\n \treturn NULL;\n }\n \n@@ -1827,7 +1835,7 @@ const char *enter_repo(const char *path, unsigned flags)\n \t}\n \n \tif (is_git_directory(\".\")) {\n-\t\tset_git_dir(\".\", 0);\n+\t\tset_git_dir(the_repository, \".\", 0);\n \t\tcheck_repository_format(NULL);\n \t\treturn path;\n \t}\n@@ -1891,18 +1899,18 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \n \tswitch (setup_git_directory_gently_1(&dir, &gitdir, &report, 1)) {\n \tcase GIT_DIR_EXPLICIT:\n-\t\tprefix = setup_explicit_git_dir(gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_explicit_git_dir(the_repository, gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_DISCOVERED:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_discovered_git_dir(gitdir.buf, &cwd, dir.len,\n+\t\tprefix = setup_discovered_git_dir(the_repository, gitdir.buf, &cwd, dir.len,\n \t\t\t\t\t\t  &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_BARE:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_bare_git_dir(&cwd, dir.len, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_bare_git_dir(the_repository, &cwd, dir.len, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_HIT_CEILING:\n \t\tif (!nongit_ok)\n@@ -2044,7 +2052,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\tfree(payload);\n \t}\n \n-\tsetup_original_cwd();\n+\tsetup_original_cwd(the_repository);\n \n \tstrbuf_release(&dir);\n \tstrbuf_release(&gitdir);\n@@ -2110,7 +2118,7 @@ void check_repository_format(struct repository_format *fmt)\n \tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n \tif (!fmt)\n \t\tfmt = &repo_fmt;\n-\tcheck_repository_format_gently(repo_get_git_dir(the_repository), fmt, NULL);\n+\tcheck_repository_format_gently(the_repository, repo_get_git_dir(the_repository), fmt, NULL);\n \tstartup_info->have_repository = 1;\n \trepo_set_hash_algo(the_repository, fmt->hash_algo);\n \trepo_set_compat_hash_algo(the_repository, fmt->compat_hash_algo);\n@@ -2239,7 +2247,9 @@ const char *get_template_dir(const char *option_template)\n \n #define GIT_DEFAULT_HASH_ENVIRONMENT \"GIT_DEFAULT_HASH\"\n \n-static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n+static void copy_templates_1(struct repository *repo,\n+\t\t\t     struct strbuf *path,\n+\t\t\t     struct strbuf *template_path,\n \t\t\t     DIR *dir)\n {\n \tsize_t path_baselen = path->len;\n@@ -2253,7 +2263,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n \t * with the way the namespace under .git/ is organized, should\n \t * be really carefully chosen.\n \t */\n-\tsafe_create_dir(the_repository, path->buf, 1);\n+\tsafe_create_dir(repo, path->buf, 1);\n \twhile ((de = readdir(dir)) != NULL) {\n \t\tstruct stat st_git, st_template;\n \t\tint exists = 0;\n@@ -2281,7 +2291,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n \t\t\t\tdie_errno(_(\"cannot opendir '%s'\"), template_path->buf);\n \t\t\tstrbuf_addch(path, '/');\n \t\t\tstrbuf_addch(template_path, '/');\n-\t\t\tcopy_templates_1(path, template_path, subdir);\n+\t\t\tcopy_templates_1(repo, path, template_path, subdir);\n \t\t\tclosedir(subdir);\n \t\t}\n \t\telse if (exists)\n@@ -2306,7 +2316,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n \t}\n }\n \n-static void copy_templates(const char *option_template)\n+static void copy_templates(struct repository *repo, const char *option_template)\n {\n \tconst char *template_dir = get_template_dir(option_template);\n \tstruct strbuf path = STRBUF_INIT;\n@@ -2347,9 +2357,9 @@ static void copy_templates(const char *option_template)\n \t\tgoto close_free_return;\n \t}\n \n-\tstrbuf_addstr(&path, repo_get_common_dir(the_repository));\n+\tstrbuf_addstr(&path, repo_get_common_dir(repo));\n \tstrbuf_complete(&path, '/');\n-\tcopy_templates_1(&path, &template_path, dir);\n+\tcopy_templates_1(repo, &path, &template_path, dir);\n close_free_return:\n \tclosedir(dir);\n free_return:\n@@ -2443,13 +2453,13 @@ void initialize_repository_version(int hash_algo,\n \tstrbuf_release(&repo_version);\n }\n \n-static int is_reinit(void)\n+static int is_reinit(struct repository *repo)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tchar junk[2];\n \tint ret;\n \n-\trepo_git_path_replace(the_repository, &buf, \"HEAD\");\n+\trepo_git_path_replace(repo, &buf, \"HEAD\");\n \tret = !access(buf.buf, R_OK) || readlink(buf.buf, junk, sizeof(junk) - 1) != -1;\n \tstrbuf_release(&buf);\n \treturn ret;\n@@ -2459,7 +2469,7 @@ void create_reference_database(const char *initial_branch, int quiet)\n {\n \tstruct strbuf err = STRBUF_INIT;\n \tchar *to_free = NULL;\n-\tint reinit = is_reinit();\n+\tint reinit = is_reinit(the_repository);\n \n \tif (ref_store_create_on_disk(get_main_ref_store(the_repository), 0, &err))\n \t\tdie(\"failed to set up refs db: %s\", err.buf);\n@@ -2493,7 +2503,8 @@ void create_reference_database(const char *initial_branch, int quiet)\n \tfree(to_free);\n }\n \n-static int create_default_files(const char *template_path,\n+static int create_default_files(struct repository *repo,\n+\t\t\t\tconst char *template_path,\n \t\t\t\tconst char *original_git_dir,\n \t\t\t\tconst struct repository_format *fmt,\n \t\t\t\tint init_shared_repository)\n@@ -2502,7 +2513,7 @@ static int create_default_files(const char *template_path,\n \tstruct strbuf path = STRBUF_INIT;\n \tint reinit;\n \tint filemode;\n-\tconst char *work_tree = repo_get_work_tree(the_repository);\n+\tconst char *work_tree = repo_get_work_tree(repo);\n \n \t/*\n \t * First copy the templates -- we might have the default\n@@ -2513,19 +2524,19 @@ static int create_default_files(const char *template_path,\n \t * values (since we've just potentially changed what's available on\n \t * disk).\n \t */\n-\tcopy_templates(template_path);\n-\trepo_config_clear(the_repository);\n-\trepo_settings_reset_shared_repository(the_repository);\n-\trepo_config(the_repository, git_default_config, NULL);\n+\tcopy_templates(repo, template_path);\n+\trepo_config_clear(repo);\n+\trepo_settings_reset_shared_repository(repo);\n+\trepo_config(repo, git_default_config, NULL);\n \n-\treinit = is_reinit();\n+\treinit = is_reinit(repo);\n \n \t/*\n \t * We must make sure command-line options continue to override any\n \t * values we might have just re-read from the config.\n \t */\n \tif (init_shared_repository != -1)\n-\t\trepo_settings_set_shared_repository(the_repository,\n+\t\trepo_settings_set_shared_repository(repo,\n \t\t\t\t\t\t    init_shared_repository);\n \n \tis_bare_repository_cfg = !work_tree;\n@@ -2534,14 +2545,14 @@ static int create_default_files(const char *template_path,\n \t * We would have created the above under user's umask -- under\n \t * shared-repository settings, we would need to fix them up.\n \t */\n-\tif (repo_settings_get_shared_repository(the_repository)) {\n-\t\tadjust_shared_perm(the_repository, repo_get_git_dir(the_repository));\n+\tif (repo_settings_get_shared_repository(repo)) {\n+\t\tadjust_shared_perm(repo, repo_get_git_dir(repo));\n \t}\n \n \tinitialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, reinit);\n \n \t/* Check filemode trustability */\n-\trepo_git_path_replace(the_repository, &path, \"config\");\n+\trepo_git_path_replace(repo, &path, \"config\");\n \tfilemode = TEST_FILEMODE;\n \tif (TEST_FILEMODE && !lstat(path.buf, &st1)) {\n \t\tstruct stat st2;\n@@ -2552,22 +2563,22 @@ static int create_default_files(const char *template_path,\n \t\tif (filemode && !reinit && (st1.st_mode & S_IXUSR))\n \t\t\tfilemode = 0;\n \t}\n-\trepo_config_set(the_repository, \"core.filemode\", filemode ? \"true\" : \"false\");\n+\trepo_config_set(repo, \"core.filemode\", filemode ? \"true\" : \"false\");\n \n \tif (is_bare_repository())\n-\t\trepo_config_set(the_repository, \"core.bare\", \"true\");\n+\t\trepo_config_set(repo, \"core.bare\", \"true\");\n \telse {\n-\t\trepo_config_set(the_repository, \"core.bare\", \"false\");\n+\t\trepo_config_set(repo, \"core.bare\", \"false\");\n \t\t/* allow template config file to override the default */\n-\t\tif (repo_settings_get_log_all_ref_updates(the_repository) == LOG_REFS_UNSET)\n-\t\t\trepo_config_set(the_repository, \"core.logallrefupdates\", \"true\");\n+\t\tif (repo_settings_get_log_all_ref_updates(repo) == LOG_REFS_UNSET)\n+\t\t\trepo_config_set(repo, \"core.logallrefupdates\", \"true\");\n \t\tif (needs_work_tree_config(original_git_dir, work_tree))\n-\t\t\trepo_config_set(the_repository, \"core.worktree\", work_tree);\n+\t\t\trepo_config_set(repo, \"core.worktree\", work_tree);\n \t}\n \n \tif (!reinit) {\n \t\t/* Check if symlink is supported in the work tree */\n-\t\trepo_git_path_replace(the_repository, &path, \"tXXXXXX\");\n+\t\trepo_git_path_replace(repo, &path, \"tXXXXXX\");\n \t\tif (!close(xmkstemp(path.buf)) &&\n \t\t    !unlink(path.buf) &&\n \t\t    !symlink(\"testing\", path.buf) &&\n@@ -2575,12 +2586,12 @@ static int create_default_files(const char *template_path,\n \t\t    S_ISLNK(st1.st_mode))\n \t\t\tunlink(path.buf); /* good */\n \t\telse\n-\t\t\trepo_config_set(the_repository, \"core.symlinks\", \"false\");\n+\t\t\trepo_config_set(repo, \"core.symlinks\", \"false\");\n \n \t\t/* Check if the filesystem is case-insensitive */\n-\t\trepo_git_path_replace(the_repository, &path, \"CoNfIg\");\n+\t\trepo_git_path_replace(repo, &path, \"CoNfIg\");\n \t\tif (!access(path.buf, F_OK))\n-\t\t\trepo_config_set(the_repository, \"core.ignorecase\", \"true\");\n+\t\t\trepo_config_set(repo, \"core.ignorecase\", \"true\");\n \t\tprobe_utf8_pathname_composition();\n \t}\n \n@@ -2588,23 +2599,23 @@ static int create_default_files(const char *template_path,\n \treturn reinit;\n }\n \n-static void create_object_directory(void)\n+static void create_object_directory(struct repository *repo)\n {\n \tstruct strbuf path = STRBUF_INIT;\n \tsize_t baselen;\n \n-\tstrbuf_addstr(&path, repo_get_object_directory(the_repository));\n+\tstrbuf_addstr(&path, repo_get_object_directory(repo));\n \tbaselen = path.len;\n \n-\tsafe_create_dir(the_repository, path.buf, 1);\n+\tsafe_create_dir(repo, path.buf, 1);\n \n \tstrbuf_setlen(&path, baselen);\n \tstrbuf_addstr(&path, \"/pack\");\n-\tsafe_create_dir(the_repository, path.buf, 1);\n+\tsafe_create_dir(repo, path.buf, 1);\n \n \tstrbuf_setlen(&path, baselen);\n \tstrbuf_addstr(&path, \"/info\");\n-\tsafe_create_dir(the_repository, path.buf, 1);\n+\tsafe_create_dir(repo, path.buf, 1);\n \n \tstrbuf_release(&path);\n }\n@@ -2682,7 +2693,8 @@ static int read_default_format_config(const char *key, const char *value,\n \treturn ret;\n }\n \n-static void repository_format_configure(struct repository_format *repo_fmt,\n+static void repository_format_configure(struct repository *repo,\n+\t\t\t\t\tstruct repository_format *repo_fmt,\n \t\t\t\t\tint hash, enum ref_storage_format ref_format)\n {\n \tstruct default_format_config cfg = {\n@@ -2719,7 +2731,7 @@ static void repository_format_configure(struct repository_format *repo_fmt,\n \t} else if (cfg.hash != GIT_HASH_UNKNOWN) {\n \t\trepo_fmt->hash_algo = cfg.hash;\n \t}\n-\trepo_set_hash_algo(the_repository, repo_fmt->hash_algo);\n+\trepo_set_hash_algo(repo, repo_fmt->hash_algo);\n \n \tenv = getenv(\"GIT_DEFAULT_REF_FORMAT\");\n \tif (repo_fmt->version >= 0 &&\n@@ -2758,7 +2770,7 @@ static void repository_format_configure(struct repository_format *repo_fmt,\n \t\tfree(backend);\n \t}\n \n-\trepo_set_ref_storage_format(the_repository, repo_fmt->ref_storage_format,\n+\trepo_set_ref_storage_format(repo, repo_fmt->ref_storage_format,\n \t\t\t\t    repo_fmt->ref_storage_payload);\n }\n \n@@ -2782,12 +2794,12 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\tif (!exist_ok && !stat(real_git_dir, &st))\n \t\t\tdie(_(\"%s already exists\"), real_git_dir);\n \n-\t\tset_git_dir(real_git_dir, 1);\n+\t\tset_git_dir(the_repository, real_git_dir, 1);\n \t\tgit_dir = repo_get_git_dir(the_repository);\n \t\tseparate_git_dir(git_dir, original_git_dir);\n \t}\n \telse {\n-\t\tset_git_dir(git_dir, 1);\n+\t\tset_git_dir(the_repository, git_dir, 1);\n \t\tgit_dir = repo_get_git_dir(the_repository);\n \t}\n \tstartup_info->have_repository = 1;\n@@ -2800,7 +2812,7 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t */\n \tcheck_repository_format(&repo_fmt);\n \n-\trepository_format_configure(&repo_fmt, hash, ref_storage_format);\n+\trepository_format_configure(the_repository, &repo_fmt, hash, ref_storage_format);\n \n \t/*\n \t * Ensure `core.hidedotfiles` is processed. This must happen after we\n@@ -2811,12 +2823,12 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \n \tsafe_create_dir(the_repository, git_dir, 0);\n \n-\treinit = create_default_files(template_dir, original_git_dir,\n+\treinit = create_default_files(the_repository, template_dir, original_git_dir,\n \t\t\t\t      &repo_fmt, init_shared_repository);\n \n \tif (!(flags & INIT_DB_SKIP_REFDB))\n \t\tcreate_reference_database(initial_branch, flags & INIT_DB_QUIET);\n-\tcreate_object_directory();\n+\tcreate_object_directory(the_repository);\n \n \tif (repo_settings_get_shared_repository(the_repository)) {\n \t\tchar buf[10];\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543508","messageId":"20260518-pks-setup-wo-the-repository-v2-2-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 02/18] setup: stop using `the_repository` in `is_inside_worktree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:30:53Z","receivedAt":"2026-05-18T09:31:13Z","isPatch":true,"body":"The function `is_inside_worktree()` verifies whether or not the current\nworking directory is located inside the worktree of `the_repository`.\nThis is done by taking the worktree path and verifying that it's a\nprefix of the current working directory.\n\nThis information is cached so that we don't have to re-do this change\nmultiple times. Furthermore, we proactively set the value in multiple\nlocations so that we don't even have to perform the check when we have\ndiscovered the repository.\n\nWhile we could simply move the caching variable into the repository, the\ncurrent layout doesn't really feel sensible in the first place:\n\n  - It can easily lead to false positives or negatives if at any point\n    in time we may switch the current working directory.\n\n  - We don't call the function in a hot loop, and neither is it overly\n    expensive to compute.\n\nDrop the caching infrastructure and instead compute the property ad-hoc\nvia an injected repository.\n\nNote that there is one small gotcha: we sometimes may end up with\nrelative directory paths, and if so `is_inside_dir()` might fail. This\nwasn't an issue before because of how we proactively set the cached\nvalue during repository discovery. Now that we stop doing that it\nbecomes a problem though, but it is worked around by resolving the\nrepository directory via `realpath()`.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/ls-files.c  |  2 +-\n builtin/rev-parse.c |  4 ++--\n object-name.c       |  2 +-\n setup.c             | 25 ++++++++++++++-----------\n setup.h             |  2 +-\n submodule.c         |  2 +-\n 6 files changed, 20 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex b148607f7a..09d95111b3 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -703,7 +703,7 @@ int cmd_ls_files(int argc,\n \tif (dir.exclude_per_dir)\n \t\texc_given = 1;\n \n-\tif (require_work_tree && !is_inside_work_tree())\n+\tif (require_work_tree && !is_inside_work_tree(repo))\n \t\tsetup_work_tree();\n \n \tif (recurse_submodules &&\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 218b5f34d6..52709ca69b 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -1006,7 +1006,7 @@ int cmd_rev_parse(int argc,\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--show-cdup\")) {\n \t\t\t\tconst char *pfx = prefix;\n-\t\t\t\tif (!is_inside_work_tree()) {\n+\t\t\t\tif (!is_inside_work_tree(the_repository)) {\n \t\t\t\t\tconst char *work_tree =\n \t\t\t\t\t\trepo_get_work_tree(the_repository);\n \t\t\t\t\tif (work_tree)\n@@ -1068,7 +1068,7 @@ int cmd_rev_parse(int argc,\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--is-inside-work-tree\")) {\n-\t\t\t\tprintf(\"%s\\n\", is_inside_work_tree() ? \"true\"\n+\t\t\t\tprintf(\"%s\\n\", is_inside_work_tree(the_repository) ? \"true\"\n \t\t\t\t\t\t: \"false\");\n \t\t\t\tcontinue;\n \t\t\t}\ndiff --git a/object-name.c b/object-name.c\nindex 21dcdc4a0e..37a9ce8e87 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -1703,7 +1703,7 @@ static char *resolve_relative_path(struct repository *r, const char *rel)\n \tif (!starts_with(rel, \"./\") && !starts_with(rel, \"../\"))\n \t\treturn NULL;\n \n-\tif (r != the_repository || !is_inside_work_tree())\n+\tif (r != the_repository || !is_inside_work_tree(the_repository))\n \t\tdie(_(\"relative path syntax can't be used outside working tree\"));\n \n \t/* die() inside prefix_path() if resolved path is outside worktree */\ndiff --git a/setup.c b/setup.c\nindex ba2898473a..b316d9aaa8 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -27,7 +27,6 @@\n #include \"worktree.h\"\n \n static int inside_git_dir = -1;\n-static int inside_work_tree = -1;\n static int work_tree_config_is_bogus;\n enum allowed_bare_repo {\n \tALLOWED_BARE_REPO_EXPLICIT = 0,\n@@ -299,7 +298,7 @@ void verify_filename(const char *prefix,\n  */\n void verify_non_filename(const char *prefix, const char *arg)\n {\n-\tif (!is_inside_work_tree() || is_inside_git_dir())\n+\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir())\n \t\treturn;\n \tif (*arg == '-')\n \t\treturn; /* flag */\n@@ -477,11 +476,20 @@ int is_inside_git_dir(void)\n \treturn inside_git_dir;\n }\n \n-int is_inside_work_tree(void)\n+int is_inside_work_tree(struct repository *repo)\n {\n-\tif (inside_work_tree < 0)\n-\t\tinside_work_tree = is_inside_dir(repo_get_work_tree(the_repository));\n-\treturn inside_work_tree;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tconst char *worktree;\n+\tint ret;\n+\n+\tworktree = repo_get_work_tree(repo);\n+\tif (!worktree)\n+\t\treturn 0;\n+\n+\tret = is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n+\n+\tstrbuf_release(&buf);\n+\treturn ret;\n }\n \n void setup_work_tree(void)\n@@ -798,13 +806,10 @@ static int check_repository_format_gently(struct repository *repo,\n \tif (!has_common) {\n \t\tif (candidate->is_bare != -1) {\n \t\t\tis_bare_repository_cfg = candidate->is_bare;\n-\t\t\tif (is_bare_repository_cfg == 1)\n-\t\t\t\tinside_work_tree = -1;\n \t\t}\n \t\tif (candidate->work_tree) {\n \t\t\tfree(git_work_tree_cfg);\n \t\t\tgit_work_tree_cfg = xstrdup(candidate->work_tree);\n-\t\t\tinside_work_tree = -1;\n \t\t}\n \t}\n \n@@ -1252,7 +1257,6 @@ static const char *setup_discovered_git_dir(struct repository *repo,\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n \t\tset_git_dir(repo, gitdir, 0);\n \tinside_git_dir = 0;\n-\tinside_work_tree = 1;\n \tif (offset >= cwd->len)\n \t\treturn NULL;\n \n@@ -1288,7 +1292,6 @@ static const char *setup_bare_git_dir(struct repository *repo,\n \t}\n \n \tinside_git_dir = 1;\n-\tinside_work_tree = 0;\n \tif (offset != cwd->len) {\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\ndiff --git a/setup.h b/setup.h\nindex 80bc6e5f07..7c0aa75319 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -5,7 +5,7 @@\n #include \"string-list.h\"\n \n int is_inside_git_dir(void);\n-int is_inside_work_tree(void);\n+int is_inside_work_tree(struct repository *repo);\n int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);\n int get_common_dir(struct strbuf *sb, const char *gitdir);\n \ndiff --git a/submodule.c b/submodule.c\nindex b1a0363f9d..a939ff5072 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -2620,7 +2620,7 @@ int get_superproject_working_tree(struct strbuf *buf)\n \tint code;\n \tssize_t len;\n \n-\tif (!is_inside_work_tree())\n+\tif (!is_inside_work_tree(the_repository))\n \t\t/*\n \t\t * FIXME:\n \t\t * We might have a superproject, but it is harder\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543509","messageId":"20260518-pks-setup-wo-the-repository-v2-3-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 03/18] setup: stop using `the_repository` in `is_inside_git_dir()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:30:54Z","receivedAt":"2026-05-18T09:31:14Z","isPatch":true,"body":"Similar as with the preceding commit, `is_inside_git_dir()` determines\nwhether the current working directory is located inside the gitdir of\n`the_repository`. Perform the same refactoring by dropping the caching\nmechanism and injecting the repository that shall be checked.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/rev-parse.c |  2 +-\n setup.c             | 14 ++++++--------\n setup.h             |  2 +-\n 3 files changed, 8 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 52709ca69b..2fcd6851d1 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -1063,7 +1063,7 @@ int cmd_rev_parse(int argc,\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--is-inside-git-dir\")) {\n-\t\t\t\tprintf(\"%s\\n\", is_inside_git_dir() ? \"true\"\n+\t\t\t\tprintf(\"%s\\n\", is_inside_git_dir(the_repository) ? \"true\"\n \t\t\t\t\t\t: \"false\");\n \t\t\t\tcontinue;\n \t\t\t}\ndiff --git a/setup.c b/setup.c\nindex b316d9aaa8..041e08b98d 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -26,7 +26,6 @@\n #include \"trace2.h\"\n #include \"worktree.h\"\n \n-static int inside_git_dir = -1;\n static int work_tree_config_is_bogus;\n enum allowed_bare_repo {\n \tALLOWED_BARE_REPO_EXPLICIT = 0,\n@@ -298,7 +297,7 @@ void verify_filename(const char *prefix,\n  */\n void verify_non_filename(const char *prefix, const char *arg)\n {\n-\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir())\n+\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir(the_repository))\n \t\treturn;\n \tif (*arg == '-')\n \t\treturn; /* flag */\n@@ -469,11 +468,12 @@ int is_nonbare_repository_dir(struct strbuf *path)\n \treturn ret;\n }\n \n-int is_inside_git_dir(void)\n+int is_inside_git_dir(struct repository *repo)\n {\n-\tif (inside_git_dir < 0)\n-\t\tinside_git_dir = is_inside_dir(repo_get_git_dir(the_repository));\n-\treturn inside_git_dir;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tint ret = is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));\n+\tstrbuf_release(&buf);\n+\treturn ret;\n }\n \n int is_inside_work_tree(struct repository *repo)\n@@ -1256,7 +1256,6 @@ static const char *setup_discovered_git_dir(struct repository *repo,\n \tset_git_work_tree(\".\");\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n \t\tset_git_dir(repo, gitdir, 0);\n-\tinside_git_dir = 0;\n \tif (offset >= cwd->len)\n \t\treturn NULL;\n \n@@ -1291,7 +1290,6 @@ static const char *setup_bare_git_dir(struct repository *repo,\n \t\treturn setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n \t}\n \n-\tinside_git_dir = 1;\n \tif (offset != cwd->len) {\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\ndiff --git a/setup.h b/setup.h\nindex 7c0aa75319..71d3f91883 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -4,7 +4,7 @@\n #include \"refs.h\"\n #include \"string-list.h\"\n \n-int is_inside_git_dir(void);\n+int is_inside_git_dir(struct repository *repo);\n int is_inside_work_tree(struct repository *repo);\n int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);\n int get_common_dir(struct strbuf *sb, const char *gitdir);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543510","messageId":"20260518-pks-setup-wo-the-repository-v2-4-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 04/18] setup: stop using `the_repository` in `prefix_path()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:30:55Z","receivedAt":"2026-05-18T09:31:17Z","isPatch":true,"body":"Stop using `the_repository` in `prefix_path()` and instead accept the\nrepository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/blame.c            |  2 +-\n builtin/check-attr.c       |  2 +-\n builtin/checkout-index.c   |  4 ++--\n builtin/mv.c               |  5 +++--\n builtin/sparse-checkout.c  |  3 ++-\n builtin/update-index.c     |  6 +++---\n line-log.c                 |  2 +-\n object-name.c              |  2 +-\n pathspec.c                 |  2 +-\n setup.c                    | 15 ++++++++-------\n setup.h                    |  4 ++--\n t/helper/test-path-utils.c |  2 +-\n 12 files changed, 26 insertions(+), 23 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex f3a11eff44..ffbd3ce5c5 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -708,7 +708,7 @@ static unsigned parse_score(const char *arg)\n \n static char *add_prefix(const char *prefix, const char *path)\n {\n-\treturn prefix_path(prefix, prefix ? strlen(prefix) : 0, path);\n+\treturn prefix_path(the_repository, prefix, prefix ? strlen(prefix) : 0, path);\n }\n \n static int git_blame_config(const char *var, const char *value,\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 51ed48ce43..04b86e42ae 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -67,7 +67,7 @@ static void check_attr(const char *prefix, struct attr_check *check,\n \n {\n \tchar *full_path =\n-\t\tprefix_path(prefix, prefix ? strlen(prefix) : 0, file);\n+\t\tprefix_path(the_repository, prefix, prefix ? strlen(prefix) : 0, file);\n \n \tif (collect_all) {\n \t\tgit_all_attrs(the_repository->index, full_path, check);\ndiff --git a/builtin/checkout-index.c b/builtin/checkout-index.c\nindex 188128aebd..311b94ff31 100644\n--- a/builtin/checkout-index.c\n+++ b/builtin/checkout-index.c\n@@ -303,7 +303,7 @@ int cmd_checkout_index(int argc,\n \t\t\tdie(\"git checkout-index: don't mix '--all' and explicit filenames\");\n \t\tif (read_from_stdin)\n \t\t\tdie(\"git checkout-index: don't mix '--stdin' and explicit filenames\");\n-\t\tp = prefix_path(prefix, prefix_length, arg);\n+\t\tp = prefix_path(repo, prefix, prefix_length, arg);\n \t\terr |= checkout_file(repo->index, p, prefix);\n \t\tfree(p);\n \t}\n@@ -325,7 +325,7 @@ int cmd_checkout_index(int argc,\n \t\t\t\t\tdie(\"line is badly quoted\");\n \t\t\t\tstrbuf_swap(&buf, &unquoted);\n \t\t\t}\n-\t\t\tp = prefix_path(prefix, prefix_length, buf.buf);\n+\t\t\tp = prefix_path(repo, prefix, prefix_length, buf.buf);\n \t\t\terr |= checkout_file(repo->index, p, prefix);\n \t\t\tfree(p);\n \t\t}\ndiff --git a/builtin/mv.c b/builtin/mv.c\nindex 2215d34e31..948b330639 100644\n--- a/builtin/mv.c\n+++ b/builtin/mv.c\n@@ -71,7 +71,7 @@ static void internal_prefix_pathspec(struct strvec *out,\n \n \t\ttrimmed = xmemdupz(pathspec[i], to_copy);\n \t\tmaybe_basename = (flags & DUP_BASENAME) ? basename(trimmed) : trimmed;\n-\t\tprefixed_path = prefix_path(prefix, prefixlen, maybe_basename);\n+\t\tprefixed_path = prefix_path(the_repository, prefix, prefixlen, maybe_basename);\n \t\tstrvec_push(out, prefixed_path);\n \n \t\tfree(prefixed_path);\n@@ -394,7 +394,8 @@ int cmd_mv(int argc,\n \t\t\tfor (j = 0; j < last - first; j++) {\n \t\t\t\tconst struct cache_entry *ce = the_repository->index->cache[first + j];\n \t\t\t\tconst char *path = ce->name;\n-\t\t\t\tchar *prefixed_path = prefix_path(dst_with_slash, dst_with_slash_len, path + length + 1);\n+\t\t\t\tchar *prefixed_path = prefix_path(the_repository, dst_with_slash,\n+\t\t\t\t\t\t\t\t  dst_with_slash_len, path + length + 1);\n \n \t\t\t\tstrvec_push(&sources, path);\n \t\t\t\tstrvec_push(&destinations, prefixed_path);\ndiff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c\nindex f4aa405da9..2af50fb2f9 100644\n--- a/builtin/sparse-checkout.c\n+++ b/builtin/sparse-checkout.c\n@@ -735,7 +735,8 @@ static void sanitize_paths(struct repository *repo,\n \t\tint prefix_len = strlen(prefix);\n \n \t\tfor (i = 0; i < args->nr; i++) {\n-\t\t\tchar *prefixed_path = prefix_path(prefix, prefix_len, args->v[i]);\n+\t\t\tchar *prefixed_path = prefix_path(the_repository, prefix,\n+\t\t\t\t\t\t\t  prefix_len, args->v[i]);\n \t\t\tstrvec_replace(args, i, prefixed_path);\n \t\t\tfree(prefixed_path);\n \t\t}\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 8a5907767b..7434112b8e 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -655,7 +655,7 @@ static int do_unresolve(int ac, const char **av,\n \n \tfor (i = 1; i < ac; i++) {\n \t\tconst char *arg = av[i];\n-\t\tchar *p = prefix_path(prefix, prefix_length, arg);\n+\t\tchar *p = prefix_path(the_repository, prefix, prefix_length, arg);\n \t\terr |= unresolve_one(p);\n \t\tfree(p);\n \t}\n@@ -1158,7 +1158,7 @@ int cmd_update_index(int argc,\n \t\t\t}\n \n \t\t\tsetup_work_tree();\n-\t\t\tp = prefix_path(prefix, prefix_length, path);\n+\t\t\tp = prefix_path(the_repository, prefix, prefix_length, path);\n \t\t\tupdate_one(p);\n \t\t\tif (set_executable_bit)\n \t\t\t\tchmod_path(set_executable_bit, p);\n@@ -1208,7 +1208,7 @@ int cmd_update_index(int argc,\n \t\t\t\t\tdie(\"line is badly quoted\");\n \t\t\t\tstrbuf_swap(&buf, &unquoted);\n \t\t\t}\n-\t\t\tp = prefix_path(prefix, prefix_length, buf.buf);\n+\t\t\tp = prefix_path(the_repository, prefix, prefix_length, buf.buf);\n \t\t\tupdate_one(p);\n \t\t\tif (set_executable_bit)\n \t\t\t\tchmod_path(set_executable_bit, p);\ndiff --git a/line-log.c b/line-log.c\nindex 858a899cd2..346c60c554 100644\n--- a/line-log.c\n+++ b/line-log.c\n@@ -589,7 +589,7 @@ parse_lines(struct repository *r, struct commit *commit,\n \t\trange_part = xstrndup(item->string, name_part - item->string);\n \t\tname_part++;\n \n-\t\tfull_name = prefix_path(prefix, prefix ? strlen(prefix) : 0,\n+\t\tfull_name = prefix_path(r, prefix, prefix ? strlen(prefix) : 0,\n \t\t\t\t\tname_part);\n \n \t\tspec = alloc_filespec(full_name);\ndiff --git a/object-name.c b/object-name.c\nindex 37a9ce8e87..9ac86f19c7 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -1707,7 +1707,7 @@ static char *resolve_relative_path(struct repository *r, const char *rel)\n \t\tdie(_(\"relative path syntax can't be used outside working tree\"));\n \n \t/* die() inside prefix_path() if resolved path is outside worktree */\n-\treturn prefix_path(startup_info->prefix,\n+\treturn prefix_path(the_repository, startup_info->prefix,\n \t\t\t   startup_info->prefix ? strlen(startup_info->prefix) : 0,\n \t\t\t   rel);\n }\ndiff --git a/pathspec.c b/pathspec.c\nindex 5993c4afa0..f78b22709c 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -486,7 +486,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,\n \t\tmatch = xstrdup(copyfrom);\n \t\tprefixlen = 0;\n \t} else {\n-\t\tmatch = prefix_path_gently(prefix, prefixlen,\n+\t\tmatch = prefix_path_gently(the_repository, prefix, prefixlen,\n \t\t\t\t\t   &prefixlen, copyfrom);\n \t\tif (!match) {\n \t\t\tconst char *hint_path;\ndiff --git a/setup.c b/setup.c\nindex 041e08b98d..adad6ceec0 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -117,7 +117,8 @@ static int abspath_part_inside_repo(struct repository *repo, char *path)\n  *  ../../sub1/sub2/foo -> sub1/sub2/foo (but no remaining prefix)\n  *  `pwd`/../bar -> sub1/bar       (no remaining prefix)\n  */\n-char *prefix_path_gently(const char *prefix, int len,\n+char *prefix_path_gently(struct repository *repo,\n+\t\t\t const char *prefix, int len,\n \t\t\t int *remaining_prefix, const char *path)\n {\n \tconst char *orig = path;\n@@ -130,7 +131,7 @@ char *prefix_path_gently(const char *prefix, int len,\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n-\t\tif (abspath_part_inside_repo(the_repository, sanitized)) {\n+\t\tif (abspath_part_inside_repo(repo, sanitized)) {\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n@@ -146,13 +147,13 @@ char *prefix_path_gently(const char *prefix, int len,\n \treturn sanitized;\n }\n \n-char *prefix_path(const char *prefix, int len, const char *path)\n+char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path)\n {\n-\tchar *r = prefix_path_gently(prefix, len, NULL, path);\n+\tchar *r = prefix_path_gently(repo, prefix, len, NULL, path);\n \tif (!r) {\n-\t\tconst char *hint_path = repo_get_work_tree(the_repository);\n+\t\tconst char *hint_path = repo_get_work_tree(repo);\n \t\tif (!hint_path)\n-\t\t\thint_path = repo_get_git_dir(the_repository);\n+\t\t\thint_path = repo_get_git_dir(repo);\n \t\tdie(_(\"'%s' is outside repository at '%s'\"), path,\n \t\t    absolute_path(hint_path));\n \t}\n@@ -162,7 +163,7 @@ char *prefix_path(const char *prefix, int len, const char *path)\n int path_inside_repo(const char *prefix, const char *path)\n {\n \tint len = prefix ? strlen(prefix) : 0;\n-\tchar *r = prefix_path_gently(prefix, len, NULL, path);\n+\tchar *r = prefix_path_gently(the_repository, prefix, len, NULL, path);\n \tif (r) {\n \t\tfree(r);\n \t\treturn 1;\ndiff --git a/setup.h b/setup.h\nindex 71d3f91883..24034572b1 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -138,8 +138,8 @@ const char *enter_repo(const char *path, unsigned flags);\n \n const char *setup_git_directory_gently(int *);\n const char *setup_git_directory(void);\n-char *prefix_path(const char *prefix, int len, const char *path);\n-char *prefix_path_gently(const char *prefix, int len, int *remaining, const char *path);\n+char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path);\n+char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\n \n int check_filename(const char *prefix, const char *name);\n void verify_filename(const char *prefix,\ndiff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c\nindex 874542ec34..163fdeefb0 100644\n--- a/t/helper/test-path-utils.c\n+++ b/t/helper/test-path-utils.c\n@@ -379,7 +379,7 @@ int cmd__path_utils(int argc, const char **argv)\n \t\tint nongit_ok;\n \t\tsetup_git_directory_gently(&nongit_ok);\n \t\twhile (argc > 3) {\n-\t\t\tchar *pfx = prefix_path(prefix, prefix_len, argv[3]);\n+\t\t\tchar *pfx = prefix_path(the_repository, prefix, prefix_len, argv[3]);\n \n \t\t\tputs(pfx);\n \t\t\tfree(pfx);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543511","messageId":"20260518-pks-setup-wo-the-repository-v2-5-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 05/18] setup: stop using `the_repository` in `path_inside_repo()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:30:56Z","receivedAt":"2026-05-18T09:31:19Z","isPatch":true,"body":"Stop using `the_repository` in `path_inside_repo()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/diff.c | 4 ++--\n setup.c        | 4 ++--\n setup.h        | 2 +-\n 3 files changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/diff.c b/builtin/diff.c\nindex 0b23c41456..7ddebce2ac 100644\n--- a/builtin/diff.c\n+++ b/builtin/diff.c\n@@ -471,8 +471,8 @@ int cmd_diff(int argc,\n \t\t * as a colourful \"diff\" replacement.\n \t\t */\n \t\tif (nongit || ((argc == i + 2) &&\n-\t\t\t       (!path_inside_repo(prefix, argv[i]) ||\n-\t\t\t\t!path_inside_repo(prefix, argv[i + 1]))))\n+\t\t\t       (!path_inside_repo(the_repository, prefix, argv[i]) ||\n+\t\t\t\t!path_inside_repo(the_repository, prefix, argv[i + 1]))))\n \t\t\tno_index = DIFF_NO_INDEX_IMPLICIT;\n \t}\n \ndiff --git a/setup.c b/setup.c\nindex adad6ceec0..4ef6216e82 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -160,10 +160,10 @@ char *prefix_path(struct repository *repo, const char *prefix, int len, const ch\n \treturn r;\n }\n \n-int path_inside_repo(const char *prefix, const char *path)\n+int path_inside_repo(struct repository *repo, const char *prefix, const char *path)\n {\n \tint len = prefix ? strlen(prefix) : 0;\n-\tchar *r = prefix_path_gently(the_repository, prefix, len, NULL, path);\n+\tchar *r = prefix_path_gently(repo, prefix, len, NULL, path);\n \tif (r) {\n \t\tfree(r);\n \t\treturn 1;\ndiff --git a/setup.h b/setup.h\nindex 24034572b1..c3247d7fc8 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -146,7 +146,7 @@ void verify_filename(const char *prefix,\n \t\t     const char *name,\n \t\t     int diagnose_misspelt_rev);\n void verify_non_filename(const char *prefix, const char *name);\n-int path_inside_repo(const char *prefix, const char *path);\n+int path_inside_repo(struct repository *repo, const char *prefix, const char *path);\n \n void sanitize_stdfds(void);\n int daemonize(void);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543512","messageId":"20260518-pks-setup-wo-the-repository-v2-6-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 06/18] setup: stop using `the_repository` in `verify_filename()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:30:57Z","receivedAt":"2026-05-18T09:31:22Z","isPatch":true,"body":"Stop using `the_repository` in `verify_filename()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/grep.c      | 2 +-\n builtin/reset.c     | 2 +-\n builtin/rev-parse.c | 4 ++--\n revision.c          | 2 +-\n setup.c             | 5 +++--\n setup.h             | 3 ++-\n 6 files changed, 10 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex e33285e5e6..b0e350cf89 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1163,7 +1163,7 @@ int cmd_grep(int argc,\n \tif (!seen_dashdash) {\n \t\tint j;\n \t\tfor (j = i; j < argc; j++)\n-\t\t\tverify_filename(prefix, argv[j], j == i && allow_revs);\n+\t\t\tverify_filename(the_repository, prefix, argv[j], j == i && allow_revs);\n \t}\n \n \tparse_pathspec(&pathspec, 0,\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex 3590be57a5..1ac374d31b 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -285,7 +285,7 @@ static void parse_args(struct pathspec *pathspec,\n \t\t\trev = *argv++;\n \t\t} else {\n \t\t\t/* Otherwise we treat this as a filename */\n-\t\t\tverify_filename(prefix, argv[0], 1);\n+\t\t\tverify_filename(the_repository, prefix, argv[0], 1);\n \t\t}\n \t}\n \ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 2fcd6851d1..8fdb75413d 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -749,7 +749,7 @@ int cmd_rev_parse(int argc,\n \n \t\tif (as_is) {\n \t\t\tif (show_file(arg, output_prefix) && as_is < 2)\n-\t\t\t\tverify_filename(prefix, arg, 0);\n+\t\t\t\tverify_filename(the_repository, prefix, arg, 0);\n \t\t\tcontinue;\n \t\t}\n \n@@ -1173,7 +1173,7 @@ int cmd_rev_parse(int argc,\n \t\tas_is = 1;\n \t\tif (!show_file(arg, output_prefix))\n \t\t\tcontinue;\n-\t\tverify_filename(prefix, arg, 1);\n+\t\tverify_filename(the_repository, prefix, arg, 1);\n \t}\n \tstrbuf_release(&buf);\n \tif (verify) {\ndiff --git a/revision.c b/revision.c\nindex 599b3a66c3..5d53244379 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -3067,7 +3067,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s\n \t\t\t * but the latter we have checked in the main loop.\n \t\t\t */\n \t\t\tfor (j = i; j < argc; j++)\n-\t\t\t\tverify_filename(revs->prefix, argv[j], j == i);\n+\t\t\t\tverify_filename(the_repository, revs->prefix, argv[j], j == i);\n \n \t\t\tstrvec_pushv(&prune_data, argv + i);\n \t\t\tbreak;\ndiff --git a/setup.c b/setup.c\nindex 4ef6216e82..e673663cab 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -280,7 +280,8 @@ static int looks_like_pathspec(const char *arg)\n  * diagnose_misspelt_rev == 0 for the next ones (because we already\n  * saw a filename, there's not ambiguity anymore).\n  */\n-void verify_filename(const char *prefix,\n+void verify_filename(struct repository *repo,\n+\t\t     const char *prefix,\n \t\t     const char *arg,\n \t\t     int diagnose_misspelt_rev)\n {\n@@ -288,7 +289,7 @@ void verify_filename(const char *prefix,\n \t\tdie(_(\"option '%s' must come before non-option arguments\"), arg);\n \tif (looks_like_pathspec(arg) || check_filename(prefix, arg))\n \t\treturn;\n-\tdie_verify_filename(the_repository, prefix, arg, diagnose_misspelt_rev);\n+\tdie_verify_filename(repo, prefix, arg, diagnose_misspelt_rev);\n }\n \n /*\ndiff --git a/setup.h b/setup.h\nindex c3247d7fc8..24a6f66629 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -142,7 +142,8 @@ char *prefix_path(struct repository *repo, const char *prefix, int len, const ch\n char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\n \n int check_filename(const char *prefix, const char *name);\n-void verify_filename(const char *prefix,\n+void verify_filename(struct repository *repo,\n+\t\t     const char *prefix,\n \t\t     const char *name,\n \t\t     int diagnose_misspelt_rev);\n void verify_non_filename(const char *prefix, const char *name);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543513","messageId":"20260518-pks-setup-wo-the-repository-v2-7-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 07/18] setup: stop using `the_repository` in `verify_non_filename()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:30:58Z","receivedAt":"2026-05-18T09:31:25Z","isPatch":true,"body":"Stop using `the_repository` in `verify_non_filename()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/checkout.c | 2 +-\n builtin/grep.c     | 2 +-\n builtin/reset.c    | 2 +-\n revision.c         | 4 ++--\n setup.c            | 4 ++--\n setup.h            | 2 +-\n 6 files changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex ac0186a33e..14cefa0199 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -1492,7 +1492,7 @@ static int parse_branchname_arg(int argc, const char **argv,\n \t\t * it would be extremely annoying.\n \t\t */\n \t\tif (argc)\n-\t\t\tverify_non_filename(opts->prefix, arg);\n+\t\t\tverify_non_filename(the_repository, opts->prefix, arg);\n \t} else if (opts->accept_pathspec) {\n \t\targcount++;\n \t\targv++;\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex b0e350cf89..4ec0c016b1 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1151,7 +1151,7 @@ int cmd_grep(int argc,\n \n \t\tobject = parse_object_or_die(the_repository, &oid, arg);\n \t\tif (!seen_dashdash)\n-\t\t\tverify_non_filename(prefix, arg);\n+\t\t\tverify_non_filename(the_repository, prefix, arg);\n \t\tadd_object_array_with_path(object, arg, &list, oc.mode, oc.path);\n \t\tobject_context_release(&oc);\n \t}\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex 1ac374d31b..11f57605b5 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -281,7 +281,7 @@ static void parse_args(struct pathspec *pathspec,\n \t\t\t * Ok, argv[0] looks like a commit/tree; it should not\n \t\t\t * be a filename.\n \t\t\t */\n-\t\t\tverify_non_filename(prefix, argv[0]);\n+\t\t\tverify_non_filename(the_repository, prefix, argv[0]);\n \t\t\trev = *argv++;\n \t\t} else {\n \t\t\t/* Otherwise we treat this as a filename */\ndiff --git a/revision.c b/revision.c\nindex 5d53244379..b5fe3ef95d 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2072,7 +2072,7 @@ static int handle_dotdot_1(const char *a_name, const char *b_name,\n \t\treturn -1;\n \n \tif (!cant_be_filename) {\n-\t\tverify_non_filename(revs->prefix, full_name);\n+\t\tverify_non_filename(the_repository, revs->prefix, full_name);\n \t}\n \n \ta_obj = parse_object(revs->repo, &a_oid);\n@@ -2225,7 +2225,7 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl\n \t\tgoto out;\n \t}\n \tif (!cant_be_filename)\n-\t\tverify_non_filename(revs->prefix, arg);\n+\t\tverify_non_filename(the_repository, revs->prefix, arg);\n \tobject = get_reference(revs, arg, &oid, flags ^ local_flags);\n \tif (!object) {\n \t\tret = (revs->ignore_missing || revs->do_not_die_on_missing_objects) ? 0 : -1;\ndiff --git a/setup.c b/setup.c\nindex e673663cab..759aba4e2c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -297,9 +297,9 @@ void verify_filename(struct repository *repo,\n  * and we parsed the arg as a refname.  It should not be interpretable\n  * as a filename.\n  */\n-void verify_non_filename(const char *prefix, const char *arg)\n+void verify_non_filename(struct repository *repo, const char *prefix, const char *arg)\n {\n-\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir(the_repository))\n+\tif (!is_inside_work_tree(repo) || is_inside_git_dir(repo))\n \t\treturn;\n \tif (*arg == '-')\n \t\treturn; /* flag */\ndiff --git a/setup.h b/setup.h\nindex 24a6f66629..364c2c728a 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -146,7 +146,7 @@ void verify_filename(struct repository *repo,\n \t\t     const char *prefix,\n \t\t     const char *name,\n \t\t     int diagnose_misspelt_rev);\n-void verify_non_filename(const char *prefix, const char *name);\n+void verify_non_filename(struct repository *repo, const char *prefix, const char *name);\n int path_inside_repo(struct repository *repo, const char *prefix, const char *path);\n \n void sanitize_stdfds(void);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543514","messageId":"20260518-pks-setup-wo-the-repository-v2-8-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 08/18] setup: stop using `the_repository` in `enter_repo()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:30:59Z","receivedAt":"2026-05-18T09:31:27Z","isPatch":true,"body":"Stop using `the_repository` in `enter_repo()` and instead accept the\nrepository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/receive-pack.c   | 2 +-\n builtin/upload-archive.c | 2 +-\n builtin/upload-pack.c    | 2 +-\n daemon.c                 | 4 ++--\n http-backend.c           | 2 +-\n setup.c                  | 4 ++--\n setup.h                  | 2 +-\n 7 files changed, 9 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex f0771590a7..322d178c92 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2643,7 +2643,7 @@ int cmd_receive_pack(int argc,\n \n \tsetup_path();\n \n-\tif (!enter_repo(service_dir, 0))\n+\tif (!enter_repo(the_repository, service_dir, 0))\n \t\tdie(\"'%s' does not appear to be a git repository\", service_dir);\n \n \trepo_config(the_repository, receive_pack_config, NULL);\ndiff --git a/builtin/upload-archive.c b/builtin/upload-archive.c\nindex 25312bb2a5..718e74b3ac 100644\n--- a/builtin/upload-archive.c\n+++ b/builtin/upload-archive.c\n@@ -31,7 +31,7 @@ int cmd_upload_archive_writer(int argc,\n \tif (argc != 2)\n \t\tusage(upload_archive_usage);\n \n-\tif (!enter_repo(argv[1], 0))\n+\tif (!enter_repo(the_repository, argv[1], 0))\n \t\tdie(\"'%s' does not appear to be a git repository\", argv[1]);\n \n \tinit_archivers();\ndiff --git a/builtin/upload-pack.c b/builtin/upload-pack.c\nindex 30498fafea..32831fb879 100644\n--- a/builtin/upload-pack.c\n+++ b/builtin/upload-pack.c\n@@ -59,7 +59,7 @@ int cmd_upload_pack(int argc,\n \n \tif (strict)\n \t\tenter_repo_flags |= ENTER_REPO_STRICT;\n-\tif (!enter_repo(dir, enter_repo_flags))\n+\tif (!enter_repo(the_repository, dir, enter_repo_flags))\n \t\tdie(\"'%s' does not appear to be a git repository\", dir);\n \n \tswitch (determine_protocol_version_server()) {\ndiff --git a/daemon.c b/daemon.c\nindex 0a7b1aae44..947dd90655 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -244,14 +244,14 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)\n \t}\n \n \tenter_repo_flags = strict_paths ? ENTER_REPO_STRICT : 0;\n-\tpath = enter_repo(dir, enter_repo_flags);\n+\tpath = enter_repo(the_repository, dir, enter_repo_flags);\n \tif (!path && base_path && base_path_relaxed) {\n \t\t/*\n \t\t * if we fail and base_path_relaxed is enabled, try without\n \t\t * prefixing the base path\n \t\t */\n \t\tdir = directory;\n-\t\tpath = enter_repo(dir, enter_repo_flags);\n+\t\tpath = enter_repo(the_repository, dir, enter_repo_flags);\n \t}\n \n \tif (!path) {\ndiff --git a/http-backend.c b/http-backend.c\nindex 1a171c5c5a..c7566b1d12 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -809,7 +809,7 @@ int cmd_main(int argc UNUSED, const char **argv UNUSED)\n \t\tnot_found(&hdr, \"Request not supported: '%s'\", dir);\n \n \tsetup_path();\n-\tif (!enter_repo(dir, 0))\n+\tif (!enter_repo(the_repository, dir, 0))\n \t\tnot_found(&hdr, \"Not a git repository: '%s'\", dir);\n \tif (!getenv(\"GIT_HTTP_EXPORT_ALL\") &&\n \t    access(\"git-daemon-export-ok\", F_OK) )\ndiff --git a/setup.c b/setup.c\nindex 759aba4e2c..cb479cd91a 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1765,7 +1765,7 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir,\n \treturn result;\n }\n \n-const char *enter_repo(const char *path, unsigned flags)\n+const char *enter_repo(struct repository *repo, const char *path, unsigned flags)\n {\n \tstatic struct strbuf validated_path = STRBUF_INIT;\n \tstatic struct strbuf used_path = STRBUF_INIT;\n@@ -1838,7 +1838,7 @@ const char *enter_repo(const char *path, unsigned flags)\n \t}\n \n \tif (is_git_directory(\".\")) {\n-\t\tset_git_dir(the_repository, \".\", 0);\n+\t\tset_git_dir(repo, \".\", 0);\n \t\tcheck_repository_format(NULL);\n \t\treturn path;\n \t}\ndiff --git a/setup.h b/setup.h\nindex 364c2c728a..d0cfdfd44a 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -134,7 +134,7 @@ enum {\n  * links.  User relative paths are also returned as they are given,\n  * except DWIM suffixing.\n  */\n-const char *enter_repo(const char *path, unsigned flags);\n+const char *enter_repo(struct repository *repo, const char *path, unsigned flags);\n \n const char *setup_git_directory_gently(int *);\n const char *setup_git_directory(void);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543515","messageId":"20260518-pks-setup-wo-the-repository-v2-9-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 09/18] setup: stop using `the_repository` in `setup_work_tree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:31:00Z","receivedAt":"2026-05-18T09:31:30Z","isPatch":true,"body":"Stop using `the_repository` in `setup_work_tree()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nNote that the function tracks two bits of information via global\nvariables. This of course doesn't make much sense anymore now that we\ncan set up worktrees for arbitrary repositories:\n\n  - We track whether the worktree has already been initialized and, if\n    so, we skip the call to `chdir_notify()` and setenv(3p). It does not\n    make much sense to store this info in the repository, as we _would_\n    want to update the environment when switching between worktrees back\n    and forth.\n\n    So instead of storing this info in the repository, we drop this\n    state entirely and live with the fact that we may execute the logic\n    twice. It should ultimately be idempotent though and thus not be\n    much of a problem.\n\n  - We track whether the worktree configuration is bogus. If so, and if\n    later on some caller tries to setup the worktree, then we'll die\n    instead. This is indeed information that we can move into the\n    repository itself.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n blame.c                     |  2 +-\n builtin/check-attr.c        |  2 +-\n builtin/clone.c             |  2 +-\n builtin/describe.c          |  2 +-\n builtin/diff-index.c        |  2 +-\n builtin/diff.c              |  4 ++--\n builtin/difftool.c          |  2 +-\n builtin/grep.c              |  2 +-\n builtin/ls-files.c          |  2 +-\n builtin/read-tree.c         |  2 +-\n builtin/reset.c             |  2 +-\n builtin/rm.c                |  2 +-\n builtin/sparse-checkout.c   | 16 ++++++++--------\n builtin/submodule--helper.c |  2 +-\n builtin/update-index.c      | 10 +++++-----\n git.c                       |  2 +-\n repository.h                |  1 +\n setup.c                     | 15 ++++-----------\n setup.h                     |  2 +-\n t/helper/test-subprocess.c  |  4 +++-\n wt-status.c                 |  2 +-\n 21 files changed, 38 insertions(+), 42 deletions(-)\n\ndiff --git a/blame.c b/blame.c\nindex a3c49d132e..977cbb7097 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -2813,7 +2813,7 @@ void setup_scoreboard(struct blame_scoreboard *sb,\n \t\t}\n \n \t\tif (!sb->contents_from)\n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \n \t\tsb->final = fake_working_tree_commit(sb->repo,\n \t\t\t\t\t\t     &sb->revs->diffopt,\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 04b86e42ae..98f64d5b92 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -117,7 +117,7 @@ int cmd_check_attr(int argc,\n \tint cnt, i, doubledash, filei;\n \n \tif (!is_bare_repository())\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \trepo_config(the_repository, git_default_config, NULL);\n \ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex d23b0cafcf..09f6d97658 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -669,7 +669,7 @@ static int checkout(int submodule_progress,\n \t}\n \n \t/* We need to be in the new work tree for the checkout */\n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \n \trepo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);\n \ndiff --git a/builtin/describe.c b/builtin/describe.c\nindex bffeed13a3..1c47d7c0b7 100644\n--- a/builtin/describe.c\n+++ b/builtin/describe.c\n@@ -781,7 +781,7 @@ int cmd_describe(int argc,\n \t\t\tstruct rev_info revs;\n \t\t\tint fd;\n \n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \t\t\tprepare_repo_settings(the_repository);\n \t\t\tthe_repository->settings.command_requires_full_index = 0;\n \t\t\trepo_read_index(the_repository);\ndiff --git a/builtin/diff-index.c b/builtin/diff-index.c\nindex 522dacfc4c..3db7cffede 100644\n--- a/builtin/diff-index.c\n+++ b/builtin/diff-index.c\n@@ -69,7 +69,7 @@ int cmd_diff_index(int argc,\n \t    rev.max_count != -1 || rev.min_age != -1 || rev.max_age != -1)\n \t\tusage(diff_cache_usage);\n \tif (!(option & DIFF_INDEX_CACHED)) {\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\tif (repo_read_index_preload(the_repository, &rev.diffopt.pathspec, 0) < 0) {\n \t\t\tperror(\"repo_read_index_preload\");\n \t\t\treturn -1;\ndiff --git a/builtin/diff.c b/builtin/diff.c\nindex 7ddebce2ac..1ede873ac1 100644\n--- a/builtin/diff.c\n+++ b/builtin/diff.c\n@@ -159,7 +159,7 @@ static void builtin_diff_index(struct rev_info *revs,\n \t    revs->max_age != -1)\n \t\tusage(builtin_diff_usage);\n \tif (!(option & DIFF_INDEX_CACHED)) {\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\tif (repo_read_index_preload(the_repository,\n \t\t\t\t\t    &revs->diffopt.pathspec, 0) < 0) {\n \t\t\tdie_errno(\"repo_read_index_preload\");\n@@ -281,7 +281,7 @@ static void builtin_diff_files(struct rev_info *revs, int argc, const char **arg\n \t    (revs->diffopt.output_format & DIFF_FORMAT_PATCH))\n \t\tdiff_merges_set_dense_combined_if_unset(revs);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (repo_read_index_preload(the_repository, &revs->diffopt.pathspec,\n \t\t\t\t    0) < 0) {\n \t\tdie_errno(\"repo_read_index_preload\");\ndiff --git a/builtin/difftool.c b/builtin/difftool.c\nindex e4bc1f8316..2a21005f2e 100644\n--- a/builtin/difftool.c\n+++ b/builtin/difftool.c\n@@ -767,7 +767,7 @@ int cmd_difftool(int argc,\n \t\tdie(_(\"difftool requires worktree or --no-index\"));\n \n \tif (!no_index){\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(repo);\n \t\tsetenv(GIT_DIR_ENVIRONMENT, absolute_path(repo_get_git_dir(repo)), 1);\n \t\tsetenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(repo_get_work_tree(repo)), 1);\n \t} else if (dir_diff)\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 4ec0c016b1..679f8b567a 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1272,7 +1272,7 @@ int cmd_grep(int argc,\n \t\tdie(_(\"--[no-]exclude-standard cannot be used for tracked contents\"));\n \t} else if (!list.nr) {\n \t\tif (!cached)\n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \n \t\thit = grep_cache(&opt, &pathspec, cached);\n \t} else {\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex 09d95111b3..e1a22b41b9 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -704,7 +704,7 @@ int cmd_ls_files(int argc,\n \t\texc_given = 1;\n \n \tif (require_work_tree && !is_inside_work_tree(repo))\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(repo);\n \n \tif (recurse_submodules &&\n \t    (show_deleted || show_others || show_unmerged ||\ndiff --git a/builtin/read-tree.c b/builtin/read-tree.c\nindex 460b21e40a..999a82ecdf 100644\n--- a/builtin/read-tree.c\n+++ b/builtin/read-tree.c\n@@ -229,7 +229,7 @@ int cmd_read_tree(int argc,\n \t\topts.preserve_ignored = 0;\n \t/* otherwise, opts.preserve_ignored is irrelevant */\n \tif (opts.merge && !opts.index_only)\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \tif (opts.skip_sparse_checkout)\n \t\tensure_full_index(the_repository->index);\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex 11f57605b5..3be6bd0121 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -468,7 +468,7 @@ int cmd_reset(int argc,\n \t\ttrace2_cmd_mode(reset_type_names[reset_type]);\n \n \tif (reset_type != SOFT && (reset_type != MIXED || repo_get_work_tree(the_repository)))\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \tif (reset_type == MIXED && is_bare_repository())\n \t\tdie(_(\"%s reset is not allowed in a bare repository\"),\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex 05d89e98c3..081d0bc375 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -296,7 +296,7 @@ int cmd_rm(int argc,\n \t\tdie(_(\"No pathspec was given. Which files should I remove?\"));\n \n \tif (!index_only)\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \tprepare_repo_settings(the_repository);\n \tthe_repository->settings.command_requires_full_index = 0;\ndiff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c\nindex 2af50fb2f9..d89acbeb53 100644\n--- a/builtin/sparse-checkout.c\n+++ b/builtin/sparse-checkout.c\n@@ -63,7 +63,7 @@ static int sparse_checkout_list(int argc, const char **argv, const char *prefix,\n \tint res;\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"this worktree is not sparse\"));\n \n@@ -229,7 +229,7 @@ static int update_working_directory(struct repository *r,\n \to.dst_index = r->index;\n \to.skip_sparse_checkout = 0;\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \n \trepo_hold_locked_index(r, &lock_file, LOCK_DIE_ON_ERROR);\n \n@@ -468,7 +468,7 @@ static int sparse_checkout_init(int argc, const char **argv, const char *prefix,\n \t\tOPT_END(),\n \t};\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \trepo_read_index(repo);\n \n \tinit_opts.cone_mode = -1;\n@@ -802,7 +802,7 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix,\n \tint ret;\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"no sparse-checkout to add to\"));\n \n@@ -856,7 +856,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix,\n \tstruct strvec patterns = STRVEC_INIT;\n \tint ret;\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \trepo_read_index(repo);\n \n \tset_opts.cone_mode = -1;\n@@ -912,7 +912,7 @@ static int sparse_checkout_reapply(int argc, const char **argv,\n \t};\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"must be in a sparse-checkout to reapply sparsity patterns\"));\n \n@@ -975,7 +975,7 @@ static int sparse_checkout_clean(int argc, const char **argv,\n \t\tOPT_END(),\n \t};\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"must be in a sparse-checkout to clean directories\"));\n \tif (!core_sparse_checkout_cone)\n@@ -1053,7 +1053,7 @@ static int sparse_checkout_disable(int argc, const char **argv,\n \t * forcibly return to a dense checkout regardless of initial state.\n \t */\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \targc = parse_options(argc, argv, prefix,\n \t\t\t     builtin_sparse_checkout_disable_options,\n \t\t\t     builtin_sparse_checkout_disable_usage, 0);\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 2f589e3b37..1cc82a134d 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1250,7 +1250,7 @@ static int compute_summary_module_list(struct object_id *head_oid,\n \n \tif (!info->cached) {\n \t\tif (diff_cmd == DIFF_INDEX)\n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \t\tif (repo_read_index_preload(the_repository, &rev.diffopt.pathspec, 0) < 0) {\n \t\t\tperror(\"repo_read_index_preload\");\n \t\t\tret = -1;\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 7434112b8e..d6dabacfd1 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -732,7 +732,7 @@ struct refresh_params {\n \n static int refresh(struct refresh_params *o, unsigned int flag)\n {\n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \trepo_read_index(the_repository);\n \t*o->has_errors |= refresh_index(the_repository->index, o->flags | flag, NULL,\n \t\t\t\t\tNULL, NULL);\n@@ -901,7 +901,7 @@ static enum parse_opt_result reupdate_callback(\n \tBUG_ON_OPT_ARG(arg);\n \n \t/* consume remaining arguments. */\n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \t*has_errors = do_reupdate(ctx->argv + 1, prefix);\n \tif (*has_errors)\n \t\tthe_repository->index->cache_changed = 0;\n@@ -1157,7 +1157,7 @@ int cmd_update_index(int argc,\n \t\t\t\ttransaction = NULL;\n \t\t\t}\n \n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \t\t\tp = prefix_path(the_repository, prefix, prefix_length, path);\n \t\t\tupdate_one(p);\n \t\t\tif (set_executable_bit)\n@@ -1199,7 +1199,7 @@ int cmd_update_index(int argc,\n \t\tstruct strbuf buf = STRBUF_INIT;\n \t\tstruct strbuf unquoted = STRBUF_INIT;\n \n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\twhile (getline_fn(&buf, stdin) != EOF) {\n \t\t\tchar *p;\n \t\t\tif (!nul_term_line && buf.buf[0] == '\"') {\n@@ -1253,7 +1253,7 @@ int cmd_update_index(int argc,\n \t\treport(_(\"Untracked cache disabled\"));\n \t\tbreak;\n \tcase UC_TEST:\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\treturn !test_if_untracked_cache_is_supported();\n \tcase UC_ENABLE:\n \tcase UC_FORCE:\ndiff --git a/git.c b/git.c\nindex 5a40eab8a2..eaede42c4e 100644\n--- a/git.c\n+++ b/git.c\n@@ -497,7 +497,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct\n \tcommit_pager_choice();\n \n \tif (!help && p->option & NEED_WORK_TREE)\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \ttrace_argv_printf(argv, \"trace: built-in: git\");\n \ttrace2_cmd_name(p->cmd);\ndiff --git a/repository.h b/repository.h\nindex 4969d8b8eb..832451fc61 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -114,6 +114,7 @@ struct repository {\n \t * A NULL value indicates that there is no working directory.\n \t */\n \tchar *worktree;\n+\tbool worktree_config_is_bogus;\n \n \t/*\n \t * Path from the root of the top-level superproject down to this\ndiff --git a/setup.c b/setup.c\nindex cb479cd91a..50324f8f37 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -26,7 +26,6 @@\n #include \"trace2.h\"\n #include \"worktree.h\"\n \n-static int work_tree_config_is_bogus;\n enum allowed_bare_repo {\n \tALLOWED_BARE_REPO_EXPLICIT = 0,\n \tALLOWED_BARE_REPO_ALL,\n@@ -494,18 +493,14 @@ int is_inside_work_tree(struct repository *repo)\n \treturn ret;\n }\n \n-void setup_work_tree(void)\n+void setup_work_tree(struct repository *repo)\n {\n \tconst char *work_tree;\n-\tstatic int initialized = 0;\n \n-\tif (initialized)\n-\t\treturn;\n-\n-\tif (work_tree_config_is_bogus)\n+\tif (repo->worktree_config_is_bogus)\n \t\tdie(_(\"unable to set up work tree using invalid config\"));\n \n-\twork_tree = repo_get_work_tree(the_repository);\n+\twork_tree = repo_get_work_tree(repo);\n \tif (!work_tree || chdir_notify(work_tree))\n \t\tdie(_(\"this operation must be run in a work tree\"));\n \n@@ -515,8 +510,6 @@ void setup_work_tree(void)\n \t */\n \tif (getenv(GIT_WORK_TREE_ENVIRONMENT))\n \t\tsetenv(GIT_WORK_TREE_ENVIRONMENT, \".\", 1);\n-\n-\tinitialized = 1;\n }\n \n static void setup_original_cwd(struct repository *repo)\n@@ -1164,7 +1157,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t\tif (git_work_tree_cfg) {\n \t\t\t/* #22.2, #30 */\n \t\t\twarning(\"core.bare and core.worktree do not make sense\");\n-\t\t\twork_tree_config_is_bogus = 1;\n+\t\t\trepo->worktree_config_is_bogus = true;\n \t\t}\n \n \t\t/* #18, #26 */\ndiff --git a/setup.h b/setup.h\nindex d0cfdfd44a..8fed365637 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -56,7 +56,7 @@ const char *resolve_gitdir_gently(const char *suspect, int *return_error_code);\n void die_upon_dubious_ownership(const char *gitfile, const char *worktree,\n \t\t\t\tconst char *gitdir);\n \n-void setup_work_tree(void);\n+void setup_work_tree(struct repository *repo);\n \n /*\n  * discover_git_directory_reason() is similar to discover_git_directory(),\ndiff --git a/t/helper/test-subprocess.c b/t/helper/test-subprocess.c\nindex c344f1694d..8a070e47cd 100644\n--- a/t/helper/test-subprocess.c\n+++ b/t/helper/test-subprocess.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"run-command.h\"\n #include \"setup.h\"\n@@ -11,7 +13,7 @@ int cmd__subprocess(int argc, const char **argv)\n \tif (nogit)\n \t\tdie(\"No git repo found\");\n \tif (argc > 1 && !strcmp(argv[1], \"--setup-work-tree\")) {\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\targv++;\n \t}\n \tcp.git_cmd = 1;\ndiff --git a/wt-status.c b/wt-status.c\nindex 479ccc3304..6cc77ba68c 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1206,7 +1206,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)\n \t\tstatus_printf_ln(s, c,\n \t\t\t\"--------------------------------------------------\");\n \t\tstatus_printf_ln(s, c, _(\"Changes not staged for commit:\"));\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\trev.diffopt.a_prefix = \"i/\";\n \t\trev.diffopt.b_prefix = \"w/\";\n \t\trun_diff_files(&rev, 0);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543516","messageId":"20260518-pks-setup-wo-the-repository-v2-10-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 10/18] setup: stop using `the_repository` in `set_git_work_tree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:31:01Z","receivedAt":"2026-05-18T09:31:32Z","isPatch":true,"body":"Stop using `the_repository` in `set_git_work_tree()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSimilar as with the preceding commit, we track whether the worktree has\nbeen initialized already via a global variable so that we can die in\ncase the repository is re-initialized with a different worktree path.\nStore this info in the `struct repository` instead so that we correctly\nhandle this per repository.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c   |  2 +-\n builtin/init-db.c |  6 +++---\n repository.h      |  1 +\n setup.c           | 24 +++++++++++-------------\n setup.h           |  2 +-\n 5 files changed, 17 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 09f6d97658..8844e3d481 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1116,7 +1116,7 @@ int cmd_clone(int argc,\n \t\t\tdie_errno(_(\"could not create work tree dir '%s'\"),\n \t\t\t\t  work_tree);\n \t\tjunk_work_tree = work_tree;\n-\t\tset_git_work_tree(work_tree);\n+\t\tset_git_work_tree(the_repository, work_tree);\n \t}\n \n \tif (real_git_dir) {\ndiff --git a/builtin/init-db.c b/builtin/init-db.c\nindex bb853e69f5..e626b0d8b7 100644\n--- a/builtin/init-db.c\n+++ b/builtin/init-db.c\n@@ -237,9 +237,9 @@ int cmd_init_db(int argc,\n \t\tif (!git_work_tree_cfg)\n \t\t\tgit_work_tree_cfg = xgetcwd();\n \t\tif (work_tree)\n-\t\t\tset_git_work_tree(work_tree);\n+\t\t\tset_git_work_tree(the_repository, work_tree);\n \t\telse\n-\t\t\tset_git_work_tree(git_work_tree_cfg);\n+\t\t\tset_git_work_tree(the_repository, git_work_tree_cfg);\n \t\tif (access(repo_get_work_tree(the_repository), X_OK))\n \t\t\tdie_errno (_(\"Cannot access work tree '%s'\"),\n \t\t\t\t   repo_get_work_tree(the_repository));\n@@ -248,7 +248,7 @@ int cmd_init_db(int argc,\n \t\tif (real_git_dir)\n \t\t\tdie(_(\"--separate-git-dir incompatible with bare repository\"));\n \t\tif (work_tree)\n-\t\t\tset_git_work_tree(work_tree);\n+\t\t\tset_git_work_tree(the_repository, work_tree);\n \t}\n \n \tflags |= INIT_DB_EXIST_OK;\ndiff --git a/repository.h b/repository.h\nindex 832451fc61..d391aff8ab 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -114,6 +114,7 @@ struct repository {\n \t * A NULL value indicates that there is no working directory.\n \t */\n \tchar *worktree;\n+\tbool worktree_initialized;\n \tbool worktree_config_is_bogus;\n \n \t/*\ndiff --git a/setup.c b/setup.c\nindex 50324f8f37..796ac5792f 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1152,7 +1152,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \n \t/* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */\n \tif (work_tree_env)\n-\t\tset_git_work_tree(work_tree_env);\n+\t\tset_git_work_tree(repo, work_tree_env);\n \telse if (is_bare_repository_cfg > 0) {\n \t\tif (git_work_tree_cfg) {\n \t\t\t/* #22.2, #30 */\n@@ -1167,7 +1167,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t}\n \telse if (git_work_tree_cfg) { /* #6, #14 */\n \t\tif (is_absolute_path(git_work_tree_cfg))\n-\t\t\tset_git_work_tree(git_work_tree_cfg);\n+\t\t\tset_git_work_tree(repo, git_work_tree_cfg);\n \t\telse {\n \t\t\tchar *core_worktree;\n \t\t\tif (chdir(gitdirenv))\n@@ -1177,7 +1177,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t\t\tcore_worktree = xgetcwd();\n \t\t\tif (chdir(cwd->buf))\n \t\t\t\tdie_errno(_(\"cannot come back to cwd\"));\n-\t\t\tset_git_work_tree(core_worktree);\n+\t\t\tset_git_work_tree(repo, core_worktree);\n \t\t\tfree(core_worktree);\n \t\t}\n \t}\n@@ -1188,7 +1188,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t\treturn NULL;\n \t}\n \telse /* #2, #10 */\n-\t\tset_git_work_tree(\".\");\n+\t\tset_git_work_tree(repo, \".\");\n \n \t/* set_git_work_tree() must have been called by now */\n \tworktree = repo_get_work_tree(repo);\n@@ -1248,7 +1248,7 @@ static const char *setup_discovered_git_dir(struct repository *repo,\n \t}\n \n \t/* #0, #1, #5, #8, #9, #12, #13 */\n-\tset_git_work_tree(\".\");\n+\tset_git_work_tree(repo, \".\");\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n \t\tset_git_dir(repo, gitdir, 0);\n \tif (offset >= cwd->len)\n@@ -1839,29 +1839,27 @@ const char *enter_repo(struct repository *repo, const char *path, unsigned flags\n \treturn NULL;\n }\n \n-static int git_work_tree_initialized;\n-\n /*\n  * Note.  This works only before you used a work tree.  This was added\n  * primarily to support git-clone to work in a new repository it just\n  * created, and is not meant to flip between different work trees.\n  */\n-void set_git_work_tree(const char *new_work_tree)\n+void set_git_work_tree(struct repository *repo, const char *new_work_tree)\n {\n-\tif (git_work_tree_initialized) {\n+\tif (repo->worktree_initialized) {\n \t\tstruct strbuf realpath = STRBUF_INIT;\n \n \t\tstrbuf_realpath(&realpath, new_work_tree, 1);\n \t\tnew_work_tree = realpath.buf;\n-\t\tif (strcmp(new_work_tree, the_repository->worktree))\n+\t\tif (strcmp(new_work_tree, repo->worktree))\n \t\t\tdie(\"internal error: work tree has already been set\\n\"\n \t\t\t    \"Current worktree: %s\\nNew worktree: %s\",\n-\t\t\t    the_repository->worktree, new_work_tree);\n+\t\t\t    repo->worktree, new_work_tree);\n \t\tstrbuf_release(&realpath);\n \t\treturn;\n \t}\n-\tgit_work_tree_initialized = 1;\n-\trepo_set_worktree(the_repository, new_work_tree);\n+\trepo->worktree_initialized = true;\n+\trepo_set_worktree(repo, new_work_tree);\n }\n \n const char *setup_git_directory_gently(int *nongit_ok)\ndiff --git a/setup.h b/setup.h\nindex 8fed365637..1a37089fa0 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -96,7 +96,7 @@ static inline int discover_git_directory(struct strbuf *commondir,\n \treturn 0;\n }\n \n-void set_git_work_tree(const char *tree);\n+void set_git_work_tree(struct repository *repo, const char *tree);\n \n /* Flags that can be passed to `enter_repo()`. */\n enum {\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543517","messageId":"20260518-pks-setup-wo-the-repository-v2-11-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 11/18] setup: stop using `the_repository` in `setup_git_env()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:31:02Z","receivedAt":"2026-05-18T09:31:35Z","isPatch":true,"body":"Stop using `the_repository` in `setup_git_env()` and instead accept the\nrepository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nFurthermore, the function is never used outside of \"setup.c\". Drop the\ndeclaration in \"environment.h\" and make it static.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n environment.h | 2 --\n setup.c       | 6 +++---\n 2 files changed, 3 insertions(+), 5 deletions(-)\n\ndiff --git a/environment.h b/environment.h\nindex 123a71cdc8..9eb97b3869 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -147,8 +147,6 @@ void repo_config_values_init(struct repo_config_values *cfg);\n  * Please do not add new global config variables here.\n  */\n # ifdef USE_THE_REPOSITORY_VARIABLE\n-void setup_git_env(const char *git_dir);\n-\n /*\n  * Returns true iff we have a configured git repository (either via\n  * setup_git_directory, or in the environment via $GIT_DIR).\ndiff --git a/setup.c b/setup.c\nindex 796ac5792f..8965f8ccaf 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1074,9 +1074,9 @@ static void setup_git_env_internal(struct repository *repo,\n \t\tfetch_if_missing = 0;\n }\n \n-void setup_git_env(const char *git_dir)\n+static void setup_git_env(struct repository *repo, const char *git_dir)\n {\n-\tsetup_git_env_internal(the_repository, git_dir, false);\n+\tsetup_git_env_internal(repo, git_dir, false);\n }\n \n static void set_git_dir_1(struct repository *repo, const char *path, bool skip_initializing_odb)\n@@ -1988,7 +1988,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\t\tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n \t\t\tif (!gitdir)\n \t\t\t\tgitdir = DEFAULT_GIT_DIR_ENVIRONMENT;\n-\t\t\tsetup_git_env(gitdir);\n+\t\t\tsetup_git_env(the_repository, gitdir);\n \t\t}\n \t\tif (startup_info->have_repository) {\n \t\t\trepo_set_hash_algo(the_repository, repo_fmt.hash_algo);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543518","messageId":"20260518-pks-setup-wo-the-repository-v2-12-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 12/18] setup: stop using `the_repository` in `setup_git_directory_gently()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:31:03Z","receivedAt":"2026-05-18T09:31:38Z","isPatch":true,"body":"Stop using `the_repository` in `setup_git_directory_gently()` and\ninstead accept the repository as a parameter. The injection of\n`the_repository` is thus bumped one level higher, where callers now pass\nit in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/check-ref-format.c |  5 ++++-\n builtin/diff.c             |  2 +-\n builtin/hash-object.c      |  2 +-\n builtin/help.c             |  2 +-\n builtin/stripspace.c       |  2 +-\n git.c                      |  6 +++---\n http-fetch.c               |  2 +-\n imap-send.c                |  2 +-\n remote-curl.c              |  4 ++--\n setup.c                    | 36 ++++++++++++++++++------------------\n setup.h                    |  2 +-\n t/helper/test-path-utils.c |  2 +-\n t/helper/test-subprocess.c |  2 +-\n 13 files changed, 36 insertions(+), 33 deletions(-)\n\ndiff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c\nindex 5d80afeec0..e42b0444ea 100644\n--- a/builtin/check-ref-format.c\n+++ b/builtin/check-ref-format.c\n@@ -1,6 +1,9 @@\n /*\n  * GIT - The information manager from hell\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"builtin.h\"\n #include \"refs.h\"\n #include \"setup.h\"\n@@ -41,7 +44,7 @@ static int check_ref_format_branch(const char *arg)\n \tconst char *name;\n \tint nongit;\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \tif (check_branch_ref(&sb, arg) ||\n \t    !skip_prefix(sb.buf, \"refs/heads/\", &name))\n \t\tdie(\"'%s' is not a valid branch name\", arg);\ndiff --git a/builtin/diff.c b/builtin/diff.c\nindex 1ede873ac1..4b46e394ce 100644\n--- a/builtin/diff.c\n+++ b/builtin/diff.c\n@@ -455,7 +455,7 @@ int cmd_diff(int argc,\n \t\t\tbreak;\n \t}\n \n-\tprefix = setup_git_directory_gently(&nongit);\n+\tprefix = setup_git_directory_gently(the_repository, &nongit);\n \n \tif (!nongit) {\n \t\tprepare_repo_settings(the_repository);\ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex 5d900a6b8c..d7905bedc2 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -102,7 +102,7 @@ int cmd_hash_object(int argc,\n \tif (flags & INDEX_WRITE_OBJECT)\n \t\tprefix = setup_git_directory();\n \telse\n-\t\tprefix = setup_git_directory_gently(&nongit);\n+\t\tprefix = setup_git_directory_gently(the_repository, &nongit);\n \n \tif (nongit && !the_hash_algo)\n \t\trepo_set_hash_algo(the_repository, GIT_HASH_DEFAULT);\ndiff --git a/builtin/help.c b/builtin/help.c\nindex c0aece4da3..a140339999 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -740,7 +740,7 @@ int cmd_help(int argc,\n \t\treturn 0;\n \t}\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \trepo_config(the_repository, git_help_config, NULL);\n \n \tif (parsed_help_format != HELP_FORMAT_NONE)\ndiff --git a/builtin/stripspace.c b/builtin/stripspace.c\nindex 4a566cbc5d..18705f1a5b 100644\n--- a/builtin/stripspace.c\n+++ b/builtin/stripspace.c\n@@ -54,7 +54,7 @@ int cmd_stripspace(int argc,\n \t\tusage_with_options(stripspace_usage, options);\n \n \tif (mode == STRIP_COMMENTS || mode == COMMENT_LINES) {\n-\t\tsetup_git_directory_gently(&nongit);\n+\t\tsetup_git_directory_gently(the_repository, &nongit);\n \t\trepo_config(the_repository, git_default_config, NULL);\n \t}\n \ndiff --git a/git.c b/git.c\nindex eaede42c4e..2cc018fc5c 100644\n--- a/git.c\n+++ b/git.c\n@@ -84,7 +84,7 @@ static int list_cmds(const char *spec)\n \t* Set up the repository so we can pick up any repo-level config (like\n \t* completion.commands).\n \t*/\n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \n \twhile (*spec) {\n \t\tconst char *sep = strchrnul(spec, ',');\n@@ -386,7 +386,7 @@ static int handle_alias(struct strvec *args, struct string_list *expanded_aliase\n \t\t\tint nongit_ok;\n \n \t\t\t/* Aliases expect GIT_PREFIX, GIT_DIR etc to be set */\n-\t\t\tsetup_git_directory_gently(&nongit_ok);\n+\t\t\tsetup_git_directory_gently(the_repository, &nongit_ok);\n \n \t\t\tcommit_pager_choice();\n \n@@ -480,7 +480,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct\n \t\tprefix = setup_git_directory();\n \t\tno_repo = 0;\n \t} else if (run_setup & RUN_SETUP_GENTLY) {\n-\t\tprefix = setup_git_directory_gently(&no_repo);\n+\t\tprefix = setup_git_directory_gently(the_repository, &no_repo);\n \t} else {\n \t\tprefix = NULL;\n \t}\ndiff --git a/http-fetch.c b/http-fetch.c\nindex 1922e23fcd..f9b6ecb061 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -109,7 +109,7 @@ int cmd_main(int argc, const char **argv)\n \tstruct strvec index_pack_args = STRVEC_INIT;\n \tint ret;\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \n \twhile (arg < argc && argv[arg][0] == '-') {\n \t\tconst char *p;\ndiff --git a/imap-send.c b/imap-send.c\nindex af02c6a689..cfd6a5120c 100644\n--- a/imap-send.c\n+++ b/imap-send.c\n@@ -1799,7 +1799,7 @@ int cmd_main(int argc, const char **argv)\n \tint nongit_ok;\n \tint ret;\n \n-\tsetup_git_directory_gently(&nongit_ok);\n+\tsetup_git_directory_gently(the_repository, &nongit_ok);\n \trepo_config(the_repository, git_imap_config, &server);\n \n \targc = parse_options(argc, (const char **)argv, \"\", imap_send_options, imap_send_usage, 0);\ndiff --git a/remote-curl.c b/remote-curl.c\nindex aba60d5712..a84fc860ec 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -1557,7 +1557,7 @@ int cmd_main(int argc, const char **argv)\n \tint nongit;\n \tint ret = 1;\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \tif (argc < 2) {\n \t\terror(_(\"remote-curl: usage: git remote-curl <remote> [<url>]\"));\n \t\tgoto cleanup;\n@@ -1605,7 +1605,7 @@ int cmd_main(int argc, const char **argv)\n \t\t\tbreak;\n \t\tif (starts_with(buf.buf, \"fetch \")) {\n \t\t\tif (nongit) {\n-\t\t\t\tsetup_git_directory_gently(&nongit);\n+\t\t\t\tsetup_git_directory_gently(the_repository, &nongit);\n \t\t\t\tif (nongit)\n \t\t\t\t\tdie(_(\"remote-curl: fetch attempted without a local repo\"));\n \t\t\t}\ndiff --git a/setup.c b/setup.c\nindex 8965f8ccaf..c12c6cbda2 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1862,7 +1862,7 @@ void set_git_work_tree(struct repository *repo, const char *new_work_tree)\n \trepo_set_worktree(repo, new_work_tree);\n }\n \n-const char *setup_git_directory_gently(int *nongit_ok)\n+const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)\n {\n \tstatic struct strbuf cwd = STRBUF_INIT;\n \tstruct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT, report = STRBUF_INIT;\n@@ -1877,7 +1877,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t * configuration (including the per-repo config file that we\n \t * ignored previously).\n \t */\n-\trepo_config_clear(the_repository);\n+\trepo_config_clear(repo);\n \n \t/*\n \t * Let's assume that we are in a git repository.\n@@ -1893,18 +1893,18 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \n \tswitch (setup_git_directory_gently_1(&dir, &gitdir, &report, 1)) {\n \tcase GIT_DIR_EXPLICIT:\n-\t\tprefix = setup_explicit_git_dir(the_repository, gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_explicit_git_dir(repo, gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_DISCOVERED:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_discovered_git_dir(the_repository, gitdir.buf, &cwd, dir.len,\n+\t\tprefix = setup_discovered_git_dir(repo, gitdir.buf, &cwd, dir.len,\n \t\t\t\t\t\t  &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_BARE:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_bare_git_dir(the_repository, &cwd, dir.len, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_bare_git_dir(repo, &cwd, dir.len, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_HIT_CEILING:\n \t\tif (!nongit_ok)\n@@ -1984,30 +1984,30 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t    startup_info->have_repository ||\n \t    /* GIT_DIR_EXPLICIT */\n \t    getenv(GIT_DIR_ENVIRONMENT)) {\n-\t\tif (!the_repository->gitdir) {\n+\t\tif (!repo->gitdir) {\n \t\t\tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n \t\t\tif (!gitdir)\n \t\t\t\tgitdir = DEFAULT_GIT_DIR_ENVIRONMENT;\n-\t\t\tsetup_git_env(the_repository, gitdir);\n+\t\t\tsetup_git_env(repo, gitdir);\n \t\t}\n \t\tif (startup_info->have_repository) {\n-\t\t\trepo_set_hash_algo(the_repository, repo_fmt.hash_algo);\n-\t\t\trepo_set_compat_hash_algo(the_repository,\n+\t\t\trepo_set_hash_algo(repo, repo_fmt.hash_algo);\n+\t\t\trepo_set_compat_hash_algo(repo,\n \t\t\t\t\t\t  repo_fmt.compat_hash_algo);\n-\t\t\trepo_set_ref_storage_format(the_repository,\n+\t\t\trepo_set_ref_storage_format(repo,\n \t\t\t\t\t\t    repo_fmt.ref_storage_format,\n \t\t\t\t\t\t    repo_fmt.ref_storage_payload);\n-\t\t\tthe_repository->repository_format_worktree_config =\n+\t\t\trepo->repository_format_worktree_config =\n \t\t\t\trepo_fmt.worktree_config;\n-\t\t\tthe_repository->repository_format_relative_worktrees =\n+\t\t\trepo->repository_format_relative_worktrees =\n \t\t\t\trepo_fmt.relative_worktrees;\n-\t\t\tthe_repository->repository_format_submodule_path_cfg =\n+\t\t\trepo->repository_format_submodule_path_cfg =\n \t\t\t\trepo_fmt.submodule_path_cfg;\n \t\t\t/* take ownership of repo_fmt.partial_clone */\n-\t\t\tthe_repository->repository_format_partial_clone =\n+\t\t\trepo->repository_format_partial_clone =\n \t\t\t\trepo_fmt.partial_clone;\n \t\t\trepo_fmt.partial_clone = NULL;\n-\t\t\tthe_repository->repository_format_precious_objects =\n+\t\t\trepo->repository_format_precious_objects =\n \t\t\t\trepo_fmt.precious_objects;\n \t\t}\n \t}\n@@ -2040,13 +2040,13 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\tformat = ref_storage_format_by_name(backend);\n \t\tif (format == REF_STORAGE_FORMAT_UNKNOWN)\n \t\t\tdie(_(\"unknown ref storage format: '%s'\"), backend);\n-\t\trepo_set_ref_storage_format(the_repository, format, payload);\n+\t\trepo_set_ref_storage_format(repo, format, payload);\n \n \t\tfree(backend);\n \t\tfree(payload);\n \t}\n \n-\tsetup_original_cwd(the_repository);\n+\tsetup_original_cwd(repo);\n \n \tstrbuf_release(&dir);\n \tstrbuf_release(&gitdir);\n@@ -2138,7 +2138,7 @@ void check_repository_format(struct repository_format *fmt)\n  */\n const char *setup_git_directory(void)\n {\n-\treturn setup_git_directory_gently(NULL);\n+\treturn setup_git_directory_gently(the_repository, NULL);\n }\n \n const char *resolve_gitdir_gently(const char *suspect, int *return_error_code)\ndiff --git a/setup.h b/setup.h\nindex 1a37089fa0..18092fbf16 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -136,7 +136,7 @@ enum {\n  */\n const char *enter_repo(struct repository *repo, const char *path, unsigned flags);\n \n-const char *setup_git_directory_gently(int *);\n+const char *setup_git_directory_gently(struct repository *repo, int *);\n const char *setup_git_directory(void);\n char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path);\n char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\ndiff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c\nindex 163fdeefb0..15eb44485c 100644\n--- a/t/helper/test-path-utils.c\n+++ b/t/helper/test-path-utils.c\n@@ -377,7 +377,7 @@ int cmd__path_utils(int argc, const char **argv)\n \t\tconst char *prefix = argv[2];\n \t\tint prefix_len = strlen(prefix);\n \t\tint nongit_ok;\n-\t\tsetup_git_directory_gently(&nongit_ok);\n+\t\tsetup_git_directory_gently(the_repository, &nongit_ok);\n \t\twhile (argc > 3) {\n \t\t\tchar *pfx = prefix_path(the_repository, prefix, prefix_len, argv[3]);\n \ndiff --git a/t/helper/test-subprocess.c b/t/helper/test-subprocess.c\nindex 8a070e47cd..a8194d24b3 100644\n--- a/t/helper/test-subprocess.c\n+++ b/t/helper/test-subprocess.c\n@@ -9,7 +9,7 @@ int cmd__subprocess(int argc, const char **argv)\n \tstruct child_process cp = CHILD_PROCESS_INIT;\n \tint nogit = 0;\n \n-\tsetup_git_directory_gently(&nogit);\n+\tsetup_git_directory_gently(the_repository, &nogit);\n \tif (nogit)\n \t\tdie(\"No git repo found\");\n \tif (argc > 1 && !strcmp(argv[1], \"--setup-work-tree\")) {\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543519","messageId":"20260518-pks-setup-wo-the-repository-v2-13-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 13/18] setup: stop using `the_repository` in `setup_git_directory()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:31:04Z","receivedAt":"2026-05-18T09:31:40Z","isPatch":true,"body":"Stop using `the_repository` in `setup_git_directory()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n archive.c                                    |  2 +-\n builtin/grep.c                               |  2 +-\n builtin/hash-object.c                        |  2 +-\n builtin/merge-file.c                         |  2 +-\n builtin/rev-parse.c                          |  4 ++--\n git.c                                        |  2 +-\n http-push.c                                  |  2 +-\n scalar.c                                     |  4 ++--\n setup.c                                      |  4 ++--\n setup.h                                      |  2 +-\n t/helper/test-advise.c                       |  2 +-\n t/helper/test-bitmap.c                       |  2 +-\n t/helper/test-bloom.c                        |  2 +-\n t/helper/test-cache-tree.c                   |  2 +-\n t/helper/test-config.c                       |  2 +-\n t/helper/test-dump-cache-tree.c              |  2 +-\n t/helper/test-dump-fsmonitor.c               |  2 +-\n t/helper/test-dump-split-index.c             |  2 +-\n t/helper/test-dump-untracked-cache.c         |  2 +-\n t/helper/test-find-pack.c                    |  2 +-\n t/helper/test-fsmonitor-client.c             |  2 +-\n t/helper/test-lazy-init-name-hash.c          |  2 +-\n t/helper/test-match-trees.c                  |  2 +-\n t/helper/test-pack-deltas.c                  |  2 +-\n t/helper/test-pack-mtimes.c                  |  2 +-\n t/helper/test-partial-clone.c                |  4 +++-\n t/helper/test-path-walk.c                    |  2 +-\n t/helper/test-reach.c                        |  2 +-\n t/helper/test-read-cache.c                   |  2 +-\n t/helper/test-read-graph.c                   |  2 +-\n t/helper/test-read-midx.c                    |  2 +-\n t/helper/test-ref-store.c                    |  2 +-\n t/helper/test-revision-walking.c             |  2 +-\n t/helper/test-scrap-cache-tree.c             |  2 +-\n t/helper/test-serve-v2.c                     |  2 +-\n t/helper/test-submodule-config.c             |  2 +-\n t/helper/test-submodule-nested-repo-config.c |  2 +-\n t/helper/test-submodule.c                    | 10 +++++-----\n t/helper/test-userdiff.c                     |  2 +-\n t/helper/test-write-cache.c                  |  2 +-\n 40 files changed, 49 insertions(+), 47 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex fcd474c682..51229107a5 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -786,7 +786,7 @@ int write_archive(int argc, const char **argv, const char *prefix,\n \t\t * die ourselves; but its error message will be more specific\n \t\t * than what we could write here.\n \t\t */\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \t}\n \n \tparse_treeish_arg(argv, &args, remote);\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 679f8b567a..560133feb8 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1064,7 +1064,7 @@ int cmd_grep(int argc,\n \t\t\tuse_index = 0;\n \t\telse\n \t\t\t/* die the same way as if we did it at the beginning */\n-\t\t\tsetup_git_directory();\n+\t\t\tsetup_git_directory(the_repository);\n \t}\n \t/* Ignore --recurse-submodules if --no-index is given or implied */\n \tif (!use_index)\ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex d7905bedc2..f306b0643f 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -100,7 +100,7 @@ int cmd_hash_object(int argc,\n \t\t\t     hash_object_usage, 0);\n \n \tif (flags & INDEX_WRITE_OBJECT)\n-\t\tprefix = setup_git_directory();\n+\t\tprefix = setup_git_directory(the_repository);\n \telse\n \t\tprefix = setup_git_directory_gently(the_repository, &nongit);\n \ndiff --git a/builtin/merge-file.c b/builtin/merge-file.c\nindex 59a9792208..8fa5765239 100644\n--- a/builtin/merge-file.c\n+++ b/builtin/merge-file.c\n@@ -110,7 +110,7 @@ int cmd_merge_file(int argc,\n \n \tif (!repo && object_id)\n \t\t/* emit the correct \"not a git repo\" error in this case */\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \n \tfor (i = 0; i < 3; i++) {\n \t\tchar *fname;\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 8fdb75413d..0a01ff7a75 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -739,7 +739,7 @@ int cmd_rev_parse(int argc,\n \n \t/* No options; just report on whether we're in a git repo or not. */\n \tif (argc == 1) {\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \t\trepo_config(the_repository, git_default_config, NULL);\n \t\treturn 0;\n \t}\n@@ -774,7 +774,7 @@ int cmd_rev_parse(int argc,\n \n \t\t/* The rest of the options require a git repository. */\n \t\tif (!did_repo_setup) {\n-\t\t\tprefix = setup_git_directory();\n+\t\t\tprefix = setup_git_directory(the_repository);\n \t\t\trepo_config(the_repository, git_default_config, NULL);\n \t\t\tdid_repo_setup = 1;\n \ndiff --git a/git.c b/git.c\nindex 2cc018fc5c..42cd5f5b3c 100644\n--- a/git.c\n+++ b/git.c\n@@ -477,7 +477,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct\n \t\trun_setup = RUN_SETUP_GENTLY;\n \n \tif (run_setup & RUN_SETUP) {\n-\t\tprefix = setup_git_directory();\n+\t\tprefix = setup_git_directory(the_repository);\n \t\tno_repo = 0;\n \t} else if (run_setup & RUN_SETUP_GENTLY) {\n \t\tprefix = setup_git_directory_gently(the_repository, &no_repo);\ndiff --git a/http-push.c b/http-push.c\nindex d143fe2845..520d6c3b6a 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1788,7 +1788,7 @@ int cmd_main(int argc, const char **argv)\n \tif (delete_branch && rs.nr != 1)\n \t\tdie(\"You must specify only one branch name when deleting a remote branch\");\n \n-\tgitdir = setup_git_directory();\n+\tgitdir = setup_git_directory(the_repository);\n \n \tmemset(remote_dir_exists, -1, 256);\n \ndiff --git a/scalar.c b/scalar.c\nindex 4efb6ac36d..a80d8ee3ff 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -58,7 +58,7 @@ static void setup_enlistment_directory(int argc, const char **argv,\n \t}\n \tstrbuf_setlen(&path, len);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (!the_repository->worktree)\n \t\tdie(_(\"Scalar enlistments require a worktree\"));\n@@ -514,7 +514,7 @@ static int cmd_clone(int argc, const char **argv)\n \t\tgoto cleanup;\n \t}\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \t/* common-main already logs `argv` */\n \ttrace2_def_repo(the_repository);\ndiff --git a/setup.c b/setup.c\nindex c12c6cbda2..5dc27caf15 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2136,9 +2136,9 @@ void check_repository_format(struct repository_format *fmt)\n  * directory is not a strict subdirectory of the work tree root. The\n  * prefix always ends with a '/' character.\n  */\n-const char *setup_git_directory(void)\n+const char *setup_git_directory(struct repository *repo)\n {\n-\treturn setup_git_directory_gently(the_repository, NULL);\n+\treturn setup_git_directory_gently(repo, NULL);\n }\n \n const char *resolve_gitdir_gently(const char *suspect, int *return_error_code)\ndiff --git a/setup.h b/setup.h\nindex 18092fbf16..b779661ce7 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -137,7 +137,7 @@ enum {\n const char *enter_repo(struct repository *repo, const char *path, unsigned flags);\n \n const char *setup_git_directory_gently(struct repository *repo, int *);\n-const char *setup_git_directory(void);\n+const char *setup_git_directory(struct repository *repo);\n char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path);\n char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\n \ndiff --git a/t/helper/test-advise.c b/t/helper/test-advise.c\nindex 81ed93a05c..8f9db2693e 100644\n--- a/t/helper/test-advise.c\n+++ b/t/helper/test-advise.c\n@@ -11,7 +11,7 @@ int cmd__advise_if_enabled(int argc, const char **argv)\n \tif (argc != 2)\n \t\tdie(\"usage: %s <advice>\", argv[0]);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_config(the_repository, git_default_config, NULL);\n \n \t/*\ndiff --git a/t/helper/test-bitmap.c b/t/helper/test-bitmap.c\nindex 16a01669e4..d9b9a83b8f 100644\n--- a/t/helper/test-bitmap.c\n+++ b/t/helper/test-bitmap.c\n@@ -37,7 +37,7 @@ static int bitmap_dump_pseudo_merge_objects(uint32_t n)\n \n int cmd__bitmap(int argc, const char **argv)\n {\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 2 && !strcmp(argv[1], \"list-commits\"))\n \t\treturn bitmap_list_commits();\ndiff --git a/t/helper/test-bloom.c b/t/helper/test-bloom.c\nindex 3283544bd3..0c65befbf0 100644\n--- a/t/helper/test-bloom.c\n+++ b/t/helper/test-bloom.c\n@@ -52,7 +52,7 @@ static const char *const bloom_usage = \"\\n\"\n \n int cmd__bloom(int argc, const char **argv)\n {\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc < 2)\n \t\tusage(bloom_usage);\ndiff --git a/t/helper/test-cache-tree.c b/t/helper/test-cache-tree.c\nindex ff61d0ca7e..d42e260092 100644\n--- a/t/helper/test-cache-tree.c\n+++ b/t/helper/test-cache-tree.c\n@@ -33,7 +33,7 @@ int cmd__cache_tree(int argc, const char **argv)\n \t\tOPT_END()\n \t};\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \targc = parse_options(argc, argv, NULL, options, test_cache_tree_usage, 0);\n \ndiff --git a/t/helper/test-config.c b/t/helper/test-config.c\nindex 9f8cca7c48..cfb3f4b111 100644\n--- a/t/helper/test-config.c\n+++ b/t/helper/test-config.c\n@@ -102,7 +102,7 @@ int cmd__config(int argc, const char **argv)\n \t\treturn 0;\n \t}\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tgit_configset_init(&cs);\n \ndiff --git a/t/helper/test-dump-cache-tree.c b/t/helper/test-dump-cache-tree.c\nindex 3f0c7d0ed0..ccb41a4239 100644\n--- a/t/helper/test-dump-cache-tree.c\n+++ b/t/helper/test-dump-cache-tree.c\n@@ -66,7 +66,7 @@ int cmd__dump_cache_tree(int ac UNUSED, const char **av UNUSED)\n \tstruct cache_tree *another = cache_tree();\n \tint ret;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tif (repo_read_index(the_repository) < 0)\n \t\tdie(\"unable to read index file\");\n \tistate = *the_repository->index;\ndiff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c\nindex efd017ca35..c991cbbb8a 100644\n--- a/t/helper/test-dump-fsmonitor.c\n+++ b/t/helper/test-dump-fsmonitor.c\n@@ -9,7 +9,7 @@ int cmd__dump_fsmonitor(int ac UNUSED, const char **av UNUSED)\n {\n \tstruct index_state *istate = the_repository->index;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tif (do_read_index(istate, the_repository->index_file, 0) < 0)\n \t\tdie(\"unable to read index file\");\n \tif (!istate->fsmonitor_last_update) {\ndiff --git a/t/helper/test-dump-split-index.c b/t/helper/test-dump-split-index.c\nindex f855a3862c..aae0a40a74 100644\n--- a/t/helper/test-dump-split-index.c\n+++ b/t/helper/test-dump-split-index.c\n@@ -17,7 +17,7 @@ int cmd__dump_split_index(int ac UNUSED, const char **av)\n {\n \tstruct split_index *si;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tdo_read_index(the_repository->index, av[1], 1);\n \tprintf(\"own %s\\n\", oid_to_hex(&the_repository->index->oid));\ndiff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c\nindex 01a109496b..24308bd371 100644\n--- a/t/helper/test-dump-untracked-cache.c\n+++ b/t/helper/test-dump-untracked-cache.c\n@@ -54,7 +54,7 @@ int cmd__dump_untracked_cache(int ac UNUSED, const char **av UNUSED)\n \txsetenv(\"GIT_CONFIG_KEY_0\", \"core.untrackedCache\", 1);\n \txsetenv(\"GIT_CONFIG_VALUE_0\", \"keep\", 1);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tif (repo_read_index(the_repository) < 0)\n \t\tdie(\"unable to read index file\");\n \tuc = the_repository->index->untracked;\ndiff --git a/t/helper/test-find-pack.c b/t/helper/test-find-pack.c\nindex fc4b8a77b3..28d5b1fe09 100644\n--- a/t/helper/test-find-pack.c\n+++ b/t/helper/test-find-pack.c\n@@ -25,7 +25,7 @@ int cmd__find_pack(int argc, const char **argv)\n \tstruct object_id oid;\n \tstruct packed_git *p;\n \tint count = -1, actual_count = 0;\n-\tconst char *prefix = setup_git_directory();\n+\tconst char *prefix = setup_git_directory(the_repository);\n \n \tstruct option options[] = {\n \t\tOPT_INTEGER('c', \"check-count\", &count, \"expected number of packs\"),\ndiff --git a/t/helper/test-fsmonitor-client.c b/t/helper/test-fsmonitor-client.c\nindex 02bfe92e8d..dc1dff23fb 100644\n--- a/t/helper/test-fsmonitor-client.c\n+++ b/t/helper/test-fsmonitor-client.c\n@@ -210,7 +210,7 @@ int cmd__fsmonitor_client(int argc, const char **argv)\n \n \tsubcmd = argv[0];\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (!strcmp(subcmd, \"query\"))\n \t\treturn !!do_send_query(token);\ndiff --git a/t/helper/test-lazy-init-name-hash.c b/t/helper/test-lazy-init-name-hash.c\nindex 40f5df4412..e542985c94 100644\n--- a/t/helper/test-lazy-init-name-hash.c\n+++ b/t/helper/test-lazy-init-name-hash.c\n@@ -211,7 +211,7 @@ int cmd__lazy_init_name_hash(int argc, const char **argv)\n \tconst char *prefix;\n \tuint64_t avg_single, avg_multi;\n \n-\tprefix = setup_git_directory();\n+\tprefix = setup_git_directory(the_repository);\n \n \targc = parse_options(argc, argv, prefix, options, usage, 0);\n \ndiff --git a/t/helper/test-match-trees.c b/t/helper/test-match-trees.c\nindex 2ed064b971..006ce5278e 100644\n--- a/t/helper/test-match-trees.c\n+++ b/t/helper/test-match-trees.c\n@@ -13,7 +13,7 @@ int cmd__match_trees(int ac UNUSED, const char **av)\n \tstruct object_id hash1, hash2, shifted;\n \tstruct tree *one, *two;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (repo_get_oid(the_repository, av[1], &hash1))\n \t\tdie(\"cannot parse %s as an object name\", av[1]);\ndiff --git a/t/helper/test-pack-deltas.c b/t/helper/test-pack-deltas.c\nindex 4981401eaa..c493b75e02 100644\n--- a/t/helper/test-pack-deltas.c\n+++ b/t/helper/test-pack-deltas.c\n@@ -95,7 +95,7 @@ int cmd__pack_deltas(int argc, const char **argv)\n \tif (argc || num_objects < 0)\n \t\tusage_with_options(usage_str, options);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tf = hashfd(the_repository->hash_algo, 1, \"<stdout>\");\n \twrite_pack_header(f, num_objects);\ndiff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c\nindex 7a8ee1de24..b774056799 100644\n--- a/t/helper/test-pack-mtimes.c\n+++ b/t/helper/test-pack-mtimes.c\n@@ -32,7 +32,7 @@ int cmd__pack_mtimes(int argc, const char **argv)\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct packed_git *p;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc != 2)\n \t\tusage(pack_mtimes_usage);\ndiff --git a/t/helper/test-partial-clone.c b/t/helper/test-partial-clone.c\nindex d848800749..a7aab426d0 100644\n--- a/t/helper/test-partial-clone.c\n+++ b/t/helper/test-partial-clone.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"repository.h\"\n@@ -32,7 +34,7 @@ static void object_info(const char *gitdir, const char *oid_hex)\n \n int cmd__partial_clone(int argc, const char **argv)\n {\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc < 4)\n \t\tdie(\"too few arguments\");\ndiff --git a/t/helper/test-path-walk.c b/t/helper/test-path-walk.c\nindex fe63002c2b..69676b15a5 100644\n--- a/t/helper/test-path-walk.c\n+++ b/t/helper/test-path-walk.c\n@@ -89,7 +89,7 @@ int cmd__path_walk(int argc, const char **argv)\n \t\tOPT_END(),\n \t};\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trevs.repo = the_repository;\n \n \targc = parse_options(argc, argv, NULL,\ndiff --git a/t/helper/test-reach.c b/t/helper/test-reach.c\nindex 3131b54a87..5d86a96c17 100644\n--- a/t/helper/test-reach.c\n+++ b/t/helper/test-reach.c\n@@ -39,7 +39,7 @@ int cmd__reach(int ac, const char **av)\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct repository *r = the_repository;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (ac < 2)\n \t\texit(1);\ndiff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c\nindex 9ae71cefb3..6b08ba8f07 100644\n--- a/t/helper/test-read-cache.c\n+++ b/t/helper/test-read-cache.c\n@@ -19,7 +19,7 @@ int cmd__read_cache(int argc, const char **argv)\n \n \tif (argc == 2)\n \t\tcnt = strtol(argv[1], NULL, 0);\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_config(the_repository, git_default_config, NULL);\n \n \tfor (i = 0; i < cnt; i++) {\ndiff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c\nindex 6a5f64e473..9f07b9c25a 100644\n--- a/t/helper/test-read-graph.c\n+++ b/t/helper/test-read-graph.c\n@@ -76,7 +76,7 @@ int cmd__read_graph(int argc, const char **argv)\n \tstruct odb_source *source;\n \tint ret = 0;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tsource = the_repository->objects->sources;\n \n \tprepare_repo_settings(the_repository);\ndiff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c\nindex 388d29e2b5..790000fb26 100644\n--- a/t/helper/test-read-midx.c\n+++ b/t/helper/test-read-midx.c\n@@ -14,7 +14,7 @@\n static struct multi_pack_index *setup_midx(const char *object_dir)\n {\n \tstruct odb_source *source;\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tsource = odb_find_source(the_repository->objects, object_dir);\n \tif (!source)\n \t\tsource = odb_add_to_alternates_memory(the_repository->objects,\ndiff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c\nindex 74edf2029a..3866d0aca4 100644\n--- a/t/helper/test-ref-store.c\n+++ b/t/helper/test-ref-store.c\n@@ -340,7 +340,7 @@ int cmd__ref_store(int argc UNUSED, const char **argv)\n \tconst char *func;\n \tstruct command *cmd;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \targv = get_store(argv + 1, &refs);\n \ndiff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c\nindex 071f5bd1e2..70051eeaf8 100644\n--- a/t/helper/test-revision-walking.c\n+++ b/t/helper/test-revision-walking.c\n@@ -56,7 +56,7 @@ int cmd__revision_walking(int argc, const char **argv)\n \tif (argc < 2)\n \t\treturn 1;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (!strcmp(argv[1], \"run-twice\")) {\n \t\tprintf(\"1st\\n\");\ndiff --git a/t/helper/test-scrap-cache-tree.c b/t/helper/test-scrap-cache-tree.c\nindex 64fff6e9e3..7b5ce501d9 100644\n--- a/t/helper/test-scrap-cache-tree.c\n+++ b/t/helper/test-scrap-cache-tree.c\n@@ -12,7 +12,7 @@ int cmd__scrap_cache_tree(int ac UNUSED, const char **av UNUSED)\n {\n \tstruct lock_file index_lock = LOCK_INIT;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_hold_locked_index(the_repository, &index_lock, LOCK_DIE_ON_ERROR);\n \tif (repo_read_index(the_repository) < 0)\n \t\tdie(\"unable to read index file\");\ndiff --git a/t/helper/test-serve-v2.c b/t/helper/test-serve-v2.c\nindex 63a200b8d4..27f3ed8947 100644\n--- a/t/helper/test-serve-v2.c\n+++ b/t/helper/test-serve-v2.c\n@@ -23,7 +23,7 @@ int cmd__serve_v2(int argc, const char **argv)\n \t\t\t N_(\"exit immediately after advertising capabilities\")),\n \t\tOPT_END()\n \t};\n-\tconst char *prefix = setup_git_directory();\n+\tconst char *prefix = setup_git_directory(the_repository);\n \n \t/* ignore all unknown cmdline switches for now */\n \targc = parse_options(argc, argv, prefix, options, serve_usage,\ndiff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c\nindex cbe93f2f9e..3f30292179 100644\n--- a/t/helper/test-submodule-config.c\n+++ b/t/helper/test-submodule-config.c\n@@ -34,7 +34,7 @@ int cmd__submodule_config(int argc, const char **argv)\n \tif (my_argc % 2 != 0)\n \t\tdie_usage(argc, argv, \"Wrong number of arguments.\");\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \twhile (*arg) {\n \t\tstruct object_id commit_oid;\ndiff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c\nindex 2710341cd5..7e31d3fe47 100644\n--- a/t/helper/test-submodule-nested-repo-config.c\n+++ b/t/helper/test-submodule-nested-repo-config.c\n@@ -19,7 +19,7 @@ int cmd__submodule_nested_repo_config(int argc, const char **argv)\n \tif (argc < 3)\n \t\tdie_usage(argv, \"Wrong number of arguments.\");\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (repo_submodule_init(&subrepo, the_repository, argv[1], null_oid(the_hash_algo))) {\n \t\tdie_usage(argv, \"Submodule not found.\");\ndiff --git a/t/helper/test-submodule.c b/t/helper/test-submodule.c\nindex 0133852e1e..3c5c4c4a09 100644\n--- a/t/helper/test-submodule.c\n+++ b/t/helper/test-submodule.c\n@@ -99,7 +99,7 @@ static int cmd__submodule_is_active(int argc, const char **argv)\n \tif (argc != 1)\n \t\tusage_with_options(submodule_is_active_usage, options);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \treturn !is_submodule_active(the_repository, argv[0]);\n }\n@@ -142,7 +142,7 @@ static int cmd__submodule_config_list(int argc, const char **argv)\n \targc = parse_options(argc, argv, \"test-tools\", options, usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 2)\n \t\treturn print_config_from_gitmodules(the_repository, argv[1]);\n@@ -161,7 +161,7 @@ static int cmd__submodule_config_set(int argc, const char **argv)\n \targc = parse_options(argc, argv, \"test-tools\", options, usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \t/* Equivalent to ACTION_SET in builtin/config.c */\n \tif (argc == 3) {\n@@ -183,7 +183,7 @@ static int cmd__submodule_config_unset(int argc, const char **argv)\n \t\tNULL\n \t};\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 2) {\n \t\tif (!is_writing_gitmodules_ok())\n@@ -202,7 +202,7 @@ static int cmd__submodule_config_writeable(int argc, const char **argv UNUSED)\n \t\t\"test-tool submodule config-writeable\",\n \t\tNULL\n \t};\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 1)\n \t\treturn is_writing_gitmodules_ok() ? 0 : -1;\ndiff --git a/t/helper/test-userdiff.c b/t/helper/test-userdiff.c\nindex aa3a9894d2..fc34c589b3 100644\n--- a/t/helper/test-userdiff.c\n+++ b/t/helper/test-userdiff.c\n@@ -40,7 +40,7 @@ int cmd__userdiff(int argc, const char **argv)\n \t\treturn error(\"unknown argument %s\", argv[1]);\n \n \tif (want & USERDIFF_DRIVER_TYPE_CUSTOM) {\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \t\trepo_config(the_repository, cmd__userdiff_config, NULL);\n \t}\n \ndiff --git a/t/helper/test-write-cache.c b/t/helper/test-write-cache.c\nindex b37dd2c5d6..98e1477c98 100644\n--- a/t/helper/test-write-cache.c\n+++ b/t/helper/test-write-cache.c\n@@ -12,7 +12,7 @@ int cmd__write_cache(int argc, const char **argv)\n \tint i, cnt = 1;\n \tif (argc == 2)\n \t\tcnt = strtol(argv[1], NULL, 0);\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_read_index(the_repository);\n \tfor (i = 0; i < cnt; i++) {\n \t\trepo_hold_locked_index(the_repository, &index_lock,\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543520","messageId":"20260518-pks-setup-wo-the-repository-v2-14-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 14/18] setup: stop using `the_repository` in `upgrade_repository_format()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:31:05Z","receivedAt":"2026-05-18T09:31:43Z","isPatch":true,"body":"Stop using `the_repository` in `upgrade_repository_format()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n list-objects-filter-options.c | 2 +-\n repository.h                  | 2 +-\n setup.c                       | 6 +++---\n worktree.c                    | 2 +-\n 4 files changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/list-objects-filter-options.c b/list-objects-filter-options.c\nindex cef67e5919..bc5d98f9e6 100644\n--- a/list-objects-filter-options.c\n+++ b/list-objects-filter-options.c\n@@ -378,7 +378,7 @@ void partial_clone_register(\n \t\t\t */\n \t\t\treturn;\n \t} else {\n-\t\tif (upgrade_repository_format(1) < 0)\n+\t\tif (upgrade_repository_format(the_repository, 1) < 0)\n \t\t\tdie(_(\"unable to upgrade repository format to support partial clone\"));\n \n \t\t/* Add promisor config for the remote */\ndiff --git a/repository.h b/repository.h\nindex d391aff8ab..c3ec0f4b79 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -281,6 +281,6 @@ void repo_update_index_if_able(struct repository *, struct lock_file *);\n  * Return 1 if upgrade repository format to target_version succeeded,\n  * 0 if no upgrade is necessary, and -1 when upgrade is not possible.\n  */\n-int upgrade_repository_format(int target_version);\n+int upgrade_repository_format(struct repository *repo, int target_version);\n \n #endif /* REPOSITORY_H */\ndiff --git a/setup.c b/setup.c\nindex 5dc27caf15..ed0c14e98e 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -811,7 +811,7 @@ static int check_repository_format_gently(struct repository *repo,\n \treturn 0;\n }\n \n-int upgrade_repository_format(int target_version)\n+int upgrade_repository_format(struct repository *repo, int target_version)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n \tstruct strbuf err = STRBUF_INIT;\n@@ -819,7 +819,7 @@ int upgrade_repository_format(int target_version)\n \tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n \tint ret;\n \n-\trepo_common_path_append(the_repository, &sb, \"config\");\n+\trepo_common_path_append(repo, &sb, \"config\");\n \tread_repository_format(&repo_fmt, sb.buf);\n \tstrbuf_release(&sb);\n \n@@ -841,7 +841,7 @@ int upgrade_repository_format(int target_version)\n \t}\n \n \tstrbuf_addf(&repo_version, \"%d\", target_version);\n-\trepo_config_set(the_repository, \"core.repositoryformatversion\", repo_version.buf);\n+\trepo_config_set(repo, \"core.repositoryformatversion\", repo_version.buf);\n \n \tret = 1;\n \ndiff --git a/worktree.c b/worktree.c\nindex d874e23b4e..988be84a30 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -1104,7 +1104,7 @@ void write_worktree_linking_files(const char *dotgit, const char *gitdir,\n \tstrbuf_realpath(&repo, repo.buf, 1);\n \n \tif (use_relative_paths && !the_repository->repository_format_relative_worktrees) {\n-\t\tif (upgrade_repository_format(1) < 0)\n+\t\tif (upgrade_repository_format(the_repository, 1) < 0)\n \t\t\tdie(_(\"unable to upgrade repository format to support relative worktrees\"));\n \t\tif (repo_config_set_gently(the_repository, \"extensions.relativeWorktrees\", \"true\"))\n \t\t\tdie(_(\"unable to set extensions.relativeWorktrees setting\"));\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543521","messageId":"20260518-pks-setup-wo-the-repository-v2-15-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 15/18] setup: stop using `the_repository` in `check_repository_format()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:31:06Z","receivedAt":"2026-05-18T09:31:45Z","isPatch":true,"body":"Stop using `the_repository` in `check_repository_format()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nFurthermore, the function is never used outside \"setup.c\". Drop its\ndeclaration in \"setup.h\" and make it static. Note that this requires us\nto reorder the function.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n setup.c | 58 +++++++++++++++++++++++++++++++++-------------------------\n setup.h | 10 ----------\n 2 files changed, 33 insertions(+), 35 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex ed0c14e98e..406984b62c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1758,6 +1758,37 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir,\n \treturn result;\n }\n \n+/*\n+ * Check the repository format version in the path found in repo_get_git_dir(repo),\n+ * and die if it is a version we don't understand. Generally one would\n+ * set_git_dir() before calling this, and use it only for \"are we in a valid\n+ * repo?\".\n+ *\n+ * If successful and fmt is not NULL, fill fmt with data.\n+ */\n+static void check_repository_format(struct repository *repo, struct repository_format *fmt)\n+{\n+\tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n+\tif (!fmt)\n+\t\tfmt = &repo_fmt;\n+\tcheck_repository_format_gently(repo, repo_get_git_dir(repo), fmt, NULL);\n+\tstartup_info->have_repository = 1;\n+\trepo_set_hash_algo(repo, fmt->hash_algo);\n+\trepo_set_compat_hash_algo(repo, fmt->compat_hash_algo);\n+\trepo_set_ref_storage_format(repo,\n+\t\t\t\t    fmt->ref_storage_format,\n+\t\t\t\t    fmt->ref_storage_payload);\n+\trepo->repository_format_worktree_config =\n+\t\tfmt->worktree_config;\n+\trepo->repository_format_submodule_path_cfg =\n+\t\tfmt->submodule_path_cfg;\n+\trepo->repository_format_relative_worktrees =\n+\t\tfmt->relative_worktrees;\n+\trepo->repository_format_partial_clone =\n+\t\txstrdup_or_null(fmt->partial_clone);\n+\tclear_repository_format(&repo_fmt);\n+}\n+\n const char *enter_repo(struct repository *repo, const char *path, unsigned flags)\n {\n \tstatic struct strbuf validated_path = STRBUF_INIT;\n@@ -1832,7 +1863,7 @@ const char *enter_repo(struct repository *repo, const char *path, unsigned flags\n \n \tif (is_git_directory(\".\")) {\n \t\tset_git_dir(repo, \".\", 0);\n-\t\tcheck_repository_format(NULL);\n+\t\tcheck_repository_format(repo, NULL);\n \t\treturn path;\n \t}\n \n@@ -2107,29 +2138,6 @@ int git_config_perm(const char *var, const char *value)\n \treturn -(i & 0666);\n }\n \n-void check_repository_format(struct repository_format *fmt)\n-{\n-\tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n-\tif (!fmt)\n-\t\tfmt = &repo_fmt;\n-\tcheck_repository_format_gently(the_repository, repo_get_git_dir(the_repository), fmt, NULL);\n-\tstartup_info->have_repository = 1;\n-\trepo_set_hash_algo(the_repository, fmt->hash_algo);\n-\trepo_set_compat_hash_algo(the_repository, fmt->compat_hash_algo);\n-\trepo_set_ref_storage_format(the_repository,\n-\t\t\t\t    fmt->ref_storage_format,\n-\t\t\t\t    fmt->ref_storage_payload);\n-\tthe_repository->repository_format_worktree_config =\n-\t\tfmt->worktree_config;\n-\tthe_repository->repository_format_submodule_path_cfg =\n-\t\tfmt->submodule_path_cfg;\n-\tthe_repository->repository_format_relative_worktrees =\n-\t\tfmt->relative_worktrees;\n-\tthe_repository->repository_format_partial_clone =\n-\t\txstrdup_or_null(fmt->partial_clone);\n-\tclear_repository_format(&repo_fmt);\n-}\n-\n /*\n  * Returns the \"prefix\", a path to the current working directory\n  * relative to the work tree root, or NULL, if the current working\n@@ -2804,7 +2812,7 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t * config file, so this will not fail.  What we are catching\n \t * is an attempt to reinitialize new repository with an old tool.\n \t */\n-\tcheck_repository_format(&repo_fmt);\n+\tcheck_repository_format(the_repository, &repo_fmt);\n \n \trepository_format_configure(the_repository, &repo_fmt, hash, ref_storage_format);\n \ndiff --git a/setup.h b/setup.h\nindex b779661ce7..a820041af0 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -221,16 +221,6 @@ void clear_repository_format(struct repository_format *format);\n int verify_repository_format(const struct repository_format *format,\n \t\t\t     struct strbuf *err);\n \n-/*\n- * Check the repository format version in the path found in repo_get_git_dir(the_repository),\n- * and die if it is a version we don't understand. Generally one would\n- * set_git_dir() before calling this, and use it only for \"are we in a valid\n- * repo?\".\n- *\n- * If successful and fmt is not NULL, fill fmt with data.\n- */\n-void check_repository_format(struct repository_format *fmt);\n-\n const char *get_template_dir(const char *option_template);\n \n #define INIT_DB_QUIET      (1 << 0)\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543522","messageId":"20260518-pks-setup-wo-the-repository-v2-16-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 16/18] setup: stop using `the_repository` in `initialize_repository_version()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:31:07Z","receivedAt":"2026-05-18T09:31:48Z","isPatch":true,"body":"Stop using `the_repository` in `initialize_repository_version()` and\ninstead accept the repository as a parameter. The injection of\n`the_repository` is thus bumped one level higher, where callers now pass\nit in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c |  4 ++--\n refs.c          |  2 +-\n setup.c         | 29 +++++++++++++++--------------\n setup.h         |  3 ++-\n 4 files changed, 20 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 8844e3d481..24fe0eead5 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1229,7 +1229,7 @@ int cmd_clone(int argc,\n \t *\n \t * This is sufficient for Git commands to discover the Git directory.\n \t */\n-\tinitialize_repository_version(GIT_HASH_UNKNOWN,\n+\tinitialize_repository_version(the_repository, GIT_HASH_UNKNOWN,\n \t\t\t\t      the_repository->ref_storage_format, 1);\n \n \trefs_create_refdir_stubs(the_repository, git_dir, NULL);\n@@ -1442,7 +1442,7 @@ int cmd_clone(int argc,\n \t * ours to the same thing.\n \t */\n \thash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));\n-\tinitialize_repository_version(hash_algo, the_repository->ref_storage_format, 1);\n+\tinitialize_repository_version(the_repository, hash_algo, the_repository->ref_storage_format, 1);\n \trepo_set_hash_algo(the_repository, hash_algo);\n \tcreate_reference_database(NULL, 1);\n \ndiff --git a/refs.c b/refs.c\nindex 844785219d..c36a322f4c 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -3453,7 +3453,7 @@ int repo_migrate_ref_storage_format(struct repository *repo,\n \t * repository format so that clients will use the new ref store.\n \t * We also need to swap out the repository's main ref store.\n \t */\n-\tinitialize_repository_version(hash_algo_by_ptr(repo->hash_algo), format, 1);\n+\tinitialize_repository_version(the_repository, hash_algo_by_ptr(repo->hash_algo), format, 1);\n \n \t/*\n \t * Unset the old ref store and release it. `get_main_ref_store()` will\ndiff --git a/setup.c b/setup.c\nindex 406984b62c..e09483ba34 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2385,7 +2385,8 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree)\n \treturn 1;\n }\n \n-void initialize_repository_version(int hash_algo,\n+void initialize_repository_version(struct repository *repo,\n+\t\t\t\t   int hash_algo,\n \t\t\t\t   enum ref_storage_format ref_storage_format,\n \t\t\t\t   int reinit)\n {\n@@ -2402,35 +2403,35 @@ void initialize_repository_version(int hash_algo,\n \t */\n \tif (hash_algo != GIT_HASH_SHA1_LEGACY ||\n \t    ref_storage_format != REF_STORAGE_FORMAT_FILES ||\n-\t    the_repository->ref_storage_payload)\n+\t    repo->ref_storage_payload)\n \t\ttarget_version = GIT_REPO_VERSION_READ;\n \n \tif (hash_algo != GIT_HASH_SHA1_LEGACY && hash_algo != GIT_HASH_UNKNOWN)\n-\t\trepo_config_set(the_repository, \"extensions.objectformat\",\n+\t\trepo_config_set(repo, \"extensions.objectformat\",\n \t\t\t\thash_algos[hash_algo].name);\n \telse if (reinit)\n-\t\trepo_config_set_gently(the_repository, \"extensions.objectformat\", NULL);\n+\t\trepo_config_set_gently(repo, \"extensions.objectformat\", NULL);\n \n-\tif (the_repository->ref_storage_payload) {\n+\tif (repo->ref_storage_payload) {\n \t\tstruct strbuf ref_uri = STRBUF_INIT;\n \n \t\tstrbuf_addf(&ref_uri, \"%s://%s\",\n \t\t\t    ref_storage_format_to_name(ref_storage_format),\n-\t\t\t    the_repository->ref_storage_payload);\n-\t\trepo_config_set(the_repository, \"extensions.refstorage\", ref_uri.buf);\n+\t\t\t    repo->ref_storage_payload);\n+\t\trepo_config_set(repo, \"extensions.refstorage\", ref_uri.buf);\n \t\tstrbuf_release(&ref_uri);\n \t} else if (ref_storage_format != REF_STORAGE_FORMAT_FILES) {\n-\t\trepo_config_set(the_repository, \"extensions.refstorage\",\n+\t\trepo_config_set(repo, \"extensions.refstorage\",\n \t\t\t\tref_storage_format_to_name(ref_storage_format));\n \t} else if (reinit) {\n-\t\trepo_config_set_gently(the_repository, \"extensions.refstorage\", NULL);\n+\t\trepo_config_set_gently(repo, \"extensions.refstorage\", NULL);\n \t}\n \n \tif (reinit) {\n \t\tstruct strbuf config = STRBUF_INIT;\n \t\tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n \n-\t\trepo_common_path_append(the_repository, &config, \"config\");\n+\t\trepo_common_path_append(repo, &config, \"config\");\n \t\tread_repository_format(&repo_fmt, config.buf);\n \n \t\tif (repo_fmt.v1_only_extensions.nr)\n@@ -2440,17 +2441,17 @@ void initialize_repository_version(int hash_algo,\n \t\tclear_repository_format(&repo_fmt);\n \t}\n \n-\trepo_config_get_bool(the_repository, \"init.defaultSubmodulePathConfig\",\n+\trepo_config_get_bool(repo, \"init.defaultSubmodulePathConfig\",\n \t\t\t     &default_submodule_path_config);\n \tif (default_submodule_path_config) {\n \t\t/* extensions.submodulepathconfig requires at least version 1 */\n \t\tif (target_version == 0)\n \t\t\ttarget_version = 1;\n-\t\trepo_config_set(the_repository, \"extensions.submodulepathconfig\", \"true\");\n+\t\trepo_config_set(repo, \"extensions.submodulepathconfig\", \"true\");\n \t}\n \n \tstrbuf_addf(&repo_version, \"%d\", target_version);\n-\trepo_config_set(the_repository, \"core.repositoryformatversion\", repo_version.buf);\n+\trepo_config_set(repo, \"core.repositoryformatversion\", repo_version.buf);\n \n \tstrbuf_release(&repo_version);\n }\n@@ -2551,7 +2552,7 @@ static int create_default_files(struct repository *repo,\n \t\tadjust_shared_perm(repo, repo_get_git_dir(repo));\n \t}\n \n-\tinitialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, reinit);\n+\tinitialize_repository_version(repo, fmt->hash_algo, fmt->ref_storage_format, reinit);\n \n \t/* Check filemode trustability */\n \trepo_git_path_replace(repo, &path, \"config\");\ndiff --git a/setup.h b/setup.h\nindex a820041af0..c33b675ccf 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -232,7 +232,8 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t    enum ref_storage_format ref_storage_format,\n \t    const char *initial_branch, int init_shared_repository,\n \t    unsigned int flags);\n-void initialize_repository_version(int hash_algo,\n+void initialize_repository_version(struct repository *repo,\n+\t\t\t\t   int hash_algo,\n \t\t\t\t   enum ref_storage_format ref_storage_format,\n \t\t\t\t   int reinit);\n void create_reference_database(const char *initial_branch, int quiet);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543523","messageId":"20260518-pks-setup-wo-the-repository-v2-17-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 17/18] setup: stop using `the_repository` in `create_reference_database()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:31:08Z","receivedAt":"2026-05-18T09:31:50Z","isPatch":true,"body":"Stop using `the_repository` in `create_reference_database()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c |  2 +-\n setup.c         | 13 +++++++------\n setup.h         |  2 +-\n 3 files changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 24fe0eead5..53a41629e6 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1444,7 +1444,7 @@ int cmd_clone(int argc,\n \thash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));\n \tinitialize_repository_version(the_repository, hash_algo, the_repository->ref_storage_format, 1);\n \trepo_set_hash_algo(the_repository, hash_algo);\n-\tcreate_reference_database(NULL, 1);\n+\tcreate_reference_database(the_repository, NULL, 1);\n \n \t/*\n \t * Before fetching from the remote, download and install bundle\ndiff --git a/setup.c b/setup.c\nindex e09483ba34..9c49319568 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2468,13 +2468,14 @@ static int is_reinit(struct repository *repo)\n \treturn ret;\n }\n \n-void create_reference_database(const char *initial_branch, int quiet)\n+void create_reference_database(struct repository *repo,\n+\t\t\t       const char *initial_branch, int quiet)\n {\n \tstruct strbuf err = STRBUF_INIT;\n \tchar *to_free = NULL;\n-\tint reinit = is_reinit(the_repository);\n+\tint reinit = is_reinit(repo);\n \n-\tif (ref_store_create_on_disk(get_main_ref_store(the_repository), 0, &err))\n+\tif (ref_store_create_on_disk(get_main_ref_store(repo), 0, &err))\n \t\tdie(\"failed to set up refs db: %s\", err.buf);\n \n \t/*\n@@ -2486,14 +2487,14 @@ void create_reference_database(const char *initial_branch, int quiet)\n \n \t\tif (!initial_branch)\n \t\t\tinitial_branch = to_free =\n-\t\t\t\trepo_default_branch_name(the_repository, quiet);\n+\t\t\t\trepo_default_branch_name(repo, quiet);\n \n \t\tref = xstrfmt(\"refs/heads/%s\", initial_branch);\n \t\tif (check_refname_format(ref, 0) < 0)\n \t\t\tdie(_(\"invalid initial branch name: '%s'\"),\n \t\t\t    initial_branch);\n \n-\t\tif (refs_update_symref(get_main_ref_store(the_repository), \"HEAD\", ref, NULL) < 0)\n+\t\tif (refs_update_symref(get_main_ref_store(repo), \"HEAD\", ref, NULL) < 0)\n \t\t\texit(1);\n \t\tfree(ref);\n \t}\n@@ -2830,7 +2831,7 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\t\t\t      &repo_fmt, init_shared_repository);\n \n \tif (!(flags & INIT_DB_SKIP_REFDB))\n-\t\tcreate_reference_database(initial_branch, flags & INIT_DB_QUIET);\n+\t\tcreate_reference_database(the_repository, initial_branch, flags & INIT_DB_QUIET);\n \tcreate_object_directory(the_repository);\n \n \tif (repo_settings_get_shared_repository(the_repository)) {\ndiff --git a/setup.h b/setup.h\nindex c33b675ccf..21737e9bd6 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -236,7 +236,7 @@ void initialize_repository_version(struct repository *repo,\n \t\t\t\t   int hash_algo,\n \t\t\t\t   enum ref_storage_format ref_storage_format,\n \t\t\t\t   int reinit);\n-void create_reference_database(const char *initial_branch, int quiet);\n+void create_reference_database(struct repository *repo, const char *initial_branch, int quiet);\n \n /*\n  * NOTE NOTE NOTE!!\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543524","messageId":"20260518-pks-setup-wo-the-repository-v2-18-6933c0f1d568@pks.im","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"[PATCH v2 18/18] setup: stop using `the_repository` in `init_db()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-18T09:31:09Z","receivedAt":"2026-05-18T09:31:53Z","isPatch":true,"body":"Stop using `the_repository` in `init_db()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c   |  2 +-\n builtin/init-db.c |  2 +-\n setup.c           | 43 ++++++++++++++++++++++---------------------\n setup.h           |  3 ++-\n 4 files changed, 26 insertions(+), 24 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 53a41629e6..d60d1b60bc 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1186,7 +1186,7 @@ int cmd_clone(int argc,\n \t * repository, and reference backends may persist that information into\n \t * their on-disk data structures.\n \t */\n-\tinit_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,\n+\tinit_db(the_repository, git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,\n \t\tref_storage_format, NULL,\n \t\tdo_not_override_repo_unix_permissions, INIT_DB_QUIET | INIT_DB_SKIP_REFDB);\n \ndiff --git a/builtin/init-db.c b/builtin/init-db.c\nindex e626b0d8b7..c55517ad94 100644\n--- a/builtin/init-db.c\n+++ b/builtin/init-db.c\n@@ -252,7 +252,7 @@ int cmd_init_db(int argc,\n \t}\n \n \tflags |= INIT_DB_EXIST_OK;\n-\tret = init_db(git_dir, real_git_dir, template_dir, hash_algo,\n+\tret = init_db(the_repository, git_dir, real_git_dir, template_dir, hash_algo,\n \t\t      ref_storage_format, initial_branch,\n \t\t      init_shared_repository, flags);\n \ndiff --git a/setup.c b/setup.c\nindex 9c49319568..6aee839d8c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2778,7 +2778,8 @@ static void repository_format_configure(struct repository *repo,\n \t\t\t\t    repo_fmt->ref_storage_payload);\n }\n \n-int init_db(const char *git_dir, const char *real_git_dir,\n+int init_db(struct repository *repo,\n+\t    const char *git_dir, const char *real_git_dir,\n \t    const char *template_dir, int hash,\n \t    enum ref_storage_format ref_storage_format,\n \t    const char *initial_branch,\n@@ -2798,13 +2799,13 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\tif (!exist_ok && !stat(real_git_dir, &st))\n \t\t\tdie(_(\"%s already exists\"), real_git_dir);\n \n-\t\tset_git_dir(the_repository, real_git_dir, 1);\n-\t\tgit_dir = repo_get_git_dir(the_repository);\n+\t\tset_git_dir(repo, real_git_dir, 1);\n+\t\tgit_dir = repo_get_git_dir(repo);\n \t\tseparate_git_dir(git_dir, original_git_dir);\n \t}\n \telse {\n-\t\tset_git_dir(the_repository, git_dir, 1);\n-\t\tgit_dir = repo_get_git_dir(the_repository);\n+\t\tset_git_dir(repo, git_dir, 1);\n+\t\tgit_dir = repo_get_git_dir(repo);\n \t}\n \tstartup_info->have_repository = 1;\n \n@@ -2814,27 +2815,27 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t * config file, so this will not fail.  What we are catching\n \t * is an attempt to reinitialize new repository with an old tool.\n \t */\n-\tcheck_repository_format(the_repository, &repo_fmt);\n+\tcheck_repository_format(repo, &repo_fmt);\n \n-\trepository_format_configure(the_repository, &repo_fmt, hash, ref_storage_format);\n+\trepository_format_configure(repo, &repo_fmt, hash, ref_storage_format);\n \n \t/*\n \t * Ensure `core.hidedotfiles` is processed. This must happen after we\n \t * have set up the repository format such that we can evaluate\n \t * includeIf conditions correctly in the case of re-initialization.\n \t */\n-\trepo_config(the_repository, git_default_core_config, NULL);\n+\trepo_config(repo, git_default_core_config, NULL);\n \n-\tsafe_create_dir(the_repository, git_dir, 0);\n+\tsafe_create_dir(repo, git_dir, 0);\n \n-\treinit = create_default_files(the_repository, template_dir, original_git_dir,\n+\treinit = create_default_files(repo, template_dir, original_git_dir,\n \t\t\t\t      &repo_fmt, init_shared_repository);\n \n \tif (!(flags & INIT_DB_SKIP_REFDB))\n-\t\tcreate_reference_database(the_repository, initial_branch, flags & INIT_DB_QUIET);\n-\tcreate_object_directory(the_repository);\n+\t\tcreate_reference_database(repo, initial_branch, flags & INIT_DB_QUIET);\n+\tcreate_object_directory(repo);\n \n-\tif (repo_settings_get_shared_repository(the_repository)) {\n+\tif (repo_settings_get_shared_repository(repo)) {\n \t\tchar buf[10];\n \t\t/* We do not spell \"group\" and such, so that\n \t\t * the configuration can be read by older version\n@@ -2842,29 +2843,29 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\t * and compatibility values for PERM_GROUP and\n \t\t * PERM_EVERYBODY.\n \t\t */\n-\t\tif (repo_settings_get_shared_repository(the_repository) < 0)\n+\t\tif (repo_settings_get_shared_repository(repo) < 0)\n \t\t\t/* force to the mode value */\n-\t\t\txsnprintf(buf, sizeof(buf), \"0%o\", -repo_settings_get_shared_repository(the_repository));\n-\t\telse if (repo_settings_get_shared_repository(the_repository) == PERM_GROUP)\n+\t\t\txsnprintf(buf, sizeof(buf), \"0%o\", -repo_settings_get_shared_repository(repo));\n+\t\telse if (repo_settings_get_shared_repository(repo) == PERM_GROUP)\n \t\t\txsnprintf(buf, sizeof(buf), \"%d\", OLD_PERM_GROUP);\n-\t\telse if (repo_settings_get_shared_repository(the_repository) == PERM_EVERYBODY)\n+\t\telse if (repo_settings_get_shared_repository(repo) == PERM_EVERYBODY)\n \t\t\txsnprintf(buf, sizeof(buf), \"%d\", OLD_PERM_EVERYBODY);\n \t\telse\n \t\t\tBUG(\"invalid value for shared_repository\");\n-\t\trepo_config_set(the_repository, \"core.sharedrepository\", buf);\n-\t\trepo_config_set(the_repository, \"receive.denyNonFastforwards\", \"true\");\n+\t\trepo_config_set(repo, \"core.sharedrepository\", buf);\n+\t\trepo_config_set(repo, \"receive.denyNonFastforwards\", \"true\");\n \t}\n \n \tif (!(flags & INIT_DB_QUIET)) {\n \t\tint len = strlen(git_dir);\n \n \t\tif (reinit)\n-\t\t\tprintf(repo_settings_get_shared_repository(the_repository)\n+\t\t\tprintf(repo_settings_get_shared_repository(repo)\n \t\t\t       ? _(\"Reinitialized existing shared Git repository in %s%s\\n\")\n \t\t\t       : _(\"Reinitialized existing Git repository in %s%s\\n\"),\n \t\t\t       git_dir, len && git_dir[len-1] != '/' ? \"/\" : \"\");\n \t\telse\n-\t\t\tprintf(repo_settings_get_shared_repository(the_repository)\n+\t\t\tprintf(repo_settings_get_shared_repository(repo)\n \t\t\t       ? _(\"Initialized empty shared Git repository in %s%s\\n\")\n \t\t\t       : _(\"Initialized empty Git repository in %s%s\\n\"),\n \t\t\t       git_dir, len && git_dir[len-1] != '/' ? \"/\" : \"\");\ndiff --git a/setup.h b/setup.h\nindex 21737e9bd6..9409326fe4 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -227,7 +227,8 @@ const char *get_template_dir(const char *option_template);\n #define INIT_DB_EXIST_OK   (1 << 1)\n #define INIT_DB_SKIP_REFDB (1 << 2)\n \n-int init_db(const char *git_dir, const char *real_git_dir,\n+int init_db(struct repository *repo,\n+\t    const char *git_dir, const char *real_git_dir,\n \t    const char *template_dir, int hash_algo,\n \t    enum ref_storage_format ref_storage_format,\n \t    const char *initial_branch, int init_shared_repository,\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543580","messageId":"xmqqqzn89os3.fsf@gitster.g","threadId":"65515","inReplyTo":"agrD4p1AIPtwa5gW@pks.im","subject":"Re: [PATCH 02/18] setup: stop using `the_repository` in `is_inside_worktree()`","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-05-19T01:22:20Z","receivedAt":"2026-05-19T01:22:22Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n>> I do not offhand know if other code paths that are called from this\n>> function are thread-safe, but yeah, this use of file-scope static is\n>> not a safe thing to do.\n>\n> In the current status quo this is a safe conversion to do, as we still\n> have the assumption ingrained that this only works for a single repo.\n> We were using static variables before, and we're still using static\n> variables now.\n>\n> That being said, I wouldn't mind dropping the static variable if this is\n> something we'd rather want to get rid of. It's a smell that I'm not\n> particularly happy about myself.\n>\n> I'll send a revised version in a bit, thanks!\n\nOK.  In the v2 (perhaps v3?) series, I can see the removal of two\nstatic strbuf based \"optimizations\" is the only change since the\nprevious round (after merging the previous one to the base of the\nnew iteration and comparing the result with the new iteration).\n\nLooking very good.  Shall we mark the topic for 'next' now?\n\nThanks.\n\ndiff --git w/setup.c c/setup.c\nindex 1847111616..6aee839d8c 100644\n--- w/setup.c\n+++ c/setup.c\n@@ -471,17 +471,26 @@ int is_nonbare_repository_dir(struct strbuf *path)\n \n int is_inside_git_dir(struct repository *repo)\n {\n-\tstatic struct strbuf buf = STRBUF_INIT;\n-\treturn is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tint ret = is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));\n+\tstrbuf_release(&buf);\n+\treturn ret;\n }\n \n int is_inside_work_tree(struct repository *repo)\n {\n-\tstatic struct strbuf buf = STRBUF_INIT;\n-\tconst char *worktree = repo_get_work_tree(repo);\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tconst char *worktree;\n+\tint ret;\n+\n+\tworktree = repo_get_work_tree(repo);\n \tif (!worktree)\n \t\treturn 0;\n-\treturn is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n+\n+\tret = is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n+\n+\tstrbuf_release(&buf);\n+\treturn ret;\n }\n \n void setup_work_tree(struct repository *repo)\n"},{"id":"543598","messageId":"CAOLa=ZQkj=__pALxUxbqzh9h-RVO8nC=23h0Sb=gnF-ahHHzCQ@mail.gmail.com","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-1-6933c0f1d568@pks.im","subject":"Re: [PATCH v2 01/18] setup: replace use of `the_repository` in static functions","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2026-05-19T08:03:25Z","receivedAt":"2026-05-19T08:03:27Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Replace the use of `the_repository` in \"setup.c\" for all static\n> functions. For now, we simply add `the_repository` to invocations of\n> these functions. This will be addressed in subsequent commits, where\n> we'll move up `the_repository` one more layer to callers of \"setup.c\".\n>\n\nThis commit is straight forward. We simply pass forward the\n`the_repository` variable to static functions, so they have an incoming\n`strict repository *`. I like this approach of:\n\n1. Fixing up all static functions in a file to no longer use\n`the_repository`.\n2. Fixing up the other external functions one-by-one to receive a\n`struct repository *`.\n3. Fixing up any other global variables / config used.\n\nMakes it easy to follow.\n\n[snip]\n"},{"id":"543603","messageId":"CAOLa=ZT2Qo+oJ1rx2iM3QRcXMGaucFRJdxBAgxBdz3ZtgSb=Qg@mail.gmail.com","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-2-6933c0f1d568@pks.im","subject":"Re: [PATCH v2 02/18] setup: stop using `the_repository` in `is_inside_worktree()`","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2026-05-19T08:23:21Z","receivedAt":"2026-05-19T08:23:23Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> The function `is_inside_worktree()` verifies whether or not the current\n\nNit: Here and the subject s/is_inside_worktree/is_inside_work_tree/\n\nHonestly, I would prefer `worktree` as that's what we've used through\nout the code base, but that is probably out of scope here.\n\n> working directory is located inside the worktree of `the_repository`.\n> This is done by taking the worktree path and verifying that it's a\n> prefix of the current working directory.\n>\n> This information is cached so that we don't have to re-do this change\n> multiple times. Furthermore, we proactively set the value in multiple\n> locations so that we don't even have to perform the check when we have\n> discovered the repository.\n>\n> While we could simply move the caching variable into the repository, the\n> current layout doesn't really feel sensible in the first place:\n>\n>   - It can easily lead to false positives or negatives if at any point\n>     in time we may switch the current working directory.\n>\n>   - We don't call the function in a hot loop, and neither is it overly\n>     expensive to compute.\n>\n> Drop the caching infrastructure and instead compute the property ad-hoc\n> via an injected repository.\n\nSo the caching mechanism is simply a global variable pre-set to -1.\nOkay, so that's a good improvement.\n\n>\n> Note that there is one small gotcha: we sometimes may end up with\n> relative directory paths, and if so `is_inside_dir()` might fail. This\n> wasn't an issue before because of how we proactively set the cached\n> value during repository discovery. Now that we stop doing that it\n> becomes a problem though, but it is worked around by resolving the\n> repository directory via `realpath()`.\n>\n\nCurious if you discovered this via a test. But running the tests\nwithout `realpath()` didn't trigger any failures. Is this something we\ncan add a test for?\n\n[snip]\n"},{"id":"543604","messageId":"CAOLa=ZRus0wTn70xCusFHQ-fvLFHG5f+i3jdKb+j8PhdqtwZZw@mail.gmail.com","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-3-6933c0f1d568@pks.im","subject":"Re: [PATCH v2 03/18] setup: stop using `the_repository` in `is_inside_git_dir()`","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2026-05-19T08:25:18Z","receivedAt":"2026-05-19T08:25:20Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n[snip]\n\n> -int is_inside_git_dir(void)\n> +int is_inside_git_dir(struct repository *repo)\n>  {\n> -\tif (inside_git_dir < 0)\n> -\t\tinside_git_dir = is_inside_dir(repo_get_git_dir(the_repository));\n> -\treturn inside_git_dir;\n> +\tstruct strbuf buf = STRBUF_INIT;\n> +\tint ret = is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));\n> +\tstrbuf_release(&buf);\n> +\treturn ret;\n>  }\n>\n\nFor `is_inside_work_tree()` we also check the return value of\n`repo_get_work_tree(repo)`, but here `repo_get_git_dir(repo)` is\ndirectly fed into `is_inside_dir()`. That's because the latter already\nBUGs out if the value is not set. Looks good.\n\n[snip]\n"},{"id":"543611","messageId":"CAOLa=ZSxhtorR+t-4M_COxfu6HwpcB0hr43OhqcwgkU+VLX6qQ@mail.gmail.com","threadId":"65515","inReplyTo":"20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im","subject":"Re: [PATCH v2 00/18] setup: drop uses of `the_repository`","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2026-05-19T09:26:35Z","receivedAt":"2026-05-19T09:26:37Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Hi,\n>\n> I've had enough of \"setup.c\" and its complexities, so I finally decided\n> to take the bullet and start refactoring this subsystem. This here is\n> the first out of the following three steps:\n>\n>   1. Drop all uses of `the_repository`. This doesn't yet allow us to get\n>      rid of `USE_THE_REPOSITORY_VARIABLE`.\n>\n>   2. Convert a couple of global variables and drop\n>      `is_bare_repository_cfg`, which then allows us to drop\n>      `USE_THE_REPOSITORY_VARIABLE`.\n>\n>   3. Refactor the subsystem a bit so that we stop intermixing repository\n>      discovery and repository initialization. This is my original\n>      motivation as I want to get rid of `odb_prepare_alternates()`, but\n>      due to the way we initialize the repository it has proven to be\n>      extremely tedious.\n>\n> Most of the patches in this series here are rather mechanical. There's\n> only a handful of patches that warrant more attention:\n>\n>   -  2/18: setup: stop using `the_repository` in `is_inside_worktree()`\n>   -  3/18: setup: stop using `the_repository` in `is_inside_git_dir()`\n>   -  9/18: setup: stop using `the_repository` in `setup_work_tree()`\n>   - 10/18: setup: stop using `the_repository` in `set_git_work_tree()`\n>\n\nI think the series looks to be in a good state, I left some small nits,\nfeel free to ignore.\n\n- Karthik\n"},{"id":"543613","messageId":"agwxwNIfZuwj9qod@pks.im","threadId":"65515","inReplyTo":"CAOLa=ZT2Qo+oJ1rx2iM3QRcXMGaucFRJdxBAgxBdz3ZtgSb=Qg@mail.gmail.com","subject":"Re: [PATCH v2 02/18] setup: stop using `the_repository` in `is_inside_worktree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:47:44Z","receivedAt":"2026-05-19T09:47:51Z","isPatch":true,"body":"On Tue, May 19, 2026 at 01:23:21AM -0700, Karthik Nayak wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > The function `is_inside_worktree()` verifies whether or not the current\n> \n> Nit: Here and the subject s/is_inside_worktree/is_inside_work_tree/\n> \n> Honestly, I would prefer `worktree` as that's what we've used through\n> out the code base, but that is probably out of scope here.\n\nOh, good eyes.\n\n> > Note that there is one small gotcha: we sometimes may end up with\n> > relative directory paths, and if so `is_inside_dir()` might fail. This\n> > wasn't an issue before because of how we proactively set the cached\n> > value during repository discovery. Now that we stop doing that it\n> > becomes a problem though, but it is worked around by resolving the\n> > repository directory via `realpath()`.\n> >\n> \n> Curious if you discovered this via a test. But running the tests\n> without `realpath()` didn't trigger any failures. Is this something we\n> can add a test for?\n\nNo, I wasn't able to come up with a test for this. I think overall the\nparagraph could use some tweaking as it's warning about something that\ncannot happen right now.\n\nOriginally, I had the order of `is_inside_work_tree()` and\n`is_inside_git_dir()` reversed, and I had most of the commit message in\n`is_inside_git_dir()`. So this explanation here was originally part of\nthe gitdir commit, and here it is correct: when setting the repo's\ngitdir we don't resolve it to its real path. And not using the real path\ndoes make tests fail in this case.\n\nBut this is different for the work tree: the only caller that sets\nthe repository's worktree is `repo_set_worktree()`, and that function\ndoes use `real_pathdup()` to resolve the path. So we know that the\nworktree is always the absolute resolved path, and consequently it's\nunnecessary to resolve the variable again.\n\nSo there's two ways to handle that:\n\n  - We could be defensive about it and continue to allow a relative or\n    non-resolved worktree path here and manually resolve.\n\n  - We could rely on the fact that currently the worktree path is always\n    resolved anyway.\n\nI think a world where we only ever use absolute paths is preferable, but\nI honestly don't trust our repository setup infrastructure enough to say\nthat this assumption will never break. Furthermore, it would create some\nasymmetry between `is_inside_git_dir()` and `is_inside_work_tree()` that\nis overall a bit puzzling.\n\nI guess the proper fix for this would be to also change the repository's\ngitdir to be an absolute path. But that would result in a bunch of\nuser-visible changes, both in error messages and in commands like `git\nrev-parse --git-common-dir`.\n\nMeanwhile I'm more leaning into the direction of keeping the code\nas-is, but correct the commit message.\n\nThanks!\n\nPatrick\n"},{"id":"543614","messageId":"agwyf8LATRyY0kAq@pks.im","threadId":"65515","inReplyTo":"xmqqqzn89os3.fsf@gitster.g","subject":"Re: [PATCH 02/18] setup: stop using `the_repository` in `is_inside_worktree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:50:55Z","receivedAt":"2026-05-19T09:51:01Z","isPatch":true,"body":"On Tue, May 19, 2026 at 10:22:20AM +0900, Junio C Hamano wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> >> I do not offhand know if other code paths that are called from this\n> >> function are thread-safe, but yeah, this use of file-scope static is\n> >> not a safe thing to do.\n> >\n> > In the current status quo this is a safe conversion to do, as we still\n> > have the assumption ingrained that this only works for a single repo.\n> > We were using static variables before, and we're still using static\n> > variables now.\n> >\n> > That being said, I wouldn't mind dropping the static variable if this is\n> > something we'd rather want to get rid of. It's a smell that I'm not\n> > particularly happy about myself.\n> >\n> > I'll send a revised version in a bit, thanks!\n> \n> OK.  In the v2 (perhaps v3?) series, I can see the removal of two\n> static strbuf based \"optimizations\" is the only change since the\n> previous round (after merging the previous one to the base of the\n> new iteration and comparing the result with the new iteration).\n> \n> Looking very good.  Shall we mark the topic for 'next' now?\n\nI'll send one final round to address Karthik's comment on the commit\nmessage, but once that's out I think this series is ready. Thanks!\n\nPatrick\n"},{"id":"543615","messageId":"agwytzUXxa6zIBHV@pks.im","threadId":"65515","inReplyTo":"CAOLa=ZSxhtorR+t-4M_COxfu6HwpcB0hr43OhqcwgkU+VLX6qQ@mail.gmail.com","subject":"Re: [PATCH v2 00/18] setup: drop uses of `the_repository`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:51:51Z","receivedAt":"2026-05-19T09:51:57Z","isPatch":true,"body":"On Tue, May 19, 2026 at 02:26:35AM -0700, Karthik Nayak wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > Hi,\n> >\n> > I've had enough of \"setup.c\" and its complexities, so I finally decided\n> > to take the bullet and start refactoring this subsystem. This here is\n> > the first out of the following three steps:\n> >\n> >   1. Drop all uses of `the_repository`. This doesn't yet allow us to get\n> >      rid of `USE_THE_REPOSITORY_VARIABLE`.\n> >\n> >   2. Convert a couple of global variables and drop\n> >      `is_bare_repository_cfg`, which then allows us to drop\n> >      `USE_THE_REPOSITORY_VARIABLE`.\n> >\n> >   3. Refactor the subsystem a bit so that we stop intermixing repository\n> >      discovery and repository initialization. This is my original\n> >      motivation as I want to get rid of `odb_prepare_alternates()`, but\n> >      due to the way we initialize the repository it has proven to be\n> >      extremely tedious.\n> >\n> > Most of the patches in this series here are rather mechanical. There's\n> > only a handful of patches that warrant more attention:\n> >\n> >   -  2/18: setup: stop using `the_repository` in `is_inside_worktree()`\n> >   -  3/18: setup: stop using `the_repository` in `is_inside_git_dir()`\n> >   -  9/18: setup: stop using `the_repository` in `setup_work_tree()`\n> >   - 10/18: setup: stop using `the_repository` in `set_git_work_tree()`\n> >\n> \n> I think the series looks to be in a good state, I left some small nits,\n> feel free to ignore.\n\nI'll send one more round to address your feedback. Thanks!\n\nPatrick\n"},{"id":"543616","messageId":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im","subject":"[PATCH v3 00/18] setup: drop uses of `the_repository`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:04Z","receivedAt":"2026-05-19T09:52:14Z","isPatch":true,"body":"Hi,\n\nI've had enough of \"setup.c\" and its complexities, so I finally decided\nto take the bullet and start refactoring this subsystem. This here is\nthe first out of the following three steps:\n\n  1. Drop all uses of `the_repository`. This doesn't yet allow us to get\n     rid of `USE_THE_REPOSITORY_VARIABLE`.\n\n  2. Convert a couple of global variables and drop\n     `is_bare_repository_cfg`, which then allows us to drop\n     `USE_THE_REPOSITORY_VARIABLE`.\n\n  3. Refactor the subsystem a bit so that we stop intermixing repository\n     discovery and repository initialization. This is my original\n     motivation as I want to get rid of `odb_prepare_alternates()`, but\n     due to the way we initialize the repository it has proven to be\n     extremely tedious.\n\nMost of the patches in this series here are rather mechanical. There's\nonly a handful of patches that warrant more attention:\n\n  -  2/18: setup: stop using `the_repository` in `is_inside_worktree()`\n  -  3/18: setup: stop using `the_repository` in `is_inside_git_dir()`\n  -  9/18: setup: stop using `the_repository` in `setup_work_tree()`\n  - 10/18: setup: stop using `the_repository` in `set_git_work_tree()`\n\nThose patches don't only mechanical move stuff around, but also change\nsome logic to make it work.\n\nChanges in v3:\n  - Reverse the order of the commits that refactor `is_inside_gitdir()`\n    and `is_inside_work_tree()` and clarify the logic around why we do\n    (or do not) have to use realpath(3p). The code is ultimately not\n    changed though, we still resolve the realpath for both even though\n    it's not strictly necessary to do so for the working tree.\n  - Link to v2: https://patch.msgid.link/20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im\n\nChanges in v2:\n  - Drop some static variables.\n  - Rebase on top of origin/master at 59ff4886a5 (Merge branch\n    'ps/clang-w-glibc-2.43-and-_Generic', 2026-05-13). This resolves a\n    single conflict, but more importantly the rebase fixes CI.\n  - Link to v1: https://patch.msgid.link/20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im\n\nChanges in v1 (relative to the botched-up [1]):\n  - Remove static `initialized` variable in `setup_work_tree()`.\n  - Use enum values to initialize fields.\n  - Fix up a comment.\n  - Link to v1: https://lore.kernel.org/all/20260330-pks-setup-wo-the-repository-v1-0-0d2e822837aa@pks.im/\n\nThanks!\n\nPatrick\n\n[1]: <20260330-pks-setup-wo-the-repository-v1-0-0d2e822837aa@pks.im>\n\n---\nPatrick Steinhardt (18):\n      setup: replace use of `the_repository` in static functions\n      setup: stop using `the_repository` in `is_inside_git_dir()`\n      setup: stop using `the_repository` in `is_inside_work_tree()`\n      setup: stop using `the_repository` in `prefix_path()`\n      setup: stop using `the_repository` in `path_inside_repo()`\n      setup: stop using `the_repository` in `verify_filename()`\n      setup: stop using `the_repository` in `verify_non_filename()`\n      setup: stop using `the_repository` in `enter_repo()`\n      setup: stop using `the_repository` in `setup_work_tree()`\n      setup: stop using `the_repository` in `set_git_work_tree()`\n      setup: stop using `the_repository` in `setup_git_env()`\n      setup: stop using `the_repository` in `setup_git_directory_gently()`\n      setup: stop using `the_repository` in `setup_git_directory()`\n      setup: stop using `the_repository` in `upgrade_repository_format()`\n      setup: stop using `the_repository` in `check_repository_format()`\n      setup: stop using `the_repository` in `initialize_repository_version()`\n      setup: stop using `the_repository` in `create_reference_database()`\n      setup: stop using `the_repository` in `init_db()`\n\n archive.c                                    |   2 +-\n blame.c                                      |   2 +-\n builtin/blame.c                              |   2 +-\n builtin/check-attr.c                         |   4 +-\n builtin/check-ref-format.c                   |   5 +-\n builtin/checkout-index.c                     |   4 +-\n builtin/checkout.c                           |   2 +-\n builtin/clone.c                              |  12 +-\n builtin/describe.c                           |   2 +-\n builtin/diff-index.c                         |   2 +-\n builtin/diff.c                               |  10 +-\n builtin/difftool.c                           |   2 +-\n builtin/grep.c                               |   8 +-\n builtin/hash-object.c                        |   4 +-\n builtin/help.c                               |   2 +-\n builtin/init-db.c                            |   8 +-\n builtin/ls-files.c                           |   4 +-\n builtin/merge-file.c                         |   2 +-\n builtin/mv.c                                 |   5 +-\n builtin/read-tree.c                          |   2 +-\n builtin/receive-pack.c                       |   2 +-\n builtin/reset.c                              |   6 +-\n builtin/rev-parse.c                          |  14 +-\n builtin/rm.c                                 |   2 +-\n builtin/sparse-checkout.c                    |  19 +-\n builtin/stripspace.c                         |   2 +-\n builtin/submodule--helper.c                  |   2 +-\n builtin/update-index.c                       |  16 +-\n builtin/upload-archive.c                     |   2 +-\n builtin/upload-pack.c                        |   2 +-\n daemon.c                                     |   4 +-\n environment.h                                |   2 -\n git.c                                        |  10 +-\n http-backend.c                               |   2 +-\n http-fetch.c                                 |   2 +-\n http-push.c                                  |   2 +-\n imap-send.c                                  |   2 +-\n line-log.c                                   |   2 +-\n list-objects-filter-options.c                |   2 +-\n object-name.c                                |   4 +-\n pathspec.c                                   |   2 +-\n refs.c                                       |   2 +-\n remote-curl.c                                |   4 +-\n repository.h                                 |   4 +-\n revision.c                                   |   6 +-\n scalar.c                                     |   4 +-\n setup.c                                      | 451 ++++++++++++++-------------\n setup.h                                      |  43 ++-\n submodule.c                                  |   2 +-\n t/helper/test-advise.c                       |   2 +-\n t/helper/test-bitmap.c                       |   2 +-\n t/helper/test-bloom.c                        |   2 +-\n t/helper/test-cache-tree.c                   |   2 +-\n t/helper/test-config.c                       |   2 +-\n t/helper/test-dump-cache-tree.c              |   2 +-\n t/helper/test-dump-fsmonitor.c               |   2 +-\n t/helper/test-dump-split-index.c             |   2 +-\n t/helper/test-dump-untracked-cache.c         |   2 +-\n t/helper/test-find-pack.c                    |   2 +-\n t/helper/test-fsmonitor-client.c             |   2 +-\n t/helper/test-lazy-init-name-hash.c          |   2 +-\n t/helper/test-match-trees.c                  |   2 +-\n t/helper/test-pack-deltas.c                  |   2 +-\n t/helper/test-pack-mtimes.c                  |   2 +-\n t/helper/test-partial-clone.c                |   4 +-\n t/helper/test-path-utils.c                   |   4 +-\n t/helper/test-path-walk.c                    |   2 +-\n t/helper/test-reach.c                        |   2 +-\n t/helper/test-read-cache.c                   |   2 +-\n t/helper/test-read-graph.c                   |   2 +-\n t/helper/test-read-midx.c                    |   2 +-\n t/helper/test-ref-store.c                    |   2 +-\n t/helper/test-revision-walking.c             |   2 +-\n t/helper/test-scrap-cache-tree.c             |   2 +-\n t/helper/test-serve-v2.c                     |   2 +-\n t/helper/test-submodule-config.c             |   2 +-\n t/helper/test-submodule-nested-repo-config.c |   2 +-\n t/helper/test-submodule.c                    |  10 +-\n t/helper/test-subprocess.c                   |   6 +-\n t/helper/test-userdiff.c                     |   2 +-\n t/helper/test-write-cache.c                  |   2 +-\n worktree.c                                   |   2 +-\n wt-status.c                                  |   2 +-\n 83 files changed, 402 insertions(+), 383 deletions(-)\n\nRange-diff versus v2:\n\n 1:  55bee14899 =  1:  2ebdbac05f setup: replace use of `the_repository` in static functions\n 3:  eaedc9e0d6 !  2:  23ab6d8d17 setup: stop using `the_repository` in `is_inside_git_dir()`\n    @@ Metadata\n      ## Commit message ##\n         setup: stop using `the_repository` in `is_inside_git_dir()`\n     \n    -    Similar as with the preceding commit, `is_inside_git_dir()` determines\n    -    whether the current working directory is located inside the gitdir of\n    -    `the_repository`. Perform the same refactoring by dropping the caching\n    -    mechanism and injecting the repository that shall be checked.\n    +    The function `is_inside_git_dir()` verifies whether or not the current\n    +    working directory is located inside the gitdir of `the_repository`. This\n    +    is done by taking the gitdir path and verifying that it's a prefix of\n    +    the current working directory.\n    +\n    +    This information is cached so that we don't have to re-do this change\n    +    multiple times. Furthermore, we proactively set the value in multiple\n    +    locations so that we don't even have to perform the check when we have\n    +    discovered the repository.\n    +\n    +    While we could simply move the caching variable into the repository, the\n    +    current layout doesn't really feel sensible in the first place:\n    +\n    +      - It can easily lead to false positives or negatives if at any point\n    +        in time we may switch the current working directory.\n    +\n    +      - We don't call the function in a hot loop, and neither is it overly\n    +        expensive to compute.\n    +\n    +    Drop the caching infrastructure and instead compute the property ad-hoc\n    +    via an injected repository.\n    +\n    +    Note that there is one small gotcha: we often end up with relative\n    +    gitdir paths, and if so `is_inside_dir()` might fail. This wasn't an\n    +    issue before because of how we proactively set the cached value during\n    +    repository discovery. Now that we stop doing that it becomes a problem\n    +    though, which we work around by resolving the gitdir via `realpath()`.\n     \n         Signed-off-by: Patrick Steinhardt <ps@pks.im>\n     \n    @@ setup.c\n      #include \"worktree.h\"\n      \n     -static int inside_git_dir = -1;\n    + static int inside_work_tree = -1;\n      static int work_tree_config_is_bogus;\n      enum allowed_bare_repo {\n    - \tALLOWED_BARE_REPO_EXPLICIT = 0,\n     @@ setup.c: void verify_filename(const char *prefix,\n       */\n      void verify_non_filename(const char *prefix, const char *arg)\n      {\n    --\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir())\n    -+\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir(the_repository))\n    +-\tif (!is_inside_work_tree() || is_inside_git_dir())\n    ++\tif (!is_inside_work_tree() || is_inside_git_dir(the_repository))\n      \t\treturn;\n      \tif (*arg == '-')\n      \t\treturn; /* flag */\n    @@ setup.c: int is_nonbare_repository_dir(struct strbuf *path)\n     +\treturn ret;\n      }\n      \n    - int is_inside_work_tree(struct repository *repo)\n    + int is_inside_work_tree(void)\n     @@ setup.c: static const char *setup_discovered_git_dir(struct repository *repo,\n      \tset_git_work_tree(\".\");\n      \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n      \t\tset_git_dir(repo, gitdir, 0);\n     -\tinside_git_dir = 0;\n    + \tinside_work_tree = 1;\n      \tif (offset >= cwd->len)\n      \t\treturn NULL;\n    - \n     @@ setup.c: static const char *setup_bare_git_dir(struct repository *repo,\n      \t\treturn setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n      \t}\n      \n     -\tinside_git_dir = 1;\n    + \tinside_work_tree = 0;\n      \tif (offset != cwd->len) {\n      \t\tif (chdir(cwd->buf))\n    - \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n     \n      ## setup.h ##\n     @@\n    @@ setup.h\n      \n     -int is_inside_git_dir(void);\n     +int is_inside_git_dir(struct repository *repo);\n    - int is_inside_work_tree(struct repository *repo);\n    + int is_inside_work_tree(void);\n      int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);\n      int get_common_dir(struct strbuf *sb, const char *gitdir);\n 2:  b9aef04ffe !  3:  9f9aa3869d setup: stop using `the_repository` in `is_inside_worktree()`\n    @@ Metadata\n     Author: Patrick Steinhardt <ps@pks.im>\n     \n      ## Commit message ##\n    -    setup: stop using `the_repository` in `is_inside_worktree()`\n    +    setup: stop using `the_repository` in `is_inside_work_tree()`\n     \n    -    The function `is_inside_worktree()` verifies whether or not the current\n    -    working directory is located inside the worktree of `the_repository`.\n    -    This is done by taking the worktree path and verifying that it's a\n    -    prefix of the current working directory.\n    +    Similar as with the preceding commit, `is_inside_work_tree()` determines\n    +    whether the current working directory is located inside the worktree of\n    +    `the_repository`. Perform the same refactoring by dropping the caching\n    +    mechanism and injecting the repository that shall be checked.\n     \n    -    This information is cached so that we don't have to re-do this change\n    -    multiple times. Furthermore, we proactively set the value in multiple\n    -    locations so that we don't even have to perform the check when we have\n    -    discovered the repository.\n    -\n    -    While we could simply move the caching variable into the repository, the\n    -    current layout doesn't really feel sensible in the first place:\n    -\n    -      - It can easily lead to false positives or negatives if at any point\n    -        in time we may switch the current working directory.\n    -\n    -      - We don't call the function in a hot loop, and neither is it overly\n    -        expensive to compute.\n    -\n    -    Drop the caching infrastructure and instead compute the property ad-hoc\n    -    via an injected repository.\n    -\n    -    Note that there is one small gotcha: we sometimes may end up with\n    -    relative directory paths, and if so `is_inside_dir()` might fail. This\n    -    wasn't an issue before because of how we proactively set the cached\n    -    value during repository discovery. Now that we stop doing that it\n    -    becomes a problem though, but it is worked around by resolving the\n    -    repository directory via `realpath()`.\n    +    Note that, same as in the preceding commit, we're also resolving the\n    +    worktree path via `realpath()`. In theory this step is not necessary as\n    +    we always set the worktree path via `repo_set_worktree()`, and that\n    +    function already resolves the path for us. But resolving the path a\n    +    second time is unlikely to matter performance-wise, and it feels fragile\n    +    to rely on the repository's worktree path being absolute. We thus\n    +    perform the same extra step even though it's ultimately not required.\n     \n         Signed-off-by: Patrick Steinhardt <ps@pks.im>\n     \n    @@ object-name.c: static char *resolve_relative_path(struct repository *r, const ch\n     \n      ## setup.c ##\n     @@\n    + #include \"trace2.h\"\n      #include \"worktree.h\"\n      \n    - static int inside_git_dir = -1;\n     -static int inside_work_tree = -1;\n      static int work_tree_config_is_bogus;\n      enum allowed_bare_repo {\n    @@ setup.c: void verify_filename(const char *prefix,\n       */\n      void verify_non_filename(const char *prefix, const char *arg)\n      {\n    --\tif (!is_inside_work_tree() || is_inside_git_dir())\n    -+\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir())\n    +-\tif (!is_inside_work_tree() || is_inside_git_dir(the_repository))\n    ++\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir(the_repository))\n      \t\treturn;\n      \tif (*arg == '-')\n      \t\treturn; /* flag */\n    -@@ setup.c: int is_inside_git_dir(void)\n    - \treturn inside_git_dir;\n    +@@ setup.c: int is_inside_git_dir(struct repository *repo)\n    + \treturn ret;\n      }\n      \n     -int is_inside_work_tree(void)\n    @@ setup.c: static int check_repository_format_gently(struct repository *repo,\n      \t}\n      \n     @@ setup.c: static const char *setup_discovered_git_dir(struct repository *repo,\n    + \tset_git_work_tree(\".\");\n      \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n      \t\tset_git_dir(repo, gitdir, 0);\n    - \tinside_git_dir = 0;\n     -\tinside_work_tree = 1;\n      \tif (offset >= cwd->len)\n      \t\treturn NULL;\n      \n     @@ setup.c: static const char *setup_bare_git_dir(struct repository *repo,\n    + \t\treturn setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n      \t}\n      \n    - \tinside_git_dir = 1;\n     -\tinside_work_tree = 0;\n      \tif (offset != cwd->len) {\n      \t\tif (chdir(cwd->buf))\n    @@ setup.h\n     @@\n      #include \"string-list.h\"\n      \n    - int is_inside_git_dir(void);\n    + int is_inside_git_dir(struct repository *repo);\n     -int is_inside_work_tree(void);\n     +int is_inside_work_tree(struct repository *repo);\n      int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);\n 4:  60accc2ec9 =  4:  ce095cefaa setup: stop using `the_repository` in `prefix_path()`\n 5:  ced765c68e =  5:  dd21e47a5c setup: stop using `the_repository` in `path_inside_repo()`\n 6:  2d119a5570 =  6:  ba8b6bfe0d setup: stop using `the_repository` in `verify_filename()`\n 7:  1867994202 =  7:  f6bf7e5477 setup: stop using `the_repository` in `verify_non_filename()`\n 8:  c17b96c516 =  8:  886c1a6e20 setup: stop using `the_repository` in `enter_repo()`\n 9:  e3ce4b5056 =  9:  a127018412 setup: stop using `the_repository` in `setup_work_tree()`\n10:  e26be95df8 = 10:  8f9a63b82f setup: stop using `the_repository` in `set_git_work_tree()`\n11:  83c38c45d2 = 11:  35a9857ef0 setup: stop using `the_repository` in `setup_git_env()`\n12:  153ce789de = 12:  2873901d89 setup: stop using `the_repository` in `setup_git_directory_gently()`\n13:  1f10dd9c99 = 13:  7e63ec5f01 setup: stop using `the_repository` in `setup_git_directory()`\n14:  9f19eba3df = 14:  c227ac83dd setup: stop using `the_repository` in `upgrade_repository_format()`\n15:  ff19c1691d = 15:  70bff29c9a setup: stop using `the_repository` in `check_repository_format()`\n16:  dc8072eaf7 = 16:  31e794edc3 setup: stop using `the_repository` in `initialize_repository_version()`\n17:  e9c035694e = 17:  4bbab827ab setup: stop using `the_repository` in `create_reference_database()`\n18:  0fde37999c = 18:  74c9379b28 setup: stop using `the_repository` in `init_db()`\n\n---\nbase-commit: 59ff4886a579f4bc91e976fe18590b9ae02c7a08\nchange-id: 20260330-pks-setup-wo-the-repository-81e51bc55b91\n\n"},{"id":"543617","messageId":"20260519-pks-setup-wo-the-repository-v3-1-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 01/18] setup: replace use of `the_repository` in static functions","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:05Z","receivedAt":"2026-05-19T09:52:16Z","isPatch":true,"body":"Replace the use of `the_repository` in \"setup.c\" for all static\nfunctions. For now, we simply add `the_repository` to invocations of\nthese functions. This will be addressed in subsequent commits, where\nwe'll move up `the_repository` one more layer to callers of \"setup.c\".\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n setup.c | 188 ++++++++++++++++++++++++++++++++++------------------------------\n 1 file changed, 100 insertions(+), 88 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex 7ec4427368..ba2898473a 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -50,13 +50,13 @@ const char *tmp_original_cwd;\n  * /dir/repolink/file     (repolink points to /dir/repo) -> file\n  * /dir/repo              (exactly equal to work tree)   -> (empty string)\n  */\n-static int abspath_part_inside_repo(char *path)\n+static int abspath_part_inside_repo(struct repository *repo, char *path)\n {\n \tsize_t len;\n \tsize_t wtlen;\n \tchar *path0;\n \tint off;\n-\tconst char *work_tree = precompose_string_if_needed(repo_get_work_tree(the_repository));\n+\tconst char *work_tree = precompose_string_if_needed(repo_get_work_tree(repo));\n \tstruct strbuf realpath = STRBUF_INIT;\n \n \tif (!work_tree)\n@@ -132,7 +132,7 @@ char *prefix_path_gently(const char *prefix, int len,\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n-\t\tif (abspath_part_inside_repo(sanitized)) {\n+\t\tif (abspath_part_inside_repo(the_repository, sanitized)) {\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n@@ -509,7 +509,7 @@ void setup_work_tree(void)\n \tinitialized = 1;\n }\n \n-static void setup_original_cwd(void)\n+static void setup_original_cwd(struct repository *repo)\n {\n \tstruct strbuf tmp = STRBUF_INIT;\n \tconst char *worktree = NULL;\n@@ -535,9 +535,9 @@ static void setup_original_cwd(void)\n \n \t/* Normalize the directory */\n \tif (!strbuf_realpath(&tmp, tmp_original_cwd, 0)) {\n-\t\ttrace2_data_string(\"setup\", the_repository,\n+\t\ttrace2_data_string(\"setup\", repo,\n \t\t\t\t   \"realpath-path\", tmp_original_cwd);\n-\t\ttrace2_data_string(\"setup\", the_repository,\n+\t\ttrace2_data_string(\"setup\", repo,\n \t\t\t\t   \"realpath-failure\", strerror(errno));\n \t\tfree((char*)tmp_original_cwd);\n \t\ttmp_original_cwd = NULL;\n@@ -552,7 +552,7 @@ static void setup_original_cwd(void)\n \t * Get our worktree; we only protect the current working directory\n \t * if it's in the worktree.\n \t */\n-\tworktree = repo_get_work_tree(the_repository);\n+\tworktree = repo_get_work_tree(repo);\n \tif (!worktree)\n \t\tgoto no_prevention_needed;\n \n@@ -747,7 +747,10 @@ static int check_repo_format(const char *var, const char *value,\n \treturn read_worktree_config(var, value, ctx, vdata);\n }\n \n-static int check_repository_format_gently(const char *gitdir, struct repository_format *candidate, int *nongit_ok)\n+static int check_repository_format_gently(struct repository *repo,\n+\t\t\t\t\t  const char *gitdir,\n+\t\t\t\t\t  struct repository_format *candidate,\n+\t\t\t\t\t  int *nongit_ok)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n \tstruct strbuf err = STRBUF_INIT;\n@@ -776,7 +779,7 @@ static int check_repository_format_gently(const char *gitdir, struct repository_\n \t\tdie(\"%s\", err.buf);\n \t}\n \n-\tthe_repository->repository_format_precious_objects = candidate->precious_objects;\n+\trepo->repository_format_precious_objects = candidate->precious_objects;\n \n \tstring_list_clear(&candidate->unknown_extensions, 0);\n \tstring_list_clear(&candidate->v1_only_extensions, 0);\n@@ -1034,7 +1037,8 @@ const char *read_gitfile_gently(const char *path, int *return_error_code)\n \treturn error_code ? NULL : path;\n }\n \n-static void setup_git_env_internal(const char *git_dir,\n+static void setup_git_env_internal(struct repository *repo,\n+\t\t\t\t   const char *git_dir,\n \t\t\t\t   bool skip_initializing_odb)\n {\n \tchar *git_replace_ref_base;\n@@ -1052,7 +1056,7 @@ static void setup_git_env_internal(const char *git_dir,\n \t\targs.disable_ref_updates = true;\n \targs.skip_initializing_odb = skip_initializing_odb;\n \n-\trepo_set_gitdir(the_repository, git_dir, &args);\n+\trepo_set_gitdir(repo, git_dir, &args);\n \tstrvec_clear(&to_free);\n \n \tif (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))\n@@ -1064,7 +1068,7 @@ static void setup_git_env_internal(const char *git_dir,\n \n \tshallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);\n \tif (shallow_file)\n-\t\tset_alternate_shallow_file(the_repository, shallow_file, 0);\n+\t\tset_alternate_shallow_file(repo, shallow_file, 0);\n \n \tif (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0))\n \t\tfetch_if_missing = 0;\n@@ -1072,30 +1076,31 @@ static void setup_git_env_internal(const char *git_dir,\n \n void setup_git_env(const char *git_dir)\n {\n-\tsetup_git_env_internal(git_dir, false);\n+\tsetup_git_env_internal(the_repository, git_dir, false);\n }\n \n-static void set_git_dir_1(const char *path, bool skip_initializing_odb)\n+static void set_git_dir_1(struct repository *repo, const char *path, bool skip_initializing_odb)\n {\n \txsetenv(GIT_DIR_ENVIRONMENT, path, 1);\n-\tsetup_git_env_internal(path, skip_initializing_odb);\n+\tsetup_git_env_internal(repo, path, skip_initializing_odb);\n }\n \n static void update_relative_gitdir(const char *name UNUSED,\n \t\t\t\t   const char *old_cwd,\n \t\t\t\t   const char *new_cwd,\n-\t\t\t\t   void *data UNUSED)\n+\t\t\t\t   void *data)\n {\n+\tstruct repository *repo = data;\n \tchar *path = reparent_relative_path(old_cwd, new_cwd,\n-\t\t\t\t\t    repo_get_git_dir(the_repository));\n+\t\t\t\t\t    repo_get_git_dir(repo));\n \ttrace_printf_key(&trace_setup_key,\n \t\t\t \"setup: move $GIT_DIR to '%s'\",\n \t\t\t path);\n-\tset_git_dir_1(path, true);\n+\tset_git_dir_1(repo, path, true);\n \tfree(path);\n }\n \n-static void set_git_dir(const char *path, int make_realpath)\n+static void set_git_dir(struct repository *repo, const char *path, int make_realpath)\n {\n \tstruct strbuf realpath = STRBUF_INIT;\n \n@@ -1104,14 +1109,15 @@ static void set_git_dir(const char *path, int make_realpath)\n \t\tpath = realpath.buf;\n \t}\n \n-\tset_git_dir_1(path, false);\n+\tset_git_dir_1(repo, path, false);\n \tif (!is_absolute_path(path))\n-\t\tchdir_notify_register(NULL, update_relative_gitdir, NULL);\n+\t\tchdir_notify_register(NULL, update_relative_gitdir, repo);\n \n \tstrbuf_release(&realpath);\n }\n \n-static const char *setup_explicit_git_dir(const char *gitdirenv,\n+static const char *setup_explicit_git_dir(struct repository *repo,\n+\t\t\t\t\t  const char *gitdirenv,\n \t\t\t\t\t  struct strbuf *cwd,\n \t\t\t\t\t  struct repository_format *repo_fmt,\n \t\t\t\t\t  int *nongit_ok)\n@@ -1139,7 +1145,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t\tdie(_(\"not a git repository: '%s'\"), gitdirenv);\n \t}\n \n-\tif (check_repository_format_gently(gitdirenv, repo_fmt, nongit_ok)) {\n+\tif (check_repository_format_gently(repo, gitdirenv, repo_fmt, nongit_ok)) {\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n@@ -1155,7 +1161,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t\t}\n \n \t\t/* #18, #26 */\n-\t\tset_git_dir(gitdirenv, 0);\n+\t\tset_git_dir(repo, gitdirenv, 0);\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n@@ -1177,7 +1183,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t}\n \telse if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) {\n \t\t/* #16d */\n-\t\tset_git_dir(gitdirenv, 0);\n+\t\tset_git_dir(repo, gitdirenv, 0);\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n@@ -1185,18 +1191,18 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t\tset_git_work_tree(\".\");\n \n \t/* set_git_work_tree() must have been called by now */\n-\tworktree = repo_get_work_tree(the_repository);\n+\tworktree = repo_get_work_tree(repo);\n \n \t/* both repo_get_work_tree() and cwd are already normalized */\n \tif (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */\n-\t\tset_git_dir(gitdirenv, 0);\n+\t\tset_git_dir(repo, gitdirenv, 0);\n \t\tfree(gitfile);\n \t\treturn NULL;\n \t}\n \n \toffset = dir_inside_of(cwd->buf, worktree);\n \tif (offset >= 0) {\t/* cwd inside worktree? */\n-\t\tset_git_dir(gitdirenv, 1);\n+\t\tset_git_dir(repo, gitdirenv, 1);\n \t\tif (chdir(worktree))\n \t\t\tdie_errno(_(\"cannot chdir to '%s'\"), worktree);\n \t\tstrbuf_addch(cwd, '/');\n@@ -1205,17 +1211,18 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t}\n \n \t/* cwd outside worktree */\n-\tset_git_dir(gitdirenv, 0);\n+\tset_git_dir(repo, gitdirenv, 0);\n \tfree(gitfile);\n \treturn NULL;\n }\n \n-static const char *setup_discovered_git_dir(const char *gitdir,\n+static const char *setup_discovered_git_dir(struct repository *repo,\n+\t\t\t\t\t    const char *gitdir,\n \t\t\t\t\t    struct strbuf *cwd, int offset,\n \t\t\t\t\t    struct repository_format *repo_fmt,\n \t\t\t\t\t    int *nongit_ok)\n {\n-\tif (check_repository_format_gently(gitdir, repo_fmt, nongit_ok))\n+\tif (check_repository_format_gently(repo, gitdir, repo_fmt, nongit_ok))\n \t\treturn NULL;\n \n \t/* --work-tree is set without --git-dir; use discovered one */\n@@ -1227,14 +1234,14 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n \t\t\tgitdir = to_free = real_pathdup(gitdir, 1);\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n-\t\tret = setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);\n+\t\tret = setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n \t\tfree(to_free);\n \t\treturn ret;\n \t}\n \n \t/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */\n \tif (is_bare_repository_cfg > 0) {\n-\t\tset_git_dir(gitdir, (offset != cwd->len));\n+\t\tset_git_dir(repo, gitdir, (offset != cwd->len));\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n \t\treturn NULL;\n@@ -1243,7 +1250,7 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n \t/* #0, #1, #5, #8, #9, #12, #13 */\n \tset_git_work_tree(\".\");\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n-\t\tset_git_dir(gitdir, 0);\n+\t\tset_git_dir(repo, gitdir, 0);\n \tinside_git_dir = 0;\n \tinside_work_tree = 1;\n \tif (offset >= cwd->len)\n@@ -1258,13 +1265,14 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n }\n \n /* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */\n-static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n+static const char *setup_bare_git_dir(struct repository *repo,\n+\t\t\t\t      struct strbuf *cwd, int offset,\n \t\t\t\t      struct repository_format *repo_fmt,\n \t\t\t\t      int *nongit_ok)\n {\n \tint root_len;\n \n-\tif (check_repository_format_gently(\".\", repo_fmt, nongit_ok))\n+\tif (check_repository_format_gently(repo, \".\", repo_fmt, nongit_ok))\n \t\treturn NULL;\n \n \tsetenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, \"0\", 1);\n@@ -1276,7 +1284,7 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n \t\tgitdir = offset == cwd->len ? \".\" : xmemdupz(cwd->buf, offset);\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n-\t\treturn setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);\n+\t\treturn setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n \t}\n \n \tinside_git_dir = 1;\n@@ -1286,10 +1294,10 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\n \t\troot_len = offset_1st_component(cwd->buf);\n \t\tstrbuf_setlen(cwd, offset > root_len ? offset : root_len);\n-\t\tset_git_dir(cwd->buf, 0);\n+\t\tset_git_dir(repo, cwd->buf, 0);\n \t}\n \telse\n-\t\tset_git_dir(\".\", 0);\n+\t\tset_git_dir(repo, \".\", 0);\n \treturn NULL;\n }\n \n@@ -1827,7 +1835,7 @@ const char *enter_repo(const char *path, unsigned flags)\n \t}\n \n \tif (is_git_directory(\".\")) {\n-\t\tset_git_dir(\".\", 0);\n+\t\tset_git_dir(the_repository, \".\", 0);\n \t\tcheck_repository_format(NULL);\n \t\treturn path;\n \t}\n@@ -1891,18 +1899,18 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \n \tswitch (setup_git_directory_gently_1(&dir, &gitdir, &report, 1)) {\n \tcase GIT_DIR_EXPLICIT:\n-\t\tprefix = setup_explicit_git_dir(gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_explicit_git_dir(the_repository, gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_DISCOVERED:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_discovered_git_dir(gitdir.buf, &cwd, dir.len,\n+\t\tprefix = setup_discovered_git_dir(the_repository, gitdir.buf, &cwd, dir.len,\n \t\t\t\t\t\t  &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_BARE:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_bare_git_dir(&cwd, dir.len, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_bare_git_dir(the_repository, &cwd, dir.len, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_HIT_CEILING:\n \t\tif (!nongit_ok)\n@@ -2044,7 +2052,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\tfree(payload);\n \t}\n \n-\tsetup_original_cwd();\n+\tsetup_original_cwd(the_repository);\n \n \tstrbuf_release(&dir);\n \tstrbuf_release(&gitdir);\n@@ -2110,7 +2118,7 @@ void check_repository_format(struct repository_format *fmt)\n \tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n \tif (!fmt)\n \t\tfmt = &repo_fmt;\n-\tcheck_repository_format_gently(repo_get_git_dir(the_repository), fmt, NULL);\n+\tcheck_repository_format_gently(the_repository, repo_get_git_dir(the_repository), fmt, NULL);\n \tstartup_info->have_repository = 1;\n \trepo_set_hash_algo(the_repository, fmt->hash_algo);\n \trepo_set_compat_hash_algo(the_repository, fmt->compat_hash_algo);\n@@ -2239,7 +2247,9 @@ const char *get_template_dir(const char *option_template)\n \n #define GIT_DEFAULT_HASH_ENVIRONMENT \"GIT_DEFAULT_HASH\"\n \n-static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n+static void copy_templates_1(struct repository *repo,\n+\t\t\t     struct strbuf *path,\n+\t\t\t     struct strbuf *template_path,\n \t\t\t     DIR *dir)\n {\n \tsize_t path_baselen = path->len;\n@@ -2253,7 +2263,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n \t * with the way the namespace under .git/ is organized, should\n \t * be really carefully chosen.\n \t */\n-\tsafe_create_dir(the_repository, path->buf, 1);\n+\tsafe_create_dir(repo, path->buf, 1);\n \twhile ((de = readdir(dir)) != NULL) {\n \t\tstruct stat st_git, st_template;\n \t\tint exists = 0;\n@@ -2281,7 +2291,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n \t\t\t\tdie_errno(_(\"cannot opendir '%s'\"), template_path->buf);\n \t\t\tstrbuf_addch(path, '/');\n \t\t\tstrbuf_addch(template_path, '/');\n-\t\t\tcopy_templates_1(path, template_path, subdir);\n+\t\t\tcopy_templates_1(repo, path, template_path, subdir);\n \t\t\tclosedir(subdir);\n \t\t}\n \t\telse if (exists)\n@@ -2306,7 +2316,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,\n \t}\n }\n \n-static void copy_templates(const char *option_template)\n+static void copy_templates(struct repository *repo, const char *option_template)\n {\n \tconst char *template_dir = get_template_dir(option_template);\n \tstruct strbuf path = STRBUF_INIT;\n@@ -2347,9 +2357,9 @@ static void copy_templates(const char *option_template)\n \t\tgoto close_free_return;\n \t}\n \n-\tstrbuf_addstr(&path, repo_get_common_dir(the_repository));\n+\tstrbuf_addstr(&path, repo_get_common_dir(repo));\n \tstrbuf_complete(&path, '/');\n-\tcopy_templates_1(&path, &template_path, dir);\n+\tcopy_templates_1(repo, &path, &template_path, dir);\n close_free_return:\n \tclosedir(dir);\n free_return:\n@@ -2443,13 +2453,13 @@ void initialize_repository_version(int hash_algo,\n \tstrbuf_release(&repo_version);\n }\n \n-static int is_reinit(void)\n+static int is_reinit(struct repository *repo)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tchar junk[2];\n \tint ret;\n \n-\trepo_git_path_replace(the_repository, &buf, \"HEAD\");\n+\trepo_git_path_replace(repo, &buf, \"HEAD\");\n \tret = !access(buf.buf, R_OK) || readlink(buf.buf, junk, sizeof(junk) - 1) != -1;\n \tstrbuf_release(&buf);\n \treturn ret;\n@@ -2459,7 +2469,7 @@ void create_reference_database(const char *initial_branch, int quiet)\n {\n \tstruct strbuf err = STRBUF_INIT;\n \tchar *to_free = NULL;\n-\tint reinit = is_reinit();\n+\tint reinit = is_reinit(the_repository);\n \n \tif (ref_store_create_on_disk(get_main_ref_store(the_repository), 0, &err))\n \t\tdie(\"failed to set up refs db: %s\", err.buf);\n@@ -2493,7 +2503,8 @@ void create_reference_database(const char *initial_branch, int quiet)\n \tfree(to_free);\n }\n \n-static int create_default_files(const char *template_path,\n+static int create_default_files(struct repository *repo,\n+\t\t\t\tconst char *template_path,\n \t\t\t\tconst char *original_git_dir,\n \t\t\t\tconst struct repository_format *fmt,\n \t\t\t\tint init_shared_repository)\n@@ -2502,7 +2513,7 @@ static int create_default_files(const char *template_path,\n \tstruct strbuf path = STRBUF_INIT;\n \tint reinit;\n \tint filemode;\n-\tconst char *work_tree = repo_get_work_tree(the_repository);\n+\tconst char *work_tree = repo_get_work_tree(repo);\n \n \t/*\n \t * First copy the templates -- we might have the default\n@@ -2513,19 +2524,19 @@ static int create_default_files(const char *template_path,\n \t * values (since we've just potentially changed what's available on\n \t * disk).\n \t */\n-\tcopy_templates(template_path);\n-\trepo_config_clear(the_repository);\n-\trepo_settings_reset_shared_repository(the_repository);\n-\trepo_config(the_repository, git_default_config, NULL);\n+\tcopy_templates(repo, template_path);\n+\trepo_config_clear(repo);\n+\trepo_settings_reset_shared_repository(repo);\n+\trepo_config(repo, git_default_config, NULL);\n \n-\treinit = is_reinit();\n+\treinit = is_reinit(repo);\n \n \t/*\n \t * We must make sure command-line options continue to override any\n \t * values we might have just re-read from the config.\n \t */\n \tif (init_shared_repository != -1)\n-\t\trepo_settings_set_shared_repository(the_repository,\n+\t\trepo_settings_set_shared_repository(repo,\n \t\t\t\t\t\t    init_shared_repository);\n \n \tis_bare_repository_cfg = !work_tree;\n@@ -2534,14 +2545,14 @@ static int create_default_files(const char *template_path,\n \t * We would have created the above under user's umask -- under\n \t * shared-repository settings, we would need to fix them up.\n \t */\n-\tif (repo_settings_get_shared_repository(the_repository)) {\n-\t\tadjust_shared_perm(the_repository, repo_get_git_dir(the_repository));\n+\tif (repo_settings_get_shared_repository(repo)) {\n+\t\tadjust_shared_perm(repo, repo_get_git_dir(repo));\n \t}\n \n \tinitialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, reinit);\n \n \t/* Check filemode trustability */\n-\trepo_git_path_replace(the_repository, &path, \"config\");\n+\trepo_git_path_replace(repo, &path, \"config\");\n \tfilemode = TEST_FILEMODE;\n \tif (TEST_FILEMODE && !lstat(path.buf, &st1)) {\n \t\tstruct stat st2;\n@@ -2552,22 +2563,22 @@ static int create_default_files(const char *template_path,\n \t\tif (filemode && !reinit && (st1.st_mode & S_IXUSR))\n \t\t\tfilemode = 0;\n \t}\n-\trepo_config_set(the_repository, \"core.filemode\", filemode ? \"true\" : \"false\");\n+\trepo_config_set(repo, \"core.filemode\", filemode ? \"true\" : \"false\");\n \n \tif (is_bare_repository())\n-\t\trepo_config_set(the_repository, \"core.bare\", \"true\");\n+\t\trepo_config_set(repo, \"core.bare\", \"true\");\n \telse {\n-\t\trepo_config_set(the_repository, \"core.bare\", \"false\");\n+\t\trepo_config_set(repo, \"core.bare\", \"false\");\n \t\t/* allow template config file to override the default */\n-\t\tif (repo_settings_get_log_all_ref_updates(the_repository) == LOG_REFS_UNSET)\n-\t\t\trepo_config_set(the_repository, \"core.logallrefupdates\", \"true\");\n+\t\tif (repo_settings_get_log_all_ref_updates(repo) == LOG_REFS_UNSET)\n+\t\t\trepo_config_set(repo, \"core.logallrefupdates\", \"true\");\n \t\tif (needs_work_tree_config(original_git_dir, work_tree))\n-\t\t\trepo_config_set(the_repository, \"core.worktree\", work_tree);\n+\t\t\trepo_config_set(repo, \"core.worktree\", work_tree);\n \t}\n \n \tif (!reinit) {\n \t\t/* Check if symlink is supported in the work tree */\n-\t\trepo_git_path_replace(the_repository, &path, \"tXXXXXX\");\n+\t\trepo_git_path_replace(repo, &path, \"tXXXXXX\");\n \t\tif (!close(xmkstemp(path.buf)) &&\n \t\t    !unlink(path.buf) &&\n \t\t    !symlink(\"testing\", path.buf) &&\n@@ -2575,12 +2586,12 @@ static int create_default_files(const char *template_path,\n \t\t    S_ISLNK(st1.st_mode))\n \t\t\tunlink(path.buf); /* good */\n \t\telse\n-\t\t\trepo_config_set(the_repository, \"core.symlinks\", \"false\");\n+\t\t\trepo_config_set(repo, \"core.symlinks\", \"false\");\n \n \t\t/* Check if the filesystem is case-insensitive */\n-\t\trepo_git_path_replace(the_repository, &path, \"CoNfIg\");\n+\t\trepo_git_path_replace(repo, &path, \"CoNfIg\");\n \t\tif (!access(path.buf, F_OK))\n-\t\t\trepo_config_set(the_repository, \"core.ignorecase\", \"true\");\n+\t\t\trepo_config_set(repo, \"core.ignorecase\", \"true\");\n \t\tprobe_utf8_pathname_composition();\n \t}\n \n@@ -2588,23 +2599,23 @@ static int create_default_files(const char *template_path,\n \treturn reinit;\n }\n \n-static void create_object_directory(void)\n+static void create_object_directory(struct repository *repo)\n {\n \tstruct strbuf path = STRBUF_INIT;\n \tsize_t baselen;\n \n-\tstrbuf_addstr(&path, repo_get_object_directory(the_repository));\n+\tstrbuf_addstr(&path, repo_get_object_directory(repo));\n \tbaselen = path.len;\n \n-\tsafe_create_dir(the_repository, path.buf, 1);\n+\tsafe_create_dir(repo, path.buf, 1);\n \n \tstrbuf_setlen(&path, baselen);\n \tstrbuf_addstr(&path, \"/pack\");\n-\tsafe_create_dir(the_repository, path.buf, 1);\n+\tsafe_create_dir(repo, path.buf, 1);\n \n \tstrbuf_setlen(&path, baselen);\n \tstrbuf_addstr(&path, \"/info\");\n-\tsafe_create_dir(the_repository, path.buf, 1);\n+\tsafe_create_dir(repo, path.buf, 1);\n \n \tstrbuf_release(&path);\n }\n@@ -2682,7 +2693,8 @@ static int read_default_format_config(const char *key, const char *value,\n \treturn ret;\n }\n \n-static void repository_format_configure(struct repository_format *repo_fmt,\n+static void repository_format_configure(struct repository *repo,\n+\t\t\t\t\tstruct repository_format *repo_fmt,\n \t\t\t\t\tint hash, enum ref_storage_format ref_format)\n {\n \tstruct default_format_config cfg = {\n@@ -2719,7 +2731,7 @@ static void repository_format_configure(struct repository_format *repo_fmt,\n \t} else if (cfg.hash != GIT_HASH_UNKNOWN) {\n \t\trepo_fmt->hash_algo = cfg.hash;\n \t}\n-\trepo_set_hash_algo(the_repository, repo_fmt->hash_algo);\n+\trepo_set_hash_algo(repo, repo_fmt->hash_algo);\n \n \tenv = getenv(\"GIT_DEFAULT_REF_FORMAT\");\n \tif (repo_fmt->version >= 0 &&\n@@ -2758,7 +2770,7 @@ static void repository_format_configure(struct repository_format *repo_fmt,\n \t\tfree(backend);\n \t}\n \n-\trepo_set_ref_storage_format(the_repository, repo_fmt->ref_storage_format,\n+\trepo_set_ref_storage_format(repo, repo_fmt->ref_storage_format,\n \t\t\t\t    repo_fmt->ref_storage_payload);\n }\n \n@@ -2782,12 +2794,12 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\tif (!exist_ok && !stat(real_git_dir, &st))\n \t\t\tdie(_(\"%s already exists\"), real_git_dir);\n \n-\t\tset_git_dir(real_git_dir, 1);\n+\t\tset_git_dir(the_repository, real_git_dir, 1);\n \t\tgit_dir = repo_get_git_dir(the_repository);\n \t\tseparate_git_dir(git_dir, original_git_dir);\n \t}\n \telse {\n-\t\tset_git_dir(git_dir, 1);\n+\t\tset_git_dir(the_repository, git_dir, 1);\n \t\tgit_dir = repo_get_git_dir(the_repository);\n \t}\n \tstartup_info->have_repository = 1;\n@@ -2800,7 +2812,7 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t */\n \tcheck_repository_format(&repo_fmt);\n \n-\trepository_format_configure(&repo_fmt, hash, ref_storage_format);\n+\trepository_format_configure(the_repository, &repo_fmt, hash, ref_storage_format);\n \n \t/*\n \t * Ensure `core.hidedotfiles` is processed. This must happen after we\n@@ -2811,12 +2823,12 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \n \tsafe_create_dir(the_repository, git_dir, 0);\n \n-\treinit = create_default_files(template_dir, original_git_dir,\n+\treinit = create_default_files(the_repository, template_dir, original_git_dir,\n \t\t\t\t      &repo_fmt, init_shared_repository);\n \n \tif (!(flags & INIT_DB_SKIP_REFDB))\n \t\tcreate_reference_database(initial_branch, flags & INIT_DB_QUIET);\n-\tcreate_object_directory();\n+\tcreate_object_directory(the_repository);\n \n \tif (repo_settings_get_shared_repository(the_repository)) {\n \t\tchar buf[10];\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543618","messageId":"20260519-pks-setup-wo-the-repository-v3-2-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 02/18] setup: stop using `the_repository` in `is_inside_git_dir()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:06Z","receivedAt":"2026-05-19T09:52:19Z","isPatch":true,"body":"The function `is_inside_git_dir()` verifies whether or not the current\nworking directory is located inside the gitdir of `the_repository`. This\nis done by taking the gitdir path and verifying that it's a prefix of\nthe current working directory.\n\nThis information is cached so that we don't have to re-do this change\nmultiple times. Furthermore, we proactively set the value in multiple\nlocations so that we don't even have to perform the check when we have\ndiscovered the repository.\n\nWhile we could simply move the caching variable into the repository, the\ncurrent layout doesn't really feel sensible in the first place:\n\n  - It can easily lead to false positives or negatives if at any point\n    in time we may switch the current working directory.\n\n  - We don't call the function in a hot loop, and neither is it overly\n    expensive to compute.\n\nDrop the caching infrastructure and instead compute the property ad-hoc\nvia an injected repository.\n\nNote that there is one small gotcha: we often end up with relative\ngitdir paths, and if so `is_inside_dir()` might fail. This wasn't an\nissue before because of how we proactively set the cached value during\nrepository discovery. Now that we stop doing that it becomes a problem\nthough, which we work around by resolving the gitdir via `realpath()`.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/rev-parse.c |  2 +-\n setup.c             | 14 ++++++--------\n setup.h             |  2 +-\n 3 files changed, 8 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 218b5f34d6..a216be63cf 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -1063,7 +1063,7 @@ int cmd_rev_parse(int argc,\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--is-inside-git-dir\")) {\n-\t\t\t\tprintf(\"%s\\n\", is_inside_git_dir() ? \"true\"\n+\t\t\t\tprintf(\"%s\\n\", is_inside_git_dir(the_repository) ? \"true\"\n \t\t\t\t\t\t: \"false\");\n \t\t\t\tcontinue;\n \t\t\t}\ndiff --git a/setup.c b/setup.c\nindex ba2898473a..80f3ba0d62 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -26,7 +26,6 @@\n #include \"trace2.h\"\n #include \"worktree.h\"\n \n-static int inside_git_dir = -1;\n static int inside_work_tree = -1;\n static int work_tree_config_is_bogus;\n enum allowed_bare_repo {\n@@ -299,7 +298,7 @@ void verify_filename(const char *prefix,\n  */\n void verify_non_filename(const char *prefix, const char *arg)\n {\n-\tif (!is_inside_work_tree() || is_inside_git_dir())\n+\tif (!is_inside_work_tree() || is_inside_git_dir(the_repository))\n \t\treturn;\n \tif (*arg == '-')\n \t\treturn; /* flag */\n@@ -470,11 +469,12 @@ int is_nonbare_repository_dir(struct strbuf *path)\n \treturn ret;\n }\n \n-int is_inside_git_dir(void)\n+int is_inside_git_dir(struct repository *repo)\n {\n-\tif (inside_git_dir < 0)\n-\t\tinside_git_dir = is_inside_dir(repo_get_git_dir(the_repository));\n-\treturn inside_git_dir;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tint ret = is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));\n+\tstrbuf_release(&buf);\n+\treturn ret;\n }\n \n int is_inside_work_tree(void)\n@@ -1251,7 +1251,6 @@ static const char *setup_discovered_git_dir(struct repository *repo,\n \tset_git_work_tree(\".\");\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n \t\tset_git_dir(repo, gitdir, 0);\n-\tinside_git_dir = 0;\n \tinside_work_tree = 1;\n \tif (offset >= cwd->len)\n \t\treturn NULL;\n@@ -1287,7 +1286,6 @@ static const char *setup_bare_git_dir(struct repository *repo,\n \t\treturn setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n \t}\n \n-\tinside_git_dir = 1;\n \tinside_work_tree = 0;\n \tif (offset != cwd->len) {\n \t\tif (chdir(cwd->buf))\ndiff --git a/setup.h b/setup.h\nindex 80bc6e5f07..115bda647c 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -4,7 +4,7 @@\n #include \"refs.h\"\n #include \"string-list.h\"\n \n-int is_inside_git_dir(void);\n+int is_inside_git_dir(struct repository *repo);\n int is_inside_work_tree(void);\n int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);\n int get_common_dir(struct strbuf *sb, const char *gitdir);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543619","messageId":"20260519-pks-setup-wo-the-repository-v3-3-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 03/18] setup: stop using `the_repository` in `is_inside_work_tree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:07Z","receivedAt":"2026-05-19T09:52:22Z","isPatch":true,"body":"Similar as with the preceding commit, `is_inside_work_tree()` determines\nwhether the current working directory is located inside the worktree of\n`the_repository`. Perform the same refactoring by dropping the caching\nmechanism and injecting the repository that shall be checked.\n\nNote that, same as in the preceding commit, we're also resolving the\nworktree path via `realpath()`. In theory this step is not necessary as\nwe always set the worktree path via `repo_set_worktree()`, and that\nfunction already resolves the path for us. But resolving the path a\nsecond time is unlikely to matter performance-wise, and it feels fragile\nto rely on the repository's worktree path being absolute. We thus\nperform the same extra step even though it's ultimately not required.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/ls-files.c  |  2 +-\n builtin/rev-parse.c |  4 ++--\n object-name.c       |  2 +-\n setup.c             | 25 ++++++++++++++-----------\n setup.h             |  2 +-\n submodule.c         |  2 +-\n 6 files changed, 20 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex b148607f7a..09d95111b3 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -703,7 +703,7 @@ int cmd_ls_files(int argc,\n \tif (dir.exclude_per_dir)\n \t\texc_given = 1;\n \n-\tif (require_work_tree && !is_inside_work_tree())\n+\tif (require_work_tree && !is_inside_work_tree(repo))\n \t\tsetup_work_tree();\n \n \tif (recurse_submodules &&\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex a216be63cf..2fcd6851d1 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -1006,7 +1006,7 @@ int cmd_rev_parse(int argc,\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--show-cdup\")) {\n \t\t\t\tconst char *pfx = prefix;\n-\t\t\t\tif (!is_inside_work_tree()) {\n+\t\t\t\tif (!is_inside_work_tree(the_repository)) {\n \t\t\t\t\tconst char *work_tree =\n \t\t\t\t\t\trepo_get_work_tree(the_repository);\n \t\t\t\t\tif (work_tree)\n@@ -1068,7 +1068,7 @@ int cmd_rev_parse(int argc,\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--is-inside-work-tree\")) {\n-\t\t\t\tprintf(\"%s\\n\", is_inside_work_tree() ? \"true\"\n+\t\t\t\tprintf(\"%s\\n\", is_inside_work_tree(the_repository) ? \"true\"\n \t\t\t\t\t\t: \"false\");\n \t\t\t\tcontinue;\n \t\t\t}\ndiff --git a/object-name.c b/object-name.c\nindex 21dcdc4a0e..37a9ce8e87 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -1703,7 +1703,7 @@ static char *resolve_relative_path(struct repository *r, const char *rel)\n \tif (!starts_with(rel, \"./\") && !starts_with(rel, \"../\"))\n \t\treturn NULL;\n \n-\tif (r != the_repository || !is_inside_work_tree())\n+\tif (r != the_repository || !is_inside_work_tree(the_repository))\n \t\tdie(_(\"relative path syntax can't be used outside working tree\"));\n \n \t/* die() inside prefix_path() if resolved path is outside worktree */\ndiff --git a/setup.c b/setup.c\nindex 80f3ba0d62..041e08b98d 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -26,7 +26,6 @@\n #include \"trace2.h\"\n #include \"worktree.h\"\n \n-static int inside_work_tree = -1;\n static int work_tree_config_is_bogus;\n enum allowed_bare_repo {\n \tALLOWED_BARE_REPO_EXPLICIT = 0,\n@@ -298,7 +297,7 @@ void verify_filename(const char *prefix,\n  */\n void verify_non_filename(const char *prefix, const char *arg)\n {\n-\tif (!is_inside_work_tree() || is_inside_git_dir(the_repository))\n+\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir(the_repository))\n \t\treturn;\n \tif (*arg == '-')\n \t\treturn; /* flag */\n@@ -477,11 +476,20 @@ int is_inside_git_dir(struct repository *repo)\n \treturn ret;\n }\n \n-int is_inside_work_tree(void)\n+int is_inside_work_tree(struct repository *repo)\n {\n-\tif (inside_work_tree < 0)\n-\t\tinside_work_tree = is_inside_dir(repo_get_work_tree(the_repository));\n-\treturn inside_work_tree;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tconst char *worktree;\n+\tint ret;\n+\n+\tworktree = repo_get_work_tree(repo);\n+\tif (!worktree)\n+\t\treturn 0;\n+\n+\tret = is_inside_dir(strbuf_realpath(&buf, worktree, 1));\n+\n+\tstrbuf_release(&buf);\n+\treturn ret;\n }\n \n void setup_work_tree(void)\n@@ -798,13 +806,10 @@ static int check_repository_format_gently(struct repository *repo,\n \tif (!has_common) {\n \t\tif (candidate->is_bare != -1) {\n \t\t\tis_bare_repository_cfg = candidate->is_bare;\n-\t\t\tif (is_bare_repository_cfg == 1)\n-\t\t\t\tinside_work_tree = -1;\n \t\t}\n \t\tif (candidate->work_tree) {\n \t\t\tfree(git_work_tree_cfg);\n \t\t\tgit_work_tree_cfg = xstrdup(candidate->work_tree);\n-\t\t\tinside_work_tree = -1;\n \t\t}\n \t}\n \n@@ -1251,7 +1256,6 @@ static const char *setup_discovered_git_dir(struct repository *repo,\n \tset_git_work_tree(\".\");\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n \t\tset_git_dir(repo, gitdir, 0);\n-\tinside_work_tree = 1;\n \tif (offset >= cwd->len)\n \t\treturn NULL;\n \n@@ -1286,7 +1290,6 @@ static const char *setup_bare_git_dir(struct repository *repo,\n \t\treturn setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);\n \t}\n \n-\tinside_work_tree = 0;\n \tif (offset != cwd->len) {\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(_(\"cannot come back to cwd\"));\ndiff --git a/setup.h b/setup.h\nindex 115bda647c..71d3f91883 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -5,7 +5,7 @@\n #include \"string-list.h\"\n \n int is_inside_git_dir(struct repository *repo);\n-int is_inside_work_tree(void);\n+int is_inside_work_tree(struct repository *repo);\n int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);\n int get_common_dir(struct strbuf *sb, const char *gitdir);\n \ndiff --git a/submodule.c b/submodule.c\nindex b1a0363f9d..a939ff5072 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -2620,7 +2620,7 @@ int get_superproject_working_tree(struct strbuf *buf)\n \tint code;\n \tssize_t len;\n \n-\tif (!is_inside_work_tree())\n+\tif (!is_inside_work_tree(the_repository))\n \t\t/*\n \t\t * FIXME:\n \t\t * We might have a superproject, but it is harder\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543620","messageId":"20260519-pks-setup-wo-the-repository-v3-4-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 04/18] setup: stop using `the_repository` in `prefix_path()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:08Z","receivedAt":"2026-05-19T09:52:25Z","isPatch":true,"body":"Stop using `the_repository` in `prefix_path()` and instead accept the\nrepository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/blame.c            |  2 +-\n builtin/check-attr.c       |  2 +-\n builtin/checkout-index.c   |  4 ++--\n builtin/mv.c               |  5 +++--\n builtin/sparse-checkout.c  |  3 ++-\n builtin/update-index.c     |  6 +++---\n line-log.c                 |  2 +-\n object-name.c              |  2 +-\n pathspec.c                 |  2 +-\n setup.c                    | 15 ++++++++-------\n setup.h                    |  4 ++--\n t/helper/test-path-utils.c |  2 +-\n 12 files changed, 26 insertions(+), 23 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex f3a11eff44..ffbd3ce5c5 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -708,7 +708,7 @@ static unsigned parse_score(const char *arg)\n \n static char *add_prefix(const char *prefix, const char *path)\n {\n-\treturn prefix_path(prefix, prefix ? strlen(prefix) : 0, path);\n+\treturn prefix_path(the_repository, prefix, prefix ? strlen(prefix) : 0, path);\n }\n \n static int git_blame_config(const char *var, const char *value,\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 51ed48ce43..04b86e42ae 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -67,7 +67,7 @@ static void check_attr(const char *prefix, struct attr_check *check,\n \n {\n \tchar *full_path =\n-\t\tprefix_path(prefix, prefix ? strlen(prefix) : 0, file);\n+\t\tprefix_path(the_repository, prefix, prefix ? strlen(prefix) : 0, file);\n \n \tif (collect_all) {\n \t\tgit_all_attrs(the_repository->index, full_path, check);\ndiff --git a/builtin/checkout-index.c b/builtin/checkout-index.c\nindex 188128aebd..311b94ff31 100644\n--- a/builtin/checkout-index.c\n+++ b/builtin/checkout-index.c\n@@ -303,7 +303,7 @@ int cmd_checkout_index(int argc,\n \t\t\tdie(\"git checkout-index: don't mix '--all' and explicit filenames\");\n \t\tif (read_from_stdin)\n \t\t\tdie(\"git checkout-index: don't mix '--stdin' and explicit filenames\");\n-\t\tp = prefix_path(prefix, prefix_length, arg);\n+\t\tp = prefix_path(repo, prefix, prefix_length, arg);\n \t\terr |= checkout_file(repo->index, p, prefix);\n \t\tfree(p);\n \t}\n@@ -325,7 +325,7 @@ int cmd_checkout_index(int argc,\n \t\t\t\t\tdie(\"line is badly quoted\");\n \t\t\t\tstrbuf_swap(&buf, &unquoted);\n \t\t\t}\n-\t\t\tp = prefix_path(prefix, prefix_length, buf.buf);\n+\t\t\tp = prefix_path(repo, prefix, prefix_length, buf.buf);\n \t\t\terr |= checkout_file(repo->index, p, prefix);\n \t\t\tfree(p);\n \t\t}\ndiff --git a/builtin/mv.c b/builtin/mv.c\nindex 2215d34e31..948b330639 100644\n--- a/builtin/mv.c\n+++ b/builtin/mv.c\n@@ -71,7 +71,7 @@ static void internal_prefix_pathspec(struct strvec *out,\n \n \t\ttrimmed = xmemdupz(pathspec[i], to_copy);\n \t\tmaybe_basename = (flags & DUP_BASENAME) ? basename(trimmed) : trimmed;\n-\t\tprefixed_path = prefix_path(prefix, prefixlen, maybe_basename);\n+\t\tprefixed_path = prefix_path(the_repository, prefix, prefixlen, maybe_basename);\n \t\tstrvec_push(out, prefixed_path);\n \n \t\tfree(prefixed_path);\n@@ -394,7 +394,8 @@ int cmd_mv(int argc,\n \t\t\tfor (j = 0; j < last - first; j++) {\n \t\t\t\tconst struct cache_entry *ce = the_repository->index->cache[first + j];\n \t\t\t\tconst char *path = ce->name;\n-\t\t\t\tchar *prefixed_path = prefix_path(dst_with_slash, dst_with_slash_len, path + length + 1);\n+\t\t\t\tchar *prefixed_path = prefix_path(the_repository, dst_with_slash,\n+\t\t\t\t\t\t\t\t  dst_with_slash_len, path + length + 1);\n \n \t\t\t\tstrvec_push(&sources, path);\n \t\t\t\tstrvec_push(&destinations, prefixed_path);\ndiff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c\nindex f4aa405da9..2af50fb2f9 100644\n--- a/builtin/sparse-checkout.c\n+++ b/builtin/sparse-checkout.c\n@@ -735,7 +735,8 @@ static void sanitize_paths(struct repository *repo,\n \t\tint prefix_len = strlen(prefix);\n \n \t\tfor (i = 0; i < args->nr; i++) {\n-\t\t\tchar *prefixed_path = prefix_path(prefix, prefix_len, args->v[i]);\n+\t\t\tchar *prefixed_path = prefix_path(the_repository, prefix,\n+\t\t\t\t\t\t\t  prefix_len, args->v[i]);\n \t\t\tstrvec_replace(args, i, prefixed_path);\n \t\t\tfree(prefixed_path);\n \t\t}\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 8a5907767b..7434112b8e 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -655,7 +655,7 @@ static int do_unresolve(int ac, const char **av,\n \n \tfor (i = 1; i < ac; i++) {\n \t\tconst char *arg = av[i];\n-\t\tchar *p = prefix_path(prefix, prefix_length, arg);\n+\t\tchar *p = prefix_path(the_repository, prefix, prefix_length, arg);\n \t\terr |= unresolve_one(p);\n \t\tfree(p);\n \t}\n@@ -1158,7 +1158,7 @@ int cmd_update_index(int argc,\n \t\t\t}\n \n \t\t\tsetup_work_tree();\n-\t\t\tp = prefix_path(prefix, prefix_length, path);\n+\t\t\tp = prefix_path(the_repository, prefix, prefix_length, path);\n \t\t\tupdate_one(p);\n \t\t\tif (set_executable_bit)\n \t\t\t\tchmod_path(set_executable_bit, p);\n@@ -1208,7 +1208,7 @@ int cmd_update_index(int argc,\n \t\t\t\t\tdie(\"line is badly quoted\");\n \t\t\t\tstrbuf_swap(&buf, &unquoted);\n \t\t\t}\n-\t\t\tp = prefix_path(prefix, prefix_length, buf.buf);\n+\t\t\tp = prefix_path(the_repository, prefix, prefix_length, buf.buf);\n \t\t\tupdate_one(p);\n \t\t\tif (set_executable_bit)\n \t\t\t\tchmod_path(set_executable_bit, p);\ndiff --git a/line-log.c b/line-log.c\nindex 858a899cd2..346c60c554 100644\n--- a/line-log.c\n+++ b/line-log.c\n@@ -589,7 +589,7 @@ parse_lines(struct repository *r, struct commit *commit,\n \t\trange_part = xstrndup(item->string, name_part - item->string);\n \t\tname_part++;\n \n-\t\tfull_name = prefix_path(prefix, prefix ? strlen(prefix) : 0,\n+\t\tfull_name = prefix_path(r, prefix, prefix ? strlen(prefix) : 0,\n \t\t\t\t\tname_part);\n \n \t\tspec = alloc_filespec(full_name);\ndiff --git a/object-name.c b/object-name.c\nindex 37a9ce8e87..9ac86f19c7 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -1707,7 +1707,7 @@ static char *resolve_relative_path(struct repository *r, const char *rel)\n \t\tdie(_(\"relative path syntax can't be used outside working tree\"));\n \n \t/* die() inside prefix_path() if resolved path is outside worktree */\n-\treturn prefix_path(startup_info->prefix,\n+\treturn prefix_path(the_repository, startup_info->prefix,\n \t\t\t   startup_info->prefix ? strlen(startup_info->prefix) : 0,\n \t\t\t   rel);\n }\ndiff --git a/pathspec.c b/pathspec.c\nindex 5993c4afa0..f78b22709c 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -486,7 +486,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,\n \t\tmatch = xstrdup(copyfrom);\n \t\tprefixlen = 0;\n \t} else {\n-\t\tmatch = prefix_path_gently(prefix, prefixlen,\n+\t\tmatch = prefix_path_gently(the_repository, prefix, prefixlen,\n \t\t\t\t\t   &prefixlen, copyfrom);\n \t\tif (!match) {\n \t\t\tconst char *hint_path;\ndiff --git a/setup.c b/setup.c\nindex 041e08b98d..adad6ceec0 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -117,7 +117,8 @@ static int abspath_part_inside_repo(struct repository *repo, char *path)\n  *  ../../sub1/sub2/foo -> sub1/sub2/foo (but no remaining prefix)\n  *  `pwd`/../bar -> sub1/bar       (no remaining prefix)\n  */\n-char *prefix_path_gently(const char *prefix, int len,\n+char *prefix_path_gently(struct repository *repo,\n+\t\t\t const char *prefix, int len,\n \t\t\t int *remaining_prefix, const char *path)\n {\n \tconst char *orig = path;\n@@ -130,7 +131,7 @@ char *prefix_path_gently(const char *prefix, int len,\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n-\t\tif (abspath_part_inside_repo(the_repository, sanitized)) {\n+\t\tif (abspath_part_inside_repo(repo, sanitized)) {\n \t\t\tfree(sanitized);\n \t\t\treturn NULL;\n \t\t}\n@@ -146,13 +147,13 @@ char *prefix_path_gently(const char *prefix, int len,\n \treturn sanitized;\n }\n \n-char *prefix_path(const char *prefix, int len, const char *path)\n+char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path)\n {\n-\tchar *r = prefix_path_gently(prefix, len, NULL, path);\n+\tchar *r = prefix_path_gently(repo, prefix, len, NULL, path);\n \tif (!r) {\n-\t\tconst char *hint_path = repo_get_work_tree(the_repository);\n+\t\tconst char *hint_path = repo_get_work_tree(repo);\n \t\tif (!hint_path)\n-\t\t\thint_path = repo_get_git_dir(the_repository);\n+\t\t\thint_path = repo_get_git_dir(repo);\n \t\tdie(_(\"'%s' is outside repository at '%s'\"), path,\n \t\t    absolute_path(hint_path));\n \t}\n@@ -162,7 +163,7 @@ char *prefix_path(const char *prefix, int len, const char *path)\n int path_inside_repo(const char *prefix, const char *path)\n {\n \tint len = prefix ? strlen(prefix) : 0;\n-\tchar *r = prefix_path_gently(prefix, len, NULL, path);\n+\tchar *r = prefix_path_gently(the_repository, prefix, len, NULL, path);\n \tif (r) {\n \t\tfree(r);\n \t\treturn 1;\ndiff --git a/setup.h b/setup.h\nindex 71d3f91883..24034572b1 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -138,8 +138,8 @@ const char *enter_repo(const char *path, unsigned flags);\n \n const char *setup_git_directory_gently(int *);\n const char *setup_git_directory(void);\n-char *prefix_path(const char *prefix, int len, const char *path);\n-char *prefix_path_gently(const char *prefix, int len, int *remaining, const char *path);\n+char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path);\n+char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\n \n int check_filename(const char *prefix, const char *name);\n void verify_filename(const char *prefix,\ndiff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c\nindex 874542ec34..163fdeefb0 100644\n--- a/t/helper/test-path-utils.c\n+++ b/t/helper/test-path-utils.c\n@@ -379,7 +379,7 @@ int cmd__path_utils(int argc, const char **argv)\n \t\tint nongit_ok;\n \t\tsetup_git_directory_gently(&nongit_ok);\n \t\twhile (argc > 3) {\n-\t\t\tchar *pfx = prefix_path(prefix, prefix_len, argv[3]);\n+\t\t\tchar *pfx = prefix_path(the_repository, prefix, prefix_len, argv[3]);\n \n \t\t\tputs(pfx);\n \t\t\tfree(pfx);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543621","messageId":"20260519-pks-setup-wo-the-repository-v3-5-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 05/18] setup: stop using `the_repository` in `path_inside_repo()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:09Z","receivedAt":"2026-05-19T09:52:29Z","isPatch":true,"body":"Stop using `the_repository` in `path_inside_repo()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/diff.c | 4 ++--\n setup.c        | 4 ++--\n setup.h        | 2 +-\n 3 files changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/diff.c b/builtin/diff.c\nindex 0b23c41456..7ddebce2ac 100644\n--- a/builtin/diff.c\n+++ b/builtin/diff.c\n@@ -471,8 +471,8 @@ int cmd_diff(int argc,\n \t\t * as a colourful \"diff\" replacement.\n \t\t */\n \t\tif (nongit || ((argc == i + 2) &&\n-\t\t\t       (!path_inside_repo(prefix, argv[i]) ||\n-\t\t\t\t!path_inside_repo(prefix, argv[i + 1]))))\n+\t\t\t       (!path_inside_repo(the_repository, prefix, argv[i]) ||\n+\t\t\t\t!path_inside_repo(the_repository, prefix, argv[i + 1]))))\n \t\t\tno_index = DIFF_NO_INDEX_IMPLICIT;\n \t}\n \ndiff --git a/setup.c b/setup.c\nindex adad6ceec0..4ef6216e82 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -160,10 +160,10 @@ char *prefix_path(struct repository *repo, const char *prefix, int len, const ch\n \treturn r;\n }\n \n-int path_inside_repo(const char *prefix, const char *path)\n+int path_inside_repo(struct repository *repo, const char *prefix, const char *path)\n {\n \tint len = prefix ? strlen(prefix) : 0;\n-\tchar *r = prefix_path_gently(the_repository, prefix, len, NULL, path);\n+\tchar *r = prefix_path_gently(repo, prefix, len, NULL, path);\n \tif (r) {\n \t\tfree(r);\n \t\treturn 1;\ndiff --git a/setup.h b/setup.h\nindex 24034572b1..c3247d7fc8 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -146,7 +146,7 @@ void verify_filename(const char *prefix,\n \t\t     const char *name,\n \t\t     int diagnose_misspelt_rev);\n void verify_non_filename(const char *prefix, const char *name);\n-int path_inside_repo(const char *prefix, const char *path);\n+int path_inside_repo(struct repository *repo, const char *prefix, const char *path);\n \n void sanitize_stdfds(void);\n int daemonize(void);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543622","messageId":"20260519-pks-setup-wo-the-repository-v3-6-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 06/18] setup: stop using `the_repository` in `verify_filename()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:10Z","receivedAt":"2026-05-19T09:52:30Z","isPatch":true,"body":"Stop using `the_repository` in `verify_filename()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/grep.c      | 2 +-\n builtin/reset.c     | 2 +-\n builtin/rev-parse.c | 4 ++--\n revision.c          | 2 +-\n setup.c             | 5 +++--\n setup.h             | 3 ++-\n 6 files changed, 10 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex e33285e5e6..b0e350cf89 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1163,7 +1163,7 @@ int cmd_grep(int argc,\n \tif (!seen_dashdash) {\n \t\tint j;\n \t\tfor (j = i; j < argc; j++)\n-\t\t\tverify_filename(prefix, argv[j], j == i && allow_revs);\n+\t\t\tverify_filename(the_repository, prefix, argv[j], j == i && allow_revs);\n \t}\n \n \tparse_pathspec(&pathspec, 0,\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex 3590be57a5..1ac374d31b 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -285,7 +285,7 @@ static void parse_args(struct pathspec *pathspec,\n \t\t\trev = *argv++;\n \t\t} else {\n \t\t\t/* Otherwise we treat this as a filename */\n-\t\t\tverify_filename(prefix, argv[0], 1);\n+\t\t\tverify_filename(the_repository, prefix, argv[0], 1);\n \t\t}\n \t}\n \ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 2fcd6851d1..8fdb75413d 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -749,7 +749,7 @@ int cmd_rev_parse(int argc,\n \n \t\tif (as_is) {\n \t\t\tif (show_file(arg, output_prefix) && as_is < 2)\n-\t\t\t\tverify_filename(prefix, arg, 0);\n+\t\t\t\tverify_filename(the_repository, prefix, arg, 0);\n \t\t\tcontinue;\n \t\t}\n \n@@ -1173,7 +1173,7 @@ int cmd_rev_parse(int argc,\n \t\tas_is = 1;\n \t\tif (!show_file(arg, output_prefix))\n \t\t\tcontinue;\n-\t\tverify_filename(prefix, arg, 1);\n+\t\tverify_filename(the_repository, prefix, arg, 1);\n \t}\n \tstrbuf_release(&buf);\n \tif (verify) {\ndiff --git a/revision.c b/revision.c\nindex 599b3a66c3..5d53244379 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -3067,7 +3067,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s\n \t\t\t * but the latter we have checked in the main loop.\n \t\t\t */\n \t\t\tfor (j = i; j < argc; j++)\n-\t\t\t\tverify_filename(revs->prefix, argv[j], j == i);\n+\t\t\t\tverify_filename(the_repository, revs->prefix, argv[j], j == i);\n \n \t\t\tstrvec_pushv(&prune_data, argv + i);\n \t\t\tbreak;\ndiff --git a/setup.c b/setup.c\nindex 4ef6216e82..e673663cab 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -280,7 +280,8 @@ static int looks_like_pathspec(const char *arg)\n  * diagnose_misspelt_rev == 0 for the next ones (because we already\n  * saw a filename, there's not ambiguity anymore).\n  */\n-void verify_filename(const char *prefix,\n+void verify_filename(struct repository *repo,\n+\t\t     const char *prefix,\n \t\t     const char *arg,\n \t\t     int diagnose_misspelt_rev)\n {\n@@ -288,7 +289,7 @@ void verify_filename(const char *prefix,\n \t\tdie(_(\"option '%s' must come before non-option arguments\"), arg);\n \tif (looks_like_pathspec(arg) || check_filename(prefix, arg))\n \t\treturn;\n-\tdie_verify_filename(the_repository, prefix, arg, diagnose_misspelt_rev);\n+\tdie_verify_filename(repo, prefix, arg, diagnose_misspelt_rev);\n }\n \n /*\ndiff --git a/setup.h b/setup.h\nindex c3247d7fc8..24a6f66629 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -142,7 +142,8 @@ char *prefix_path(struct repository *repo, const char *prefix, int len, const ch\n char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\n \n int check_filename(const char *prefix, const char *name);\n-void verify_filename(const char *prefix,\n+void verify_filename(struct repository *repo,\n+\t\t     const char *prefix,\n \t\t     const char *name,\n \t\t     int diagnose_misspelt_rev);\n void verify_non_filename(const char *prefix, const char *name);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543624","messageId":"20260519-pks-setup-wo-the-repository-v3-7-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 07/18] setup: stop using `the_repository` in `verify_non_filename()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:11Z","receivedAt":"2026-05-19T09:52:34Z","isPatch":true,"body":"Stop using `the_repository` in `verify_non_filename()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/checkout.c | 2 +-\n builtin/grep.c     | 2 +-\n builtin/reset.c    | 2 +-\n revision.c         | 4 ++--\n setup.c            | 4 ++--\n setup.h            | 2 +-\n 6 files changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex ac0186a33e..14cefa0199 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -1492,7 +1492,7 @@ static int parse_branchname_arg(int argc, const char **argv,\n \t\t * it would be extremely annoying.\n \t\t */\n \t\tif (argc)\n-\t\t\tverify_non_filename(opts->prefix, arg);\n+\t\t\tverify_non_filename(the_repository, opts->prefix, arg);\n \t} else if (opts->accept_pathspec) {\n \t\targcount++;\n \t\targv++;\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex b0e350cf89..4ec0c016b1 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1151,7 +1151,7 @@ int cmd_grep(int argc,\n \n \t\tobject = parse_object_or_die(the_repository, &oid, arg);\n \t\tif (!seen_dashdash)\n-\t\t\tverify_non_filename(prefix, arg);\n+\t\t\tverify_non_filename(the_repository, prefix, arg);\n \t\tadd_object_array_with_path(object, arg, &list, oc.mode, oc.path);\n \t\tobject_context_release(&oc);\n \t}\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex 1ac374d31b..11f57605b5 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -281,7 +281,7 @@ static void parse_args(struct pathspec *pathspec,\n \t\t\t * Ok, argv[0] looks like a commit/tree; it should not\n \t\t\t * be a filename.\n \t\t\t */\n-\t\t\tverify_non_filename(prefix, argv[0]);\n+\t\t\tverify_non_filename(the_repository, prefix, argv[0]);\n \t\t\trev = *argv++;\n \t\t} else {\n \t\t\t/* Otherwise we treat this as a filename */\ndiff --git a/revision.c b/revision.c\nindex 5d53244379..b5fe3ef95d 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2072,7 +2072,7 @@ static int handle_dotdot_1(const char *a_name, const char *b_name,\n \t\treturn -1;\n \n \tif (!cant_be_filename) {\n-\t\tverify_non_filename(revs->prefix, full_name);\n+\t\tverify_non_filename(the_repository, revs->prefix, full_name);\n \t}\n \n \ta_obj = parse_object(revs->repo, &a_oid);\n@@ -2225,7 +2225,7 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl\n \t\tgoto out;\n \t}\n \tif (!cant_be_filename)\n-\t\tverify_non_filename(revs->prefix, arg);\n+\t\tverify_non_filename(the_repository, revs->prefix, arg);\n \tobject = get_reference(revs, arg, &oid, flags ^ local_flags);\n \tif (!object) {\n \t\tret = (revs->ignore_missing || revs->do_not_die_on_missing_objects) ? 0 : -1;\ndiff --git a/setup.c b/setup.c\nindex e673663cab..759aba4e2c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -297,9 +297,9 @@ void verify_filename(struct repository *repo,\n  * and we parsed the arg as a refname.  It should not be interpretable\n  * as a filename.\n  */\n-void verify_non_filename(const char *prefix, const char *arg)\n+void verify_non_filename(struct repository *repo, const char *prefix, const char *arg)\n {\n-\tif (!is_inside_work_tree(the_repository) || is_inside_git_dir(the_repository))\n+\tif (!is_inside_work_tree(repo) || is_inside_git_dir(repo))\n \t\treturn;\n \tif (*arg == '-')\n \t\treturn; /* flag */\ndiff --git a/setup.h b/setup.h\nindex 24a6f66629..364c2c728a 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -146,7 +146,7 @@ void verify_filename(struct repository *repo,\n \t\t     const char *prefix,\n \t\t     const char *name,\n \t\t     int diagnose_misspelt_rev);\n-void verify_non_filename(const char *prefix, const char *name);\n+void verify_non_filename(struct repository *repo, const char *prefix, const char *name);\n int path_inside_repo(struct repository *repo, const char *prefix, const char *path);\n \n void sanitize_stdfds(void);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543623","messageId":"20260519-pks-setup-wo-the-repository-v3-8-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 08/18] setup: stop using `the_repository` in `enter_repo()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:12Z","receivedAt":"2026-05-19T09:52:37Z","isPatch":true,"body":"Stop using `the_repository` in `enter_repo()` and instead accept the\nrepository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/receive-pack.c   | 2 +-\n builtin/upload-archive.c | 2 +-\n builtin/upload-pack.c    | 2 +-\n daemon.c                 | 4 ++--\n http-backend.c           | 2 +-\n setup.c                  | 4 ++--\n setup.h                  | 2 +-\n 7 files changed, 9 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex f0771590a7..322d178c92 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2643,7 +2643,7 @@ int cmd_receive_pack(int argc,\n \n \tsetup_path();\n \n-\tif (!enter_repo(service_dir, 0))\n+\tif (!enter_repo(the_repository, service_dir, 0))\n \t\tdie(\"'%s' does not appear to be a git repository\", service_dir);\n \n \trepo_config(the_repository, receive_pack_config, NULL);\ndiff --git a/builtin/upload-archive.c b/builtin/upload-archive.c\nindex 25312bb2a5..718e74b3ac 100644\n--- a/builtin/upload-archive.c\n+++ b/builtin/upload-archive.c\n@@ -31,7 +31,7 @@ int cmd_upload_archive_writer(int argc,\n \tif (argc != 2)\n \t\tusage(upload_archive_usage);\n \n-\tif (!enter_repo(argv[1], 0))\n+\tif (!enter_repo(the_repository, argv[1], 0))\n \t\tdie(\"'%s' does not appear to be a git repository\", argv[1]);\n \n \tinit_archivers();\ndiff --git a/builtin/upload-pack.c b/builtin/upload-pack.c\nindex 30498fafea..32831fb879 100644\n--- a/builtin/upload-pack.c\n+++ b/builtin/upload-pack.c\n@@ -59,7 +59,7 @@ int cmd_upload_pack(int argc,\n \n \tif (strict)\n \t\tenter_repo_flags |= ENTER_REPO_STRICT;\n-\tif (!enter_repo(dir, enter_repo_flags))\n+\tif (!enter_repo(the_repository, dir, enter_repo_flags))\n \t\tdie(\"'%s' does not appear to be a git repository\", dir);\n \n \tswitch (determine_protocol_version_server()) {\ndiff --git a/daemon.c b/daemon.c\nindex 0a7b1aae44..947dd90655 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -244,14 +244,14 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)\n \t}\n \n \tenter_repo_flags = strict_paths ? ENTER_REPO_STRICT : 0;\n-\tpath = enter_repo(dir, enter_repo_flags);\n+\tpath = enter_repo(the_repository, dir, enter_repo_flags);\n \tif (!path && base_path && base_path_relaxed) {\n \t\t/*\n \t\t * if we fail and base_path_relaxed is enabled, try without\n \t\t * prefixing the base path\n \t\t */\n \t\tdir = directory;\n-\t\tpath = enter_repo(dir, enter_repo_flags);\n+\t\tpath = enter_repo(the_repository, dir, enter_repo_flags);\n \t}\n \n \tif (!path) {\ndiff --git a/http-backend.c b/http-backend.c\nindex 1a171c5c5a..c7566b1d12 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -809,7 +809,7 @@ int cmd_main(int argc UNUSED, const char **argv UNUSED)\n \t\tnot_found(&hdr, \"Request not supported: '%s'\", dir);\n \n \tsetup_path();\n-\tif (!enter_repo(dir, 0))\n+\tif (!enter_repo(the_repository, dir, 0))\n \t\tnot_found(&hdr, \"Not a git repository: '%s'\", dir);\n \tif (!getenv(\"GIT_HTTP_EXPORT_ALL\") &&\n \t    access(\"git-daemon-export-ok\", F_OK) )\ndiff --git a/setup.c b/setup.c\nindex 759aba4e2c..cb479cd91a 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1765,7 +1765,7 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir,\n \treturn result;\n }\n \n-const char *enter_repo(const char *path, unsigned flags)\n+const char *enter_repo(struct repository *repo, const char *path, unsigned flags)\n {\n \tstatic struct strbuf validated_path = STRBUF_INIT;\n \tstatic struct strbuf used_path = STRBUF_INIT;\n@@ -1838,7 +1838,7 @@ const char *enter_repo(const char *path, unsigned flags)\n \t}\n \n \tif (is_git_directory(\".\")) {\n-\t\tset_git_dir(the_repository, \".\", 0);\n+\t\tset_git_dir(repo, \".\", 0);\n \t\tcheck_repository_format(NULL);\n \t\treturn path;\n \t}\ndiff --git a/setup.h b/setup.h\nindex 364c2c728a..d0cfdfd44a 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -134,7 +134,7 @@ enum {\n  * links.  User relative paths are also returned as they are given,\n  * except DWIM suffixing.\n  */\n-const char *enter_repo(const char *path, unsigned flags);\n+const char *enter_repo(struct repository *repo, const char *path, unsigned flags);\n \n const char *setup_git_directory_gently(int *);\n const char *setup_git_directory(void);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543625","messageId":"20260519-pks-setup-wo-the-repository-v3-9-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 09/18] setup: stop using `the_repository` in `setup_work_tree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:13Z","receivedAt":"2026-05-19T09:52:41Z","isPatch":true,"body":"Stop using `the_repository` in `setup_work_tree()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nNote that the function tracks two bits of information via global\nvariables. This of course doesn't make much sense anymore now that we\ncan set up worktrees for arbitrary repositories:\n\n  - We track whether the worktree has already been initialized and, if\n    so, we skip the call to `chdir_notify()` and setenv(3p). It does not\n    make much sense to store this info in the repository, as we _would_\n    want to update the environment when switching between worktrees back\n    and forth.\n\n    So instead of storing this info in the repository, we drop this\n    state entirely and live with the fact that we may execute the logic\n    twice. It should ultimately be idempotent though and thus not be\n    much of a problem.\n\n  - We track whether the worktree configuration is bogus. If so, and if\n    later on some caller tries to setup the worktree, then we'll die\n    instead. This is indeed information that we can move into the\n    repository itself.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n blame.c                     |  2 +-\n builtin/check-attr.c        |  2 +-\n builtin/clone.c             |  2 +-\n builtin/describe.c          |  2 +-\n builtin/diff-index.c        |  2 +-\n builtin/diff.c              |  4 ++--\n builtin/difftool.c          |  2 +-\n builtin/grep.c              |  2 +-\n builtin/ls-files.c          |  2 +-\n builtin/read-tree.c         |  2 +-\n builtin/reset.c             |  2 +-\n builtin/rm.c                |  2 +-\n builtin/sparse-checkout.c   | 16 ++++++++--------\n builtin/submodule--helper.c |  2 +-\n builtin/update-index.c      | 10 +++++-----\n git.c                       |  2 +-\n repository.h                |  1 +\n setup.c                     | 15 ++++-----------\n setup.h                     |  2 +-\n t/helper/test-subprocess.c  |  4 +++-\n wt-status.c                 |  2 +-\n 21 files changed, 38 insertions(+), 42 deletions(-)\n\ndiff --git a/blame.c b/blame.c\nindex a3c49d132e..977cbb7097 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -2813,7 +2813,7 @@ void setup_scoreboard(struct blame_scoreboard *sb,\n \t\t}\n \n \t\tif (!sb->contents_from)\n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \n \t\tsb->final = fake_working_tree_commit(sb->repo,\n \t\t\t\t\t\t     &sb->revs->diffopt,\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 04b86e42ae..98f64d5b92 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -117,7 +117,7 @@ int cmd_check_attr(int argc,\n \tint cnt, i, doubledash, filei;\n \n \tif (!is_bare_repository())\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \trepo_config(the_repository, git_default_config, NULL);\n \ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex d23b0cafcf..09f6d97658 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -669,7 +669,7 @@ static int checkout(int submodule_progress,\n \t}\n \n \t/* We need to be in the new work tree for the checkout */\n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \n \trepo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);\n \ndiff --git a/builtin/describe.c b/builtin/describe.c\nindex bffeed13a3..1c47d7c0b7 100644\n--- a/builtin/describe.c\n+++ b/builtin/describe.c\n@@ -781,7 +781,7 @@ int cmd_describe(int argc,\n \t\t\tstruct rev_info revs;\n \t\t\tint fd;\n \n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \t\t\tprepare_repo_settings(the_repository);\n \t\t\tthe_repository->settings.command_requires_full_index = 0;\n \t\t\trepo_read_index(the_repository);\ndiff --git a/builtin/diff-index.c b/builtin/diff-index.c\nindex 522dacfc4c..3db7cffede 100644\n--- a/builtin/diff-index.c\n+++ b/builtin/diff-index.c\n@@ -69,7 +69,7 @@ int cmd_diff_index(int argc,\n \t    rev.max_count != -1 || rev.min_age != -1 || rev.max_age != -1)\n \t\tusage(diff_cache_usage);\n \tif (!(option & DIFF_INDEX_CACHED)) {\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\tif (repo_read_index_preload(the_repository, &rev.diffopt.pathspec, 0) < 0) {\n \t\t\tperror(\"repo_read_index_preload\");\n \t\t\treturn -1;\ndiff --git a/builtin/diff.c b/builtin/diff.c\nindex 7ddebce2ac..1ede873ac1 100644\n--- a/builtin/diff.c\n+++ b/builtin/diff.c\n@@ -159,7 +159,7 @@ static void builtin_diff_index(struct rev_info *revs,\n \t    revs->max_age != -1)\n \t\tusage(builtin_diff_usage);\n \tif (!(option & DIFF_INDEX_CACHED)) {\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\tif (repo_read_index_preload(the_repository,\n \t\t\t\t\t    &revs->diffopt.pathspec, 0) < 0) {\n \t\t\tdie_errno(\"repo_read_index_preload\");\n@@ -281,7 +281,7 @@ static void builtin_diff_files(struct rev_info *revs, int argc, const char **arg\n \t    (revs->diffopt.output_format & DIFF_FORMAT_PATCH))\n \t\tdiff_merges_set_dense_combined_if_unset(revs);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (repo_read_index_preload(the_repository, &revs->diffopt.pathspec,\n \t\t\t\t    0) < 0) {\n \t\tdie_errno(\"repo_read_index_preload\");\ndiff --git a/builtin/difftool.c b/builtin/difftool.c\nindex e4bc1f8316..2a21005f2e 100644\n--- a/builtin/difftool.c\n+++ b/builtin/difftool.c\n@@ -767,7 +767,7 @@ int cmd_difftool(int argc,\n \t\tdie(_(\"difftool requires worktree or --no-index\"));\n \n \tif (!no_index){\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(repo);\n \t\tsetenv(GIT_DIR_ENVIRONMENT, absolute_path(repo_get_git_dir(repo)), 1);\n \t\tsetenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(repo_get_work_tree(repo)), 1);\n \t} else if (dir_diff)\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 4ec0c016b1..679f8b567a 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1272,7 +1272,7 @@ int cmd_grep(int argc,\n \t\tdie(_(\"--[no-]exclude-standard cannot be used for tracked contents\"));\n \t} else if (!list.nr) {\n \t\tif (!cached)\n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \n \t\thit = grep_cache(&opt, &pathspec, cached);\n \t} else {\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex 09d95111b3..e1a22b41b9 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -704,7 +704,7 @@ int cmd_ls_files(int argc,\n \t\texc_given = 1;\n \n \tif (require_work_tree && !is_inside_work_tree(repo))\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(repo);\n \n \tif (recurse_submodules &&\n \t    (show_deleted || show_others || show_unmerged ||\ndiff --git a/builtin/read-tree.c b/builtin/read-tree.c\nindex 460b21e40a..999a82ecdf 100644\n--- a/builtin/read-tree.c\n+++ b/builtin/read-tree.c\n@@ -229,7 +229,7 @@ int cmd_read_tree(int argc,\n \t\topts.preserve_ignored = 0;\n \t/* otherwise, opts.preserve_ignored is irrelevant */\n \tif (opts.merge && !opts.index_only)\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \tif (opts.skip_sparse_checkout)\n \t\tensure_full_index(the_repository->index);\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex 11f57605b5..3be6bd0121 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -468,7 +468,7 @@ int cmd_reset(int argc,\n \t\ttrace2_cmd_mode(reset_type_names[reset_type]);\n \n \tif (reset_type != SOFT && (reset_type != MIXED || repo_get_work_tree(the_repository)))\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \tif (reset_type == MIXED && is_bare_repository())\n \t\tdie(_(\"%s reset is not allowed in a bare repository\"),\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex 05d89e98c3..081d0bc375 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -296,7 +296,7 @@ int cmd_rm(int argc,\n \t\tdie(_(\"No pathspec was given. Which files should I remove?\"));\n \n \tif (!index_only)\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \tprepare_repo_settings(the_repository);\n \tthe_repository->settings.command_requires_full_index = 0;\ndiff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c\nindex 2af50fb2f9..d89acbeb53 100644\n--- a/builtin/sparse-checkout.c\n+++ b/builtin/sparse-checkout.c\n@@ -63,7 +63,7 @@ static int sparse_checkout_list(int argc, const char **argv, const char *prefix,\n \tint res;\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"this worktree is not sparse\"));\n \n@@ -229,7 +229,7 @@ static int update_working_directory(struct repository *r,\n \to.dst_index = r->index;\n \to.skip_sparse_checkout = 0;\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \n \trepo_hold_locked_index(r, &lock_file, LOCK_DIE_ON_ERROR);\n \n@@ -468,7 +468,7 @@ static int sparse_checkout_init(int argc, const char **argv, const char *prefix,\n \t\tOPT_END(),\n \t};\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \trepo_read_index(repo);\n \n \tinit_opts.cone_mode = -1;\n@@ -802,7 +802,7 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix,\n \tint ret;\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"no sparse-checkout to add to\"));\n \n@@ -856,7 +856,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix,\n \tstruct strvec patterns = STRVEC_INIT;\n \tint ret;\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \trepo_read_index(repo);\n \n \tset_opts.cone_mode = -1;\n@@ -912,7 +912,7 @@ static int sparse_checkout_reapply(int argc, const char **argv,\n \t};\n \tstruct repo_config_values *cfg = repo_config_values(the_repository);\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"must be in a sparse-checkout to reapply sparsity patterns\"));\n \n@@ -975,7 +975,7 @@ static int sparse_checkout_clean(int argc, const char **argv,\n \t\tOPT_END(),\n \t};\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \tif (!cfg->apply_sparse_checkout)\n \t\tdie(_(\"must be in a sparse-checkout to clean directories\"));\n \tif (!core_sparse_checkout_cone)\n@@ -1053,7 +1053,7 @@ static int sparse_checkout_disable(int argc, const char **argv,\n \t * forcibly return to a dense checkout regardless of initial state.\n \t */\n \n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \targc = parse_options(argc, argv, prefix,\n \t\t\t     builtin_sparse_checkout_disable_options,\n \t\t\t     builtin_sparse_checkout_disable_usage, 0);\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 2f589e3b37..1cc82a134d 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1250,7 +1250,7 @@ static int compute_summary_module_list(struct object_id *head_oid,\n \n \tif (!info->cached) {\n \t\tif (diff_cmd == DIFF_INDEX)\n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \t\tif (repo_read_index_preload(the_repository, &rev.diffopt.pathspec, 0) < 0) {\n \t\t\tperror(\"repo_read_index_preload\");\n \t\t\tret = -1;\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 7434112b8e..d6dabacfd1 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -732,7 +732,7 @@ struct refresh_params {\n \n static int refresh(struct refresh_params *o, unsigned int flag)\n {\n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \trepo_read_index(the_repository);\n \t*o->has_errors |= refresh_index(the_repository->index, o->flags | flag, NULL,\n \t\t\t\t\tNULL, NULL);\n@@ -901,7 +901,7 @@ static enum parse_opt_result reupdate_callback(\n \tBUG_ON_OPT_ARG(arg);\n \n \t/* consume remaining arguments. */\n-\tsetup_work_tree();\n+\tsetup_work_tree(the_repository);\n \t*has_errors = do_reupdate(ctx->argv + 1, prefix);\n \tif (*has_errors)\n \t\tthe_repository->index->cache_changed = 0;\n@@ -1157,7 +1157,7 @@ int cmd_update_index(int argc,\n \t\t\t\ttransaction = NULL;\n \t\t\t}\n \n-\t\t\tsetup_work_tree();\n+\t\t\tsetup_work_tree(the_repository);\n \t\t\tp = prefix_path(the_repository, prefix, prefix_length, path);\n \t\t\tupdate_one(p);\n \t\t\tif (set_executable_bit)\n@@ -1199,7 +1199,7 @@ int cmd_update_index(int argc,\n \t\tstruct strbuf buf = STRBUF_INIT;\n \t\tstruct strbuf unquoted = STRBUF_INIT;\n \n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\twhile (getline_fn(&buf, stdin) != EOF) {\n \t\t\tchar *p;\n \t\t\tif (!nul_term_line && buf.buf[0] == '\"') {\n@@ -1253,7 +1253,7 @@ int cmd_update_index(int argc,\n \t\treport(_(\"Untracked cache disabled\"));\n \t\tbreak;\n \tcase UC_TEST:\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\treturn !test_if_untracked_cache_is_supported();\n \tcase UC_ENABLE:\n \tcase UC_FORCE:\ndiff --git a/git.c b/git.c\nindex 5a40eab8a2..eaede42c4e 100644\n--- a/git.c\n+++ b/git.c\n@@ -497,7 +497,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct\n \tcommit_pager_choice();\n \n \tif (!help && p->option & NEED_WORK_TREE)\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \n \ttrace_argv_printf(argv, \"trace: built-in: git\");\n \ttrace2_cmd_name(p->cmd);\ndiff --git a/repository.h b/repository.h\nindex 4969d8b8eb..832451fc61 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -114,6 +114,7 @@ struct repository {\n \t * A NULL value indicates that there is no working directory.\n \t */\n \tchar *worktree;\n+\tbool worktree_config_is_bogus;\n \n \t/*\n \t * Path from the root of the top-level superproject down to this\ndiff --git a/setup.c b/setup.c\nindex cb479cd91a..50324f8f37 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -26,7 +26,6 @@\n #include \"trace2.h\"\n #include \"worktree.h\"\n \n-static int work_tree_config_is_bogus;\n enum allowed_bare_repo {\n \tALLOWED_BARE_REPO_EXPLICIT = 0,\n \tALLOWED_BARE_REPO_ALL,\n@@ -494,18 +493,14 @@ int is_inside_work_tree(struct repository *repo)\n \treturn ret;\n }\n \n-void setup_work_tree(void)\n+void setup_work_tree(struct repository *repo)\n {\n \tconst char *work_tree;\n-\tstatic int initialized = 0;\n \n-\tif (initialized)\n-\t\treturn;\n-\n-\tif (work_tree_config_is_bogus)\n+\tif (repo->worktree_config_is_bogus)\n \t\tdie(_(\"unable to set up work tree using invalid config\"));\n \n-\twork_tree = repo_get_work_tree(the_repository);\n+\twork_tree = repo_get_work_tree(repo);\n \tif (!work_tree || chdir_notify(work_tree))\n \t\tdie(_(\"this operation must be run in a work tree\"));\n \n@@ -515,8 +510,6 @@ void setup_work_tree(void)\n \t */\n \tif (getenv(GIT_WORK_TREE_ENVIRONMENT))\n \t\tsetenv(GIT_WORK_TREE_ENVIRONMENT, \".\", 1);\n-\n-\tinitialized = 1;\n }\n \n static void setup_original_cwd(struct repository *repo)\n@@ -1164,7 +1157,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t\tif (git_work_tree_cfg) {\n \t\t\t/* #22.2, #30 */\n \t\t\twarning(\"core.bare and core.worktree do not make sense\");\n-\t\t\twork_tree_config_is_bogus = 1;\n+\t\t\trepo->worktree_config_is_bogus = true;\n \t\t}\n \n \t\t/* #18, #26 */\ndiff --git a/setup.h b/setup.h\nindex d0cfdfd44a..8fed365637 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -56,7 +56,7 @@ const char *resolve_gitdir_gently(const char *suspect, int *return_error_code);\n void die_upon_dubious_ownership(const char *gitfile, const char *worktree,\n \t\t\t\tconst char *gitdir);\n \n-void setup_work_tree(void);\n+void setup_work_tree(struct repository *repo);\n \n /*\n  * discover_git_directory_reason() is similar to discover_git_directory(),\ndiff --git a/t/helper/test-subprocess.c b/t/helper/test-subprocess.c\nindex c344f1694d..8a070e47cd 100644\n--- a/t/helper/test-subprocess.c\n+++ b/t/helper/test-subprocess.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"run-command.h\"\n #include \"setup.h\"\n@@ -11,7 +13,7 @@ int cmd__subprocess(int argc, const char **argv)\n \tif (nogit)\n \t\tdie(\"No git repo found\");\n \tif (argc > 1 && !strcmp(argv[1], \"--setup-work-tree\")) {\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\targv++;\n \t}\n \tcp.git_cmd = 1;\ndiff --git a/wt-status.c b/wt-status.c\nindex 479ccc3304..6cc77ba68c 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1206,7 +1206,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)\n \t\tstatus_printf_ln(s, c,\n \t\t\t\"--------------------------------------------------\");\n \t\tstatus_printf_ln(s, c, _(\"Changes not staged for commit:\"));\n-\t\tsetup_work_tree();\n+\t\tsetup_work_tree(the_repository);\n \t\trev.diffopt.a_prefix = \"i/\";\n \t\trev.diffopt.b_prefix = \"w/\";\n \t\trun_diff_files(&rev, 0);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543627","messageId":"20260519-pks-setup-wo-the-repository-v3-10-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 10/18] setup: stop using `the_repository` in `set_git_work_tree()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:14Z","receivedAt":"2026-05-19T09:52:41Z","isPatch":true,"body":"Stop using `the_repository` in `set_git_work_tree()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSimilar as with the preceding commit, we track whether the worktree has\nbeen initialized already via a global variable so that we can die in\ncase the repository is re-initialized with a different worktree path.\nStore this info in the `struct repository` instead so that we correctly\nhandle this per repository.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c   |  2 +-\n builtin/init-db.c |  6 +++---\n repository.h      |  1 +\n setup.c           | 24 +++++++++++-------------\n setup.h           |  2 +-\n 5 files changed, 17 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 09f6d97658..8844e3d481 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1116,7 +1116,7 @@ int cmd_clone(int argc,\n \t\t\tdie_errno(_(\"could not create work tree dir '%s'\"),\n \t\t\t\t  work_tree);\n \t\tjunk_work_tree = work_tree;\n-\t\tset_git_work_tree(work_tree);\n+\t\tset_git_work_tree(the_repository, work_tree);\n \t}\n \n \tif (real_git_dir) {\ndiff --git a/builtin/init-db.c b/builtin/init-db.c\nindex bb853e69f5..e626b0d8b7 100644\n--- a/builtin/init-db.c\n+++ b/builtin/init-db.c\n@@ -237,9 +237,9 @@ int cmd_init_db(int argc,\n \t\tif (!git_work_tree_cfg)\n \t\t\tgit_work_tree_cfg = xgetcwd();\n \t\tif (work_tree)\n-\t\t\tset_git_work_tree(work_tree);\n+\t\t\tset_git_work_tree(the_repository, work_tree);\n \t\telse\n-\t\t\tset_git_work_tree(git_work_tree_cfg);\n+\t\t\tset_git_work_tree(the_repository, git_work_tree_cfg);\n \t\tif (access(repo_get_work_tree(the_repository), X_OK))\n \t\t\tdie_errno (_(\"Cannot access work tree '%s'\"),\n \t\t\t\t   repo_get_work_tree(the_repository));\n@@ -248,7 +248,7 @@ int cmd_init_db(int argc,\n \t\tif (real_git_dir)\n \t\t\tdie(_(\"--separate-git-dir incompatible with bare repository\"));\n \t\tif (work_tree)\n-\t\t\tset_git_work_tree(work_tree);\n+\t\t\tset_git_work_tree(the_repository, work_tree);\n \t}\n \n \tflags |= INIT_DB_EXIST_OK;\ndiff --git a/repository.h b/repository.h\nindex 832451fc61..d391aff8ab 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -114,6 +114,7 @@ struct repository {\n \t * A NULL value indicates that there is no working directory.\n \t */\n \tchar *worktree;\n+\tbool worktree_initialized;\n \tbool worktree_config_is_bogus;\n \n \t/*\ndiff --git a/setup.c b/setup.c\nindex 50324f8f37..796ac5792f 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1152,7 +1152,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \n \t/* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */\n \tif (work_tree_env)\n-\t\tset_git_work_tree(work_tree_env);\n+\t\tset_git_work_tree(repo, work_tree_env);\n \telse if (is_bare_repository_cfg > 0) {\n \t\tif (git_work_tree_cfg) {\n \t\t\t/* #22.2, #30 */\n@@ -1167,7 +1167,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t}\n \telse if (git_work_tree_cfg) { /* #6, #14 */\n \t\tif (is_absolute_path(git_work_tree_cfg))\n-\t\t\tset_git_work_tree(git_work_tree_cfg);\n+\t\t\tset_git_work_tree(repo, git_work_tree_cfg);\n \t\telse {\n \t\t\tchar *core_worktree;\n \t\t\tif (chdir(gitdirenv))\n@@ -1177,7 +1177,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t\t\tcore_worktree = xgetcwd();\n \t\t\tif (chdir(cwd->buf))\n \t\t\t\tdie_errno(_(\"cannot come back to cwd\"));\n-\t\t\tset_git_work_tree(core_worktree);\n+\t\t\tset_git_work_tree(repo, core_worktree);\n \t\t\tfree(core_worktree);\n \t\t}\n \t}\n@@ -1188,7 +1188,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,\n \t\treturn NULL;\n \t}\n \telse /* #2, #10 */\n-\t\tset_git_work_tree(\".\");\n+\t\tset_git_work_tree(repo, \".\");\n \n \t/* set_git_work_tree() must have been called by now */\n \tworktree = repo_get_work_tree(repo);\n@@ -1248,7 +1248,7 @@ static const char *setup_discovered_git_dir(struct repository *repo,\n \t}\n \n \t/* #0, #1, #5, #8, #9, #12, #13 */\n-\tset_git_work_tree(\".\");\n+\tset_git_work_tree(repo, \".\");\n \tif (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))\n \t\tset_git_dir(repo, gitdir, 0);\n \tif (offset >= cwd->len)\n@@ -1839,29 +1839,27 @@ const char *enter_repo(struct repository *repo, const char *path, unsigned flags\n \treturn NULL;\n }\n \n-static int git_work_tree_initialized;\n-\n /*\n  * Note.  This works only before you used a work tree.  This was added\n  * primarily to support git-clone to work in a new repository it just\n  * created, and is not meant to flip between different work trees.\n  */\n-void set_git_work_tree(const char *new_work_tree)\n+void set_git_work_tree(struct repository *repo, const char *new_work_tree)\n {\n-\tif (git_work_tree_initialized) {\n+\tif (repo->worktree_initialized) {\n \t\tstruct strbuf realpath = STRBUF_INIT;\n \n \t\tstrbuf_realpath(&realpath, new_work_tree, 1);\n \t\tnew_work_tree = realpath.buf;\n-\t\tif (strcmp(new_work_tree, the_repository->worktree))\n+\t\tif (strcmp(new_work_tree, repo->worktree))\n \t\t\tdie(\"internal error: work tree has already been set\\n\"\n \t\t\t    \"Current worktree: %s\\nNew worktree: %s\",\n-\t\t\t    the_repository->worktree, new_work_tree);\n+\t\t\t    repo->worktree, new_work_tree);\n \t\tstrbuf_release(&realpath);\n \t\treturn;\n \t}\n-\tgit_work_tree_initialized = 1;\n-\trepo_set_worktree(the_repository, new_work_tree);\n+\trepo->worktree_initialized = true;\n+\trepo_set_worktree(repo, new_work_tree);\n }\n \n const char *setup_git_directory_gently(int *nongit_ok)\ndiff --git a/setup.h b/setup.h\nindex 8fed365637..1a37089fa0 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -96,7 +96,7 @@ static inline int discover_git_directory(struct strbuf *commondir,\n \treturn 0;\n }\n \n-void set_git_work_tree(const char *tree);\n+void set_git_work_tree(struct repository *repo, const char *tree);\n \n /* Flags that can be passed to `enter_repo()`. */\n enum {\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543626","messageId":"20260519-pks-setup-wo-the-repository-v3-11-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 11/18] setup: stop using `the_repository` in `setup_git_env()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:15Z","receivedAt":"2026-05-19T09:52:44Z","isPatch":true,"body":"Stop using `the_repository` in `setup_git_env()` and instead accept the\nrepository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nFurthermore, the function is never used outside of \"setup.c\". Drop the\ndeclaration in \"environment.h\" and make it static.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n environment.h | 2 --\n setup.c       | 6 +++---\n 2 files changed, 3 insertions(+), 5 deletions(-)\n\ndiff --git a/environment.h b/environment.h\nindex 123a71cdc8..9eb97b3869 100644\n--- a/environment.h\n+++ b/environment.h\n@@ -147,8 +147,6 @@ void repo_config_values_init(struct repo_config_values *cfg);\n  * Please do not add new global config variables here.\n  */\n # ifdef USE_THE_REPOSITORY_VARIABLE\n-void setup_git_env(const char *git_dir);\n-\n /*\n  * Returns true iff we have a configured git repository (either via\n  * setup_git_directory, or in the environment via $GIT_DIR).\ndiff --git a/setup.c b/setup.c\nindex 796ac5792f..8965f8ccaf 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1074,9 +1074,9 @@ static void setup_git_env_internal(struct repository *repo,\n \t\tfetch_if_missing = 0;\n }\n \n-void setup_git_env(const char *git_dir)\n+static void setup_git_env(struct repository *repo, const char *git_dir)\n {\n-\tsetup_git_env_internal(the_repository, git_dir, false);\n+\tsetup_git_env_internal(repo, git_dir, false);\n }\n \n static void set_git_dir_1(struct repository *repo, const char *path, bool skip_initializing_odb)\n@@ -1988,7 +1988,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\t\tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n \t\t\tif (!gitdir)\n \t\t\t\tgitdir = DEFAULT_GIT_DIR_ENVIRONMENT;\n-\t\t\tsetup_git_env(gitdir);\n+\t\t\tsetup_git_env(the_repository, gitdir);\n \t\t}\n \t\tif (startup_info->have_repository) {\n \t\t\trepo_set_hash_algo(the_repository, repo_fmt.hash_algo);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543628","messageId":"20260519-pks-setup-wo-the-repository-v3-12-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 12/18] setup: stop using `the_repository` in `setup_git_directory_gently()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:16Z","receivedAt":"2026-05-19T09:52:48Z","isPatch":true,"body":"Stop using `the_repository` in `setup_git_directory_gently()` and\ninstead accept the repository as a parameter. The injection of\n`the_repository` is thus bumped one level higher, where callers now pass\nit in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/check-ref-format.c |  5 ++++-\n builtin/diff.c             |  2 +-\n builtin/hash-object.c      |  2 +-\n builtin/help.c             |  2 +-\n builtin/stripspace.c       |  2 +-\n git.c                      |  6 +++---\n http-fetch.c               |  2 +-\n imap-send.c                |  2 +-\n remote-curl.c              |  4 ++--\n setup.c                    | 36 ++++++++++++++++++------------------\n setup.h                    |  2 +-\n t/helper/test-path-utils.c |  2 +-\n t/helper/test-subprocess.c |  2 +-\n 13 files changed, 36 insertions(+), 33 deletions(-)\n\ndiff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c\nindex 5d80afeec0..e42b0444ea 100644\n--- a/builtin/check-ref-format.c\n+++ b/builtin/check-ref-format.c\n@@ -1,6 +1,9 @@\n /*\n  * GIT - The information manager from hell\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"builtin.h\"\n #include \"refs.h\"\n #include \"setup.h\"\n@@ -41,7 +44,7 @@ static int check_ref_format_branch(const char *arg)\n \tconst char *name;\n \tint nongit;\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \tif (check_branch_ref(&sb, arg) ||\n \t    !skip_prefix(sb.buf, \"refs/heads/\", &name))\n \t\tdie(\"'%s' is not a valid branch name\", arg);\ndiff --git a/builtin/diff.c b/builtin/diff.c\nindex 1ede873ac1..4b46e394ce 100644\n--- a/builtin/diff.c\n+++ b/builtin/diff.c\n@@ -455,7 +455,7 @@ int cmd_diff(int argc,\n \t\t\tbreak;\n \t}\n \n-\tprefix = setup_git_directory_gently(&nongit);\n+\tprefix = setup_git_directory_gently(the_repository, &nongit);\n \n \tif (!nongit) {\n \t\tprepare_repo_settings(the_repository);\ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex 5d900a6b8c..d7905bedc2 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -102,7 +102,7 @@ int cmd_hash_object(int argc,\n \tif (flags & INDEX_WRITE_OBJECT)\n \t\tprefix = setup_git_directory();\n \telse\n-\t\tprefix = setup_git_directory_gently(&nongit);\n+\t\tprefix = setup_git_directory_gently(the_repository, &nongit);\n \n \tif (nongit && !the_hash_algo)\n \t\trepo_set_hash_algo(the_repository, GIT_HASH_DEFAULT);\ndiff --git a/builtin/help.c b/builtin/help.c\nindex c0aece4da3..a140339999 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -740,7 +740,7 @@ int cmd_help(int argc,\n \t\treturn 0;\n \t}\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \trepo_config(the_repository, git_help_config, NULL);\n \n \tif (parsed_help_format != HELP_FORMAT_NONE)\ndiff --git a/builtin/stripspace.c b/builtin/stripspace.c\nindex 4a566cbc5d..18705f1a5b 100644\n--- a/builtin/stripspace.c\n+++ b/builtin/stripspace.c\n@@ -54,7 +54,7 @@ int cmd_stripspace(int argc,\n \t\tusage_with_options(stripspace_usage, options);\n \n \tif (mode == STRIP_COMMENTS || mode == COMMENT_LINES) {\n-\t\tsetup_git_directory_gently(&nongit);\n+\t\tsetup_git_directory_gently(the_repository, &nongit);\n \t\trepo_config(the_repository, git_default_config, NULL);\n \t}\n \ndiff --git a/git.c b/git.c\nindex eaede42c4e..2cc018fc5c 100644\n--- a/git.c\n+++ b/git.c\n@@ -84,7 +84,7 @@ static int list_cmds(const char *spec)\n \t* Set up the repository so we can pick up any repo-level config (like\n \t* completion.commands).\n \t*/\n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \n \twhile (*spec) {\n \t\tconst char *sep = strchrnul(spec, ',');\n@@ -386,7 +386,7 @@ static int handle_alias(struct strvec *args, struct string_list *expanded_aliase\n \t\t\tint nongit_ok;\n \n \t\t\t/* Aliases expect GIT_PREFIX, GIT_DIR etc to be set */\n-\t\t\tsetup_git_directory_gently(&nongit_ok);\n+\t\t\tsetup_git_directory_gently(the_repository, &nongit_ok);\n \n \t\t\tcommit_pager_choice();\n \n@@ -480,7 +480,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct\n \t\tprefix = setup_git_directory();\n \t\tno_repo = 0;\n \t} else if (run_setup & RUN_SETUP_GENTLY) {\n-\t\tprefix = setup_git_directory_gently(&no_repo);\n+\t\tprefix = setup_git_directory_gently(the_repository, &no_repo);\n \t} else {\n \t\tprefix = NULL;\n \t}\ndiff --git a/http-fetch.c b/http-fetch.c\nindex 1922e23fcd..f9b6ecb061 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -109,7 +109,7 @@ int cmd_main(int argc, const char **argv)\n \tstruct strvec index_pack_args = STRVEC_INIT;\n \tint ret;\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \n \twhile (arg < argc && argv[arg][0] == '-') {\n \t\tconst char *p;\ndiff --git a/imap-send.c b/imap-send.c\nindex af02c6a689..cfd6a5120c 100644\n--- a/imap-send.c\n+++ b/imap-send.c\n@@ -1799,7 +1799,7 @@ int cmd_main(int argc, const char **argv)\n \tint nongit_ok;\n \tint ret;\n \n-\tsetup_git_directory_gently(&nongit_ok);\n+\tsetup_git_directory_gently(the_repository, &nongit_ok);\n \trepo_config(the_repository, git_imap_config, &server);\n \n \targc = parse_options(argc, (const char **)argv, \"\", imap_send_options, imap_send_usage, 0);\ndiff --git a/remote-curl.c b/remote-curl.c\nindex aba60d5712..a84fc860ec 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -1557,7 +1557,7 @@ int cmd_main(int argc, const char **argv)\n \tint nongit;\n \tint ret = 1;\n \n-\tsetup_git_directory_gently(&nongit);\n+\tsetup_git_directory_gently(the_repository, &nongit);\n \tif (argc < 2) {\n \t\terror(_(\"remote-curl: usage: git remote-curl <remote> [<url>]\"));\n \t\tgoto cleanup;\n@@ -1605,7 +1605,7 @@ int cmd_main(int argc, const char **argv)\n \t\t\tbreak;\n \t\tif (starts_with(buf.buf, \"fetch \")) {\n \t\t\tif (nongit) {\n-\t\t\t\tsetup_git_directory_gently(&nongit);\n+\t\t\t\tsetup_git_directory_gently(the_repository, &nongit);\n \t\t\t\tif (nongit)\n \t\t\t\t\tdie(_(\"remote-curl: fetch attempted without a local repo\"));\n \t\t\t}\ndiff --git a/setup.c b/setup.c\nindex 8965f8ccaf..c12c6cbda2 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1862,7 +1862,7 @@ void set_git_work_tree(struct repository *repo, const char *new_work_tree)\n \trepo_set_worktree(repo, new_work_tree);\n }\n \n-const char *setup_git_directory_gently(int *nongit_ok)\n+const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)\n {\n \tstatic struct strbuf cwd = STRBUF_INIT;\n \tstruct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT, report = STRBUF_INIT;\n@@ -1877,7 +1877,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t * configuration (including the per-repo config file that we\n \t * ignored previously).\n \t */\n-\trepo_config_clear(the_repository);\n+\trepo_config_clear(repo);\n \n \t/*\n \t * Let's assume that we are in a git repository.\n@@ -1893,18 +1893,18 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \n \tswitch (setup_git_directory_gently_1(&dir, &gitdir, &report, 1)) {\n \tcase GIT_DIR_EXPLICIT:\n-\t\tprefix = setup_explicit_git_dir(the_repository, gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_explicit_git_dir(repo, gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_DISCOVERED:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_discovered_git_dir(the_repository, gitdir.buf, &cwd, dir.len,\n+\t\tprefix = setup_discovered_git_dir(repo, gitdir.buf, &cwd, dir.len,\n \t\t\t\t\t\t  &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_BARE:\n \t\tif (dir.len < cwd.len && chdir(dir.buf))\n \t\t\tdie(_(\"cannot change to '%s'\"), dir.buf);\n-\t\tprefix = setup_bare_git_dir(the_repository, &cwd, dir.len, &repo_fmt, nongit_ok);\n+\t\tprefix = setup_bare_git_dir(repo, &cwd, dir.len, &repo_fmt, nongit_ok);\n \t\tbreak;\n \tcase GIT_DIR_HIT_CEILING:\n \t\tif (!nongit_ok)\n@@ -1984,30 +1984,30 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t    startup_info->have_repository ||\n \t    /* GIT_DIR_EXPLICIT */\n \t    getenv(GIT_DIR_ENVIRONMENT)) {\n-\t\tif (!the_repository->gitdir) {\n+\t\tif (!repo->gitdir) {\n \t\t\tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n \t\t\tif (!gitdir)\n \t\t\t\tgitdir = DEFAULT_GIT_DIR_ENVIRONMENT;\n-\t\t\tsetup_git_env(the_repository, gitdir);\n+\t\t\tsetup_git_env(repo, gitdir);\n \t\t}\n \t\tif (startup_info->have_repository) {\n-\t\t\trepo_set_hash_algo(the_repository, repo_fmt.hash_algo);\n-\t\t\trepo_set_compat_hash_algo(the_repository,\n+\t\t\trepo_set_hash_algo(repo, repo_fmt.hash_algo);\n+\t\t\trepo_set_compat_hash_algo(repo,\n \t\t\t\t\t\t  repo_fmt.compat_hash_algo);\n-\t\t\trepo_set_ref_storage_format(the_repository,\n+\t\t\trepo_set_ref_storage_format(repo,\n \t\t\t\t\t\t    repo_fmt.ref_storage_format,\n \t\t\t\t\t\t    repo_fmt.ref_storage_payload);\n-\t\t\tthe_repository->repository_format_worktree_config =\n+\t\t\trepo->repository_format_worktree_config =\n \t\t\t\trepo_fmt.worktree_config;\n-\t\t\tthe_repository->repository_format_relative_worktrees =\n+\t\t\trepo->repository_format_relative_worktrees =\n \t\t\t\trepo_fmt.relative_worktrees;\n-\t\t\tthe_repository->repository_format_submodule_path_cfg =\n+\t\t\trepo->repository_format_submodule_path_cfg =\n \t\t\t\trepo_fmt.submodule_path_cfg;\n \t\t\t/* take ownership of repo_fmt.partial_clone */\n-\t\t\tthe_repository->repository_format_partial_clone =\n+\t\t\trepo->repository_format_partial_clone =\n \t\t\t\trepo_fmt.partial_clone;\n \t\t\trepo_fmt.partial_clone = NULL;\n-\t\t\tthe_repository->repository_format_precious_objects =\n+\t\t\trepo->repository_format_precious_objects =\n \t\t\t\trepo_fmt.precious_objects;\n \t\t}\n \t}\n@@ -2040,13 +2040,13 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\tformat = ref_storage_format_by_name(backend);\n \t\tif (format == REF_STORAGE_FORMAT_UNKNOWN)\n \t\t\tdie(_(\"unknown ref storage format: '%s'\"), backend);\n-\t\trepo_set_ref_storage_format(the_repository, format, payload);\n+\t\trepo_set_ref_storage_format(repo, format, payload);\n \n \t\tfree(backend);\n \t\tfree(payload);\n \t}\n \n-\tsetup_original_cwd(the_repository);\n+\tsetup_original_cwd(repo);\n \n \tstrbuf_release(&dir);\n \tstrbuf_release(&gitdir);\n@@ -2138,7 +2138,7 @@ void check_repository_format(struct repository_format *fmt)\n  */\n const char *setup_git_directory(void)\n {\n-\treturn setup_git_directory_gently(NULL);\n+\treturn setup_git_directory_gently(the_repository, NULL);\n }\n \n const char *resolve_gitdir_gently(const char *suspect, int *return_error_code)\ndiff --git a/setup.h b/setup.h\nindex 1a37089fa0..18092fbf16 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -136,7 +136,7 @@ enum {\n  */\n const char *enter_repo(struct repository *repo, const char *path, unsigned flags);\n \n-const char *setup_git_directory_gently(int *);\n+const char *setup_git_directory_gently(struct repository *repo, int *);\n const char *setup_git_directory(void);\n char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path);\n char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\ndiff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c\nindex 163fdeefb0..15eb44485c 100644\n--- a/t/helper/test-path-utils.c\n+++ b/t/helper/test-path-utils.c\n@@ -377,7 +377,7 @@ int cmd__path_utils(int argc, const char **argv)\n \t\tconst char *prefix = argv[2];\n \t\tint prefix_len = strlen(prefix);\n \t\tint nongit_ok;\n-\t\tsetup_git_directory_gently(&nongit_ok);\n+\t\tsetup_git_directory_gently(the_repository, &nongit_ok);\n \t\twhile (argc > 3) {\n \t\t\tchar *pfx = prefix_path(the_repository, prefix, prefix_len, argv[3]);\n \ndiff --git a/t/helper/test-subprocess.c b/t/helper/test-subprocess.c\nindex 8a070e47cd..a8194d24b3 100644\n--- a/t/helper/test-subprocess.c\n+++ b/t/helper/test-subprocess.c\n@@ -9,7 +9,7 @@ int cmd__subprocess(int argc, const char **argv)\n \tstruct child_process cp = CHILD_PROCESS_INIT;\n \tint nogit = 0;\n \n-\tsetup_git_directory_gently(&nogit);\n+\tsetup_git_directory_gently(the_repository, &nogit);\n \tif (nogit)\n \t\tdie(\"No git repo found\");\n \tif (argc > 1 && !strcmp(argv[1], \"--setup-work-tree\")) {\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543629","messageId":"20260519-pks-setup-wo-the-repository-v3-14-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 14/18] setup: stop using `the_repository` in `upgrade_repository_format()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:18Z","receivedAt":"2026-05-19T09:52:52Z","isPatch":true,"body":"Stop using `the_repository` in `upgrade_repository_format()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n list-objects-filter-options.c | 2 +-\n repository.h                  | 2 +-\n setup.c                       | 6 +++---\n worktree.c                    | 2 +-\n 4 files changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/list-objects-filter-options.c b/list-objects-filter-options.c\nindex cef67e5919..bc5d98f9e6 100644\n--- a/list-objects-filter-options.c\n+++ b/list-objects-filter-options.c\n@@ -378,7 +378,7 @@ void partial_clone_register(\n \t\t\t */\n \t\t\treturn;\n \t} else {\n-\t\tif (upgrade_repository_format(1) < 0)\n+\t\tif (upgrade_repository_format(the_repository, 1) < 0)\n \t\t\tdie(_(\"unable to upgrade repository format to support partial clone\"));\n \n \t\t/* Add promisor config for the remote */\ndiff --git a/repository.h b/repository.h\nindex d391aff8ab..c3ec0f4b79 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -281,6 +281,6 @@ void repo_update_index_if_able(struct repository *, struct lock_file *);\n  * Return 1 if upgrade repository format to target_version succeeded,\n  * 0 if no upgrade is necessary, and -1 when upgrade is not possible.\n  */\n-int upgrade_repository_format(int target_version);\n+int upgrade_repository_format(struct repository *repo, int target_version);\n \n #endif /* REPOSITORY_H */\ndiff --git a/setup.c b/setup.c\nindex 5dc27caf15..ed0c14e98e 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -811,7 +811,7 @@ static int check_repository_format_gently(struct repository *repo,\n \treturn 0;\n }\n \n-int upgrade_repository_format(int target_version)\n+int upgrade_repository_format(struct repository *repo, int target_version)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n \tstruct strbuf err = STRBUF_INIT;\n@@ -819,7 +819,7 @@ int upgrade_repository_format(int target_version)\n \tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n \tint ret;\n \n-\trepo_common_path_append(the_repository, &sb, \"config\");\n+\trepo_common_path_append(repo, &sb, \"config\");\n \tread_repository_format(&repo_fmt, sb.buf);\n \tstrbuf_release(&sb);\n \n@@ -841,7 +841,7 @@ int upgrade_repository_format(int target_version)\n \t}\n \n \tstrbuf_addf(&repo_version, \"%d\", target_version);\n-\trepo_config_set(the_repository, \"core.repositoryformatversion\", repo_version.buf);\n+\trepo_config_set(repo, \"core.repositoryformatversion\", repo_version.buf);\n \n \tret = 1;\n \ndiff --git a/worktree.c b/worktree.c\nindex d874e23b4e..988be84a30 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -1104,7 +1104,7 @@ void write_worktree_linking_files(const char *dotgit, const char *gitdir,\n \tstrbuf_realpath(&repo, repo.buf, 1);\n \n \tif (use_relative_paths && !the_repository->repository_format_relative_worktrees) {\n-\t\tif (upgrade_repository_format(1) < 0)\n+\t\tif (upgrade_repository_format(the_repository, 1) < 0)\n \t\t\tdie(_(\"unable to upgrade repository format to support relative worktrees\"));\n \t\tif (repo_config_set_gently(the_repository, \"extensions.relativeWorktrees\", \"true\"))\n \t\t\tdie(_(\"unable to set extensions.relativeWorktrees setting\"));\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543630","messageId":"20260519-pks-setup-wo-the-repository-v3-13-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 13/18] setup: stop using `the_repository` in `setup_git_directory()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:17Z","receivedAt":"2026-05-19T09:52:52Z","isPatch":true,"body":"Stop using `the_repository` in `setup_git_directory()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n archive.c                                    |  2 +-\n builtin/grep.c                               |  2 +-\n builtin/hash-object.c                        |  2 +-\n builtin/merge-file.c                         |  2 +-\n builtin/rev-parse.c                          |  4 ++--\n git.c                                        |  2 +-\n http-push.c                                  |  2 +-\n scalar.c                                     |  4 ++--\n setup.c                                      |  4 ++--\n setup.h                                      |  2 +-\n t/helper/test-advise.c                       |  2 +-\n t/helper/test-bitmap.c                       |  2 +-\n t/helper/test-bloom.c                        |  2 +-\n t/helper/test-cache-tree.c                   |  2 +-\n t/helper/test-config.c                       |  2 +-\n t/helper/test-dump-cache-tree.c              |  2 +-\n t/helper/test-dump-fsmonitor.c               |  2 +-\n t/helper/test-dump-split-index.c             |  2 +-\n t/helper/test-dump-untracked-cache.c         |  2 +-\n t/helper/test-find-pack.c                    |  2 +-\n t/helper/test-fsmonitor-client.c             |  2 +-\n t/helper/test-lazy-init-name-hash.c          |  2 +-\n t/helper/test-match-trees.c                  |  2 +-\n t/helper/test-pack-deltas.c                  |  2 +-\n t/helper/test-pack-mtimes.c                  |  2 +-\n t/helper/test-partial-clone.c                |  4 +++-\n t/helper/test-path-walk.c                    |  2 +-\n t/helper/test-reach.c                        |  2 +-\n t/helper/test-read-cache.c                   |  2 +-\n t/helper/test-read-graph.c                   |  2 +-\n t/helper/test-read-midx.c                    |  2 +-\n t/helper/test-ref-store.c                    |  2 +-\n t/helper/test-revision-walking.c             |  2 +-\n t/helper/test-scrap-cache-tree.c             |  2 +-\n t/helper/test-serve-v2.c                     |  2 +-\n t/helper/test-submodule-config.c             |  2 +-\n t/helper/test-submodule-nested-repo-config.c |  2 +-\n t/helper/test-submodule.c                    | 10 +++++-----\n t/helper/test-userdiff.c                     |  2 +-\n t/helper/test-write-cache.c                  |  2 +-\n 40 files changed, 49 insertions(+), 47 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex fcd474c682..51229107a5 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -786,7 +786,7 @@ int write_archive(int argc, const char **argv, const char *prefix,\n \t\t * die ourselves; but its error message will be more specific\n \t\t * than what we could write here.\n \t\t */\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \t}\n \n \tparse_treeish_arg(argv, &args, remote);\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 679f8b567a..560133feb8 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -1064,7 +1064,7 @@ int cmd_grep(int argc,\n \t\t\tuse_index = 0;\n \t\telse\n \t\t\t/* die the same way as if we did it at the beginning */\n-\t\t\tsetup_git_directory();\n+\t\t\tsetup_git_directory(the_repository);\n \t}\n \t/* Ignore --recurse-submodules if --no-index is given or implied */\n \tif (!use_index)\ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex d7905bedc2..f306b0643f 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -100,7 +100,7 @@ int cmd_hash_object(int argc,\n \t\t\t     hash_object_usage, 0);\n \n \tif (flags & INDEX_WRITE_OBJECT)\n-\t\tprefix = setup_git_directory();\n+\t\tprefix = setup_git_directory(the_repository);\n \telse\n \t\tprefix = setup_git_directory_gently(the_repository, &nongit);\n \ndiff --git a/builtin/merge-file.c b/builtin/merge-file.c\nindex 59a9792208..8fa5765239 100644\n--- a/builtin/merge-file.c\n+++ b/builtin/merge-file.c\n@@ -110,7 +110,7 @@ int cmd_merge_file(int argc,\n \n \tif (!repo && object_id)\n \t\t/* emit the correct \"not a git repo\" error in this case */\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \n \tfor (i = 0; i < 3; i++) {\n \t\tchar *fname;\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 8fdb75413d..0a01ff7a75 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -739,7 +739,7 @@ int cmd_rev_parse(int argc,\n \n \t/* No options; just report on whether we're in a git repo or not. */\n \tif (argc == 1) {\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \t\trepo_config(the_repository, git_default_config, NULL);\n \t\treturn 0;\n \t}\n@@ -774,7 +774,7 @@ int cmd_rev_parse(int argc,\n \n \t\t/* The rest of the options require a git repository. */\n \t\tif (!did_repo_setup) {\n-\t\t\tprefix = setup_git_directory();\n+\t\t\tprefix = setup_git_directory(the_repository);\n \t\t\trepo_config(the_repository, git_default_config, NULL);\n \t\t\tdid_repo_setup = 1;\n \ndiff --git a/git.c b/git.c\nindex 2cc018fc5c..42cd5f5b3c 100644\n--- a/git.c\n+++ b/git.c\n@@ -477,7 +477,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct\n \t\trun_setup = RUN_SETUP_GENTLY;\n \n \tif (run_setup & RUN_SETUP) {\n-\t\tprefix = setup_git_directory();\n+\t\tprefix = setup_git_directory(the_repository);\n \t\tno_repo = 0;\n \t} else if (run_setup & RUN_SETUP_GENTLY) {\n \t\tprefix = setup_git_directory_gently(the_repository, &no_repo);\ndiff --git a/http-push.c b/http-push.c\nindex d143fe2845..520d6c3b6a 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1788,7 +1788,7 @@ int cmd_main(int argc, const char **argv)\n \tif (delete_branch && rs.nr != 1)\n \t\tdie(\"You must specify only one branch name when deleting a remote branch\");\n \n-\tgitdir = setup_git_directory();\n+\tgitdir = setup_git_directory(the_repository);\n \n \tmemset(remote_dir_exists, -1, 256);\n \ndiff --git a/scalar.c b/scalar.c\nindex 4efb6ac36d..a80d8ee3ff 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -58,7 +58,7 @@ static void setup_enlistment_directory(int argc, const char **argv,\n \t}\n \tstrbuf_setlen(&path, len);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (!the_repository->worktree)\n \t\tdie(_(\"Scalar enlistments require a worktree\"));\n@@ -514,7 +514,7 @@ static int cmd_clone(int argc, const char **argv)\n \t\tgoto cleanup;\n \t}\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \t/* common-main already logs `argv` */\n \ttrace2_def_repo(the_repository);\ndiff --git a/setup.c b/setup.c\nindex c12c6cbda2..5dc27caf15 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2136,9 +2136,9 @@ void check_repository_format(struct repository_format *fmt)\n  * directory is not a strict subdirectory of the work tree root. The\n  * prefix always ends with a '/' character.\n  */\n-const char *setup_git_directory(void)\n+const char *setup_git_directory(struct repository *repo)\n {\n-\treturn setup_git_directory_gently(the_repository, NULL);\n+\treturn setup_git_directory_gently(repo, NULL);\n }\n \n const char *resolve_gitdir_gently(const char *suspect, int *return_error_code)\ndiff --git a/setup.h b/setup.h\nindex 18092fbf16..b779661ce7 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -137,7 +137,7 @@ enum {\n const char *enter_repo(struct repository *repo, const char *path, unsigned flags);\n \n const char *setup_git_directory_gently(struct repository *repo, int *);\n-const char *setup_git_directory(void);\n+const char *setup_git_directory(struct repository *repo);\n char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path);\n char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);\n \ndiff --git a/t/helper/test-advise.c b/t/helper/test-advise.c\nindex 81ed93a05c..8f9db2693e 100644\n--- a/t/helper/test-advise.c\n+++ b/t/helper/test-advise.c\n@@ -11,7 +11,7 @@ int cmd__advise_if_enabled(int argc, const char **argv)\n \tif (argc != 2)\n \t\tdie(\"usage: %s <advice>\", argv[0]);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_config(the_repository, git_default_config, NULL);\n \n \t/*\ndiff --git a/t/helper/test-bitmap.c b/t/helper/test-bitmap.c\nindex 16a01669e4..d9b9a83b8f 100644\n--- a/t/helper/test-bitmap.c\n+++ b/t/helper/test-bitmap.c\n@@ -37,7 +37,7 @@ static int bitmap_dump_pseudo_merge_objects(uint32_t n)\n \n int cmd__bitmap(int argc, const char **argv)\n {\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 2 && !strcmp(argv[1], \"list-commits\"))\n \t\treturn bitmap_list_commits();\ndiff --git a/t/helper/test-bloom.c b/t/helper/test-bloom.c\nindex 3283544bd3..0c65befbf0 100644\n--- a/t/helper/test-bloom.c\n+++ b/t/helper/test-bloom.c\n@@ -52,7 +52,7 @@ static const char *const bloom_usage = \"\\n\"\n \n int cmd__bloom(int argc, const char **argv)\n {\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc < 2)\n \t\tusage(bloom_usage);\ndiff --git a/t/helper/test-cache-tree.c b/t/helper/test-cache-tree.c\nindex ff61d0ca7e..d42e260092 100644\n--- a/t/helper/test-cache-tree.c\n+++ b/t/helper/test-cache-tree.c\n@@ -33,7 +33,7 @@ int cmd__cache_tree(int argc, const char **argv)\n \t\tOPT_END()\n \t};\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \targc = parse_options(argc, argv, NULL, options, test_cache_tree_usage, 0);\n \ndiff --git a/t/helper/test-config.c b/t/helper/test-config.c\nindex 9f8cca7c48..cfb3f4b111 100644\n--- a/t/helper/test-config.c\n+++ b/t/helper/test-config.c\n@@ -102,7 +102,7 @@ int cmd__config(int argc, const char **argv)\n \t\treturn 0;\n \t}\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tgit_configset_init(&cs);\n \ndiff --git a/t/helper/test-dump-cache-tree.c b/t/helper/test-dump-cache-tree.c\nindex 3f0c7d0ed0..ccb41a4239 100644\n--- a/t/helper/test-dump-cache-tree.c\n+++ b/t/helper/test-dump-cache-tree.c\n@@ -66,7 +66,7 @@ int cmd__dump_cache_tree(int ac UNUSED, const char **av UNUSED)\n \tstruct cache_tree *another = cache_tree();\n \tint ret;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tif (repo_read_index(the_repository) < 0)\n \t\tdie(\"unable to read index file\");\n \tistate = *the_repository->index;\ndiff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c\nindex efd017ca35..c991cbbb8a 100644\n--- a/t/helper/test-dump-fsmonitor.c\n+++ b/t/helper/test-dump-fsmonitor.c\n@@ -9,7 +9,7 @@ int cmd__dump_fsmonitor(int ac UNUSED, const char **av UNUSED)\n {\n \tstruct index_state *istate = the_repository->index;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tif (do_read_index(istate, the_repository->index_file, 0) < 0)\n \t\tdie(\"unable to read index file\");\n \tif (!istate->fsmonitor_last_update) {\ndiff --git a/t/helper/test-dump-split-index.c b/t/helper/test-dump-split-index.c\nindex f855a3862c..aae0a40a74 100644\n--- a/t/helper/test-dump-split-index.c\n+++ b/t/helper/test-dump-split-index.c\n@@ -17,7 +17,7 @@ int cmd__dump_split_index(int ac UNUSED, const char **av)\n {\n \tstruct split_index *si;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tdo_read_index(the_repository->index, av[1], 1);\n \tprintf(\"own %s\\n\", oid_to_hex(&the_repository->index->oid));\ndiff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c\nindex 01a109496b..24308bd371 100644\n--- a/t/helper/test-dump-untracked-cache.c\n+++ b/t/helper/test-dump-untracked-cache.c\n@@ -54,7 +54,7 @@ int cmd__dump_untracked_cache(int ac UNUSED, const char **av UNUSED)\n \txsetenv(\"GIT_CONFIG_KEY_0\", \"core.untrackedCache\", 1);\n \txsetenv(\"GIT_CONFIG_VALUE_0\", \"keep\", 1);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tif (repo_read_index(the_repository) < 0)\n \t\tdie(\"unable to read index file\");\n \tuc = the_repository->index->untracked;\ndiff --git a/t/helper/test-find-pack.c b/t/helper/test-find-pack.c\nindex fc4b8a77b3..28d5b1fe09 100644\n--- a/t/helper/test-find-pack.c\n+++ b/t/helper/test-find-pack.c\n@@ -25,7 +25,7 @@ int cmd__find_pack(int argc, const char **argv)\n \tstruct object_id oid;\n \tstruct packed_git *p;\n \tint count = -1, actual_count = 0;\n-\tconst char *prefix = setup_git_directory();\n+\tconst char *prefix = setup_git_directory(the_repository);\n \n \tstruct option options[] = {\n \t\tOPT_INTEGER('c', \"check-count\", &count, \"expected number of packs\"),\ndiff --git a/t/helper/test-fsmonitor-client.c b/t/helper/test-fsmonitor-client.c\nindex 02bfe92e8d..dc1dff23fb 100644\n--- a/t/helper/test-fsmonitor-client.c\n+++ b/t/helper/test-fsmonitor-client.c\n@@ -210,7 +210,7 @@ int cmd__fsmonitor_client(int argc, const char **argv)\n \n \tsubcmd = argv[0];\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (!strcmp(subcmd, \"query\"))\n \t\treturn !!do_send_query(token);\ndiff --git a/t/helper/test-lazy-init-name-hash.c b/t/helper/test-lazy-init-name-hash.c\nindex 40f5df4412..e542985c94 100644\n--- a/t/helper/test-lazy-init-name-hash.c\n+++ b/t/helper/test-lazy-init-name-hash.c\n@@ -211,7 +211,7 @@ int cmd__lazy_init_name_hash(int argc, const char **argv)\n \tconst char *prefix;\n \tuint64_t avg_single, avg_multi;\n \n-\tprefix = setup_git_directory();\n+\tprefix = setup_git_directory(the_repository);\n \n \targc = parse_options(argc, argv, prefix, options, usage, 0);\n \ndiff --git a/t/helper/test-match-trees.c b/t/helper/test-match-trees.c\nindex 2ed064b971..006ce5278e 100644\n--- a/t/helper/test-match-trees.c\n+++ b/t/helper/test-match-trees.c\n@@ -13,7 +13,7 @@ int cmd__match_trees(int ac UNUSED, const char **av)\n \tstruct object_id hash1, hash2, shifted;\n \tstruct tree *one, *two;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (repo_get_oid(the_repository, av[1], &hash1))\n \t\tdie(\"cannot parse %s as an object name\", av[1]);\ndiff --git a/t/helper/test-pack-deltas.c b/t/helper/test-pack-deltas.c\nindex 4981401eaa..c493b75e02 100644\n--- a/t/helper/test-pack-deltas.c\n+++ b/t/helper/test-pack-deltas.c\n@@ -95,7 +95,7 @@ int cmd__pack_deltas(int argc, const char **argv)\n \tif (argc || num_objects < 0)\n \t\tusage_with_options(usage_str, options);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tf = hashfd(the_repository->hash_algo, 1, \"<stdout>\");\n \twrite_pack_header(f, num_objects);\ndiff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c\nindex 7a8ee1de24..b774056799 100644\n--- a/t/helper/test-pack-mtimes.c\n+++ b/t/helper/test-pack-mtimes.c\n@@ -32,7 +32,7 @@ int cmd__pack_mtimes(int argc, const char **argv)\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct packed_git *p;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc != 2)\n \t\tusage(pack_mtimes_usage);\ndiff --git a/t/helper/test-partial-clone.c b/t/helper/test-partial-clone.c\nindex d848800749..a7aab426d0 100644\n--- a/t/helper/test-partial-clone.c\n+++ b/t/helper/test-partial-clone.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"repository.h\"\n@@ -32,7 +34,7 @@ static void object_info(const char *gitdir, const char *oid_hex)\n \n int cmd__partial_clone(int argc, const char **argv)\n {\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc < 4)\n \t\tdie(\"too few arguments\");\ndiff --git a/t/helper/test-path-walk.c b/t/helper/test-path-walk.c\nindex fe63002c2b..69676b15a5 100644\n--- a/t/helper/test-path-walk.c\n+++ b/t/helper/test-path-walk.c\n@@ -89,7 +89,7 @@ int cmd__path_walk(int argc, const char **argv)\n \t\tOPT_END(),\n \t};\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trevs.repo = the_repository;\n \n \targc = parse_options(argc, argv, NULL,\ndiff --git a/t/helper/test-reach.c b/t/helper/test-reach.c\nindex 3131b54a87..5d86a96c17 100644\n--- a/t/helper/test-reach.c\n+++ b/t/helper/test-reach.c\n@@ -39,7 +39,7 @@ int cmd__reach(int ac, const char **av)\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct repository *r = the_repository;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (ac < 2)\n \t\texit(1);\ndiff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c\nindex 9ae71cefb3..6b08ba8f07 100644\n--- a/t/helper/test-read-cache.c\n+++ b/t/helper/test-read-cache.c\n@@ -19,7 +19,7 @@ int cmd__read_cache(int argc, const char **argv)\n \n \tif (argc == 2)\n \t\tcnt = strtol(argv[1], NULL, 0);\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_config(the_repository, git_default_config, NULL);\n \n \tfor (i = 0; i < cnt; i++) {\ndiff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c\nindex 6a5f64e473..9f07b9c25a 100644\n--- a/t/helper/test-read-graph.c\n+++ b/t/helper/test-read-graph.c\n@@ -76,7 +76,7 @@ int cmd__read_graph(int argc, const char **argv)\n \tstruct odb_source *source;\n \tint ret = 0;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tsource = the_repository->objects->sources;\n \n \tprepare_repo_settings(the_repository);\ndiff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c\nindex 388d29e2b5..790000fb26 100644\n--- a/t/helper/test-read-midx.c\n+++ b/t/helper/test-read-midx.c\n@@ -14,7 +14,7 @@\n static struct multi_pack_index *setup_midx(const char *object_dir)\n {\n \tstruct odb_source *source;\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \tsource = odb_find_source(the_repository->objects, object_dir);\n \tif (!source)\n \t\tsource = odb_add_to_alternates_memory(the_repository->objects,\ndiff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c\nindex 74edf2029a..3866d0aca4 100644\n--- a/t/helper/test-ref-store.c\n+++ b/t/helper/test-ref-store.c\n@@ -340,7 +340,7 @@ int cmd__ref_store(int argc UNUSED, const char **argv)\n \tconst char *func;\n \tstruct command *cmd;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \targv = get_store(argv + 1, &refs);\n \ndiff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c\nindex 071f5bd1e2..70051eeaf8 100644\n--- a/t/helper/test-revision-walking.c\n+++ b/t/helper/test-revision-walking.c\n@@ -56,7 +56,7 @@ int cmd__revision_walking(int argc, const char **argv)\n \tif (argc < 2)\n \t\treturn 1;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (!strcmp(argv[1], \"run-twice\")) {\n \t\tprintf(\"1st\\n\");\ndiff --git a/t/helper/test-scrap-cache-tree.c b/t/helper/test-scrap-cache-tree.c\nindex 64fff6e9e3..7b5ce501d9 100644\n--- a/t/helper/test-scrap-cache-tree.c\n+++ b/t/helper/test-scrap-cache-tree.c\n@@ -12,7 +12,7 @@ int cmd__scrap_cache_tree(int ac UNUSED, const char **av UNUSED)\n {\n \tstruct lock_file index_lock = LOCK_INIT;\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_hold_locked_index(the_repository, &index_lock, LOCK_DIE_ON_ERROR);\n \tif (repo_read_index(the_repository) < 0)\n \t\tdie(\"unable to read index file\");\ndiff --git a/t/helper/test-serve-v2.c b/t/helper/test-serve-v2.c\nindex 63a200b8d4..27f3ed8947 100644\n--- a/t/helper/test-serve-v2.c\n+++ b/t/helper/test-serve-v2.c\n@@ -23,7 +23,7 @@ int cmd__serve_v2(int argc, const char **argv)\n \t\t\t N_(\"exit immediately after advertising capabilities\")),\n \t\tOPT_END()\n \t};\n-\tconst char *prefix = setup_git_directory();\n+\tconst char *prefix = setup_git_directory(the_repository);\n \n \t/* ignore all unknown cmdline switches for now */\n \targc = parse_options(argc, argv, prefix, options, serve_usage,\ndiff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c\nindex cbe93f2f9e..3f30292179 100644\n--- a/t/helper/test-submodule-config.c\n+++ b/t/helper/test-submodule-config.c\n@@ -34,7 +34,7 @@ int cmd__submodule_config(int argc, const char **argv)\n \tif (my_argc % 2 != 0)\n \t\tdie_usage(argc, argv, \"Wrong number of arguments.\");\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \twhile (*arg) {\n \t\tstruct object_id commit_oid;\ndiff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c\nindex 2710341cd5..7e31d3fe47 100644\n--- a/t/helper/test-submodule-nested-repo-config.c\n+++ b/t/helper/test-submodule-nested-repo-config.c\n@@ -19,7 +19,7 @@ int cmd__submodule_nested_repo_config(int argc, const char **argv)\n \tif (argc < 3)\n \t\tdie_usage(argv, \"Wrong number of arguments.\");\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (repo_submodule_init(&subrepo, the_repository, argv[1], null_oid(the_hash_algo))) {\n \t\tdie_usage(argv, \"Submodule not found.\");\ndiff --git a/t/helper/test-submodule.c b/t/helper/test-submodule.c\nindex 0133852e1e..3c5c4c4a09 100644\n--- a/t/helper/test-submodule.c\n+++ b/t/helper/test-submodule.c\n@@ -99,7 +99,7 @@ static int cmd__submodule_is_active(int argc, const char **argv)\n \tif (argc != 1)\n \t\tusage_with_options(submodule_is_active_usage, options);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \treturn !is_submodule_active(the_repository, argv[0]);\n }\n@@ -142,7 +142,7 @@ static int cmd__submodule_config_list(int argc, const char **argv)\n \targc = parse_options(argc, argv, \"test-tools\", options, usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 2)\n \t\treturn print_config_from_gitmodules(the_repository, argv[1]);\n@@ -161,7 +161,7 @@ static int cmd__submodule_config_set(int argc, const char **argv)\n \targc = parse_options(argc, argv, \"test-tools\", options, usage,\n \t\t\t     PARSE_OPT_KEEP_ARGV0);\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \t/* Equivalent to ACTION_SET in builtin/config.c */\n \tif (argc == 3) {\n@@ -183,7 +183,7 @@ static int cmd__submodule_config_unset(int argc, const char **argv)\n \t\tNULL\n \t};\n \n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 2) {\n \t\tif (!is_writing_gitmodules_ok())\n@@ -202,7 +202,7 @@ static int cmd__submodule_config_writeable(int argc, const char **argv UNUSED)\n \t\t\"test-tool submodule config-writeable\",\n \t\tNULL\n \t};\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \n \tif (argc == 1)\n \t\treturn is_writing_gitmodules_ok() ? 0 : -1;\ndiff --git a/t/helper/test-userdiff.c b/t/helper/test-userdiff.c\nindex aa3a9894d2..fc34c589b3 100644\n--- a/t/helper/test-userdiff.c\n+++ b/t/helper/test-userdiff.c\n@@ -40,7 +40,7 @@ int cmd__userdiff(int argc, const char **argv)\n \t\treturn error(\"unknown argument %s\", argv[1]);\n \n \tif (want & USERDIFF_DRIVER_TYPE_CUSTOM) {\n-\t\tsetup_git_directory();\n+\t\tsetup_git_directory(the_repository);\n \t\trepo_config(the_repository, cmd__userdiff_config, NULL);\n \t}\n \ndiff --git a/t/helper/test-write-cache.c b/t/helper/test-write-cache.c\nindex b37dd2c5d6..98e1477c98 100644\n--- a/t/helper/test-write-cache.c\n+++ b/t/helper/test-write-cache.c\n@@ -12,7 +12,7 @@ int cmd__write_cache(int argc, const char **argv)\n \tint i, cnt = 1;\n \tif (argc == 2)\n \t\tcnt = strtol(argv[1], NULL, 0);\n-\tsetup_git_directory();\n+\tsetup_git_directory(the_repository);\n \trepo_read_index(the_repository);\n \tfor (i = 0; i < cnt; i++) {\n \t\trepo_hold_locked_index(the_repository, &index_lock,\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543631","messageId":"20260519-pks-setup-wo-the-repository-v3-15-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 15/18] setup: stop using `the_repository` in `check_repository_format()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:19Z","receivedAt":"2026-05-19T09:52:54Z","isPatch":true,"body":"Stop using `the_repository` in `check_repository_format()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nFurthermore, the function is never used outside \"setup.c\". Drop its\ndeclaration in \"setup.h\" and make it static. Note that this requires us\nto reorder the function.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n setup.c | 58 +++++++++++++++++++++++++++++++++-------------------------\n setup.h | 10 ----------\n 2 files changed, 33 insertions(+), 35 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex ed0c14e98e..406984b62c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1758,6 +1758,37 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir,\n \treturn result;\n }\n \n+/*\n+ * Check the repository format version in the path found in repo_get_git_dir(repo),\n+ * and die if it is a version we don't understand. Generally one would\n+ * set_git_dir() before calling this, and use it only for \"are we in a valid\n+ * repo?\".\n+ *\n+ * If successful and fmt is not NULL, fill fmt with data.\n+ */\n+static void check_repository_format(struct repository *repo, struct repository_format *fmt)\n+{\n+\tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n+\tif (!fmt)\n+\t\tfmt = &repo_fmt;\n+\tcheck_repository_format_gently(repo, repo_get_git_dir(repo), fmt, NULL);\n+\tstartup_info->have_repository = 1;\n+\trepo_set_hash_algo(repo, fmt->hash_algo);\n+\trepo_set_compat_hash_algo(repo, fmt->compat_hash_algo);\n+\trepo_set_ref_storage_format(repo,\n+\t\t\t\t    fmt->ref_storage_format,\n+\t\t\t\t    fmt->ref_storage_payload);\n+\trepo->repository_format_worktree_config =\n+\t\tfmt->worktree_config;\n+\trepo->repository_format_submodule_path_cfg =\n+\t\tfmt->submodule_path_cfg;\n+\trepo->repository_format_relative_worktrees =\n+\t\tfmt->relative_worktrees;\n+\trepo->repository_format_partial_clone =\n+\t\txstrdup_or_null(fmt->partial_clone);\n+\tclear_repository_format(&repo_fmt);\n+}\n+\n const char *enter_repo(struct repository *repo, const char *path, unsigned flags)\n {\n \tstatic struct strbuf validated_path = STRBUF_INIT;\n@@ -1832,7 +1863,7 @@ const char *enter_repo(struct repository *repo, const char *path, unsigned flags\n \n \tif (is_git_directory(\".\")) {\n \t\tset_git_dir(repo, \".\", 0);\n-\t\tcheck_repository_format(NULL);\n+\t\tcheck_repository_format(repo, NULL);\n \t\treturn path;\n \t}\n \n@@ -2107,29 +2138,6 @@ int git_config_perm(const char *var, const char *value)\n \treturn -(i & 0666);\n }\n \n-void check_repository_format(struct repository_format *fmt)\n-{\n-\tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n-\tif (!fmt)\n-\t\tfmt = &repo_fmt;\n-\tcheck_repository_format_gently(the_repository, repo_get_git_dir(the_repository), fmt, NULL);\n-\tstartup_info->have_repository = 1;\n-\trepo_set_hash_algo(the_repository, fmt->hash_algo);\n-\trepo_set_compat_hash_algo(the_repository, fmt->compat_hash_algo);\n-\trepo_set_ref_storage_format(the_repository,\n-\t\t\t\t    fmt->ref_storage_format,\n-\t\t\t\t    fmt->ref_storage_payload);\n-\tthe_repository->repository_format_worktree_config =\n-\t\tfmt->worktree_config;\n-\tthe_repository->repository_format_submodule_path_cfg =\n-\t\tfmt->submodule_path_cfg;\n-\tthe_repository->repository_format_relative_worktrees =\n-\t\tfmt->relative_worktrees;\n-\tthe_repository->repository_format_partial_clone =\n-\t\txstrdup_or_null(fmt->partial_clone);\n-\tclear_repository_format(&repo_fmt);\n-}\n-\n /*\n  * Returns the \"prefix\", a path to the current working directory\n  * relative to the work tree root, or NULL, if the current working\n@@ -2804,7 +2812,7 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t * config file, so this will not fail.  What we are catching\n \t * is an attempt to reinitialize new repository with an old tool.\n \t */\n-\tcheck_repository_format(&repo_fmt);\n+\tcheck_repository_format(the_repository, &repo_fmt);\n \n \trepository_format_configure(the_repository, &repo_fmt, hash, ref_storage_format);\n \ndiff --git a/setup.h b/setup.h\nindex b779661ce7..a820041af0 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -221,16 +221,6 @@ void clear_repository_format(struct repository_format *format);\n int verify_repository_format(const struct repository_format *format,\n \t\t\t     struct strbuf *err);\n \n-/*\n- * Check the repository format version in the path found in repo_get_git_dir(the_repository),\n- * and die if it is a version we don't understand. Generally one would\n- * set_git_dir() before calling this, and use it only for \"are we in a valid\n- * repo?\".\n- *\n- * If successful and fmt is not NULL, fill fmt with data.\n- */\n-void check_repository_format(struct repository_format *fmt);\n-\n const char *get_template_dir(const char *option_template);\n \n #define INIT_DB_QUIET      (1 << 0)\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543632","messageId":"20260519-pks-setup-wo-the-repository-v3-16-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 16/18] setup: stop using `the_repository` in `initialize_repository_version()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:20Z","receivedAt":"2026-05-19T09:52:55Z","isPatch":true,"body":"Stop using `the_repository` in `initialize_repository_version()` and\ninstead accept the repository as a parameter. The injection of\n`the_repository` is thus bumped one level higher, where callers now pass\nit in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c |  4 ++--\n refs.c          |  2 +-\n setup.c         | 29 +++++++++++++++--------------\n setup.h         |  3 ++-\n 4 files changed, 20 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 8844e3d481..24fe0eead5 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1229,7 +1229,7 @@ int cmd_clone(int argc,\n \t *\n \t * This is sufficient for Git commands to discover the Git directory.\n \t */\n-\tinitialize_repository_version(GIT_HASH_UNKNOWN,\n+\tinitialize_repository_version(the_repository, GIT_HASH_UNKNOWN,\n \t\t\t\t      the_repository->ref_storage_format, 1);\n \n \trefs_create_refdir_stubs(the_repository, git_dir, NULL);\n@@ -1442,7 +1442,7 @@ int cmd_clone(int argc,\n \t * ours to the same thing.\n \t */\n \thash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));\n-\tinitialize_repository_version(hash_algo, the_repository->ref_storage_format, 1);\n+\tinitialize_repository_version(the_repository, hash_algo, the_repository->ref_storage_format, 1);\n \trepo_set_hash_algo(the_repository, hash_algo);\n \tcreate_reference_database(NULL, 1);\n \ndiff --git a/refs.c b/refs.c\nindex 844785219d..c36a322f4c 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -3453,7 +3453,7 @@ int repo_migrate_ref_storage_format(struct repository *repo,\n \t * repository format so that clients will use the new ref store.\n \t * We also need to swap out the repository's main ref store.\n \t */\n-\tinitialize_repository_version(hash_algo_by_ptr(repo->hash_algo), format, 1);\n+\tinitialize_repository_version(the_repository, hash_algo_by_ptr(repo->hash_algo), format, 1);\n \n \t/*\n \t * Unset the old ref store and release it. `get_main_ref_store()` will\ndiff --git a/setup.c b/setup.c\nindex 406984b62c..e09483ba34 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2385,7 +2385,8 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree)\n \treturn 1;\n }\n \n-void initialize_repository_version(int hash_algo,\n+void initialize_repository_version(struct repository *repo,\n+\t\t\t\t   int hash_algo,\n \t\t\t\t   enum ref_storage_format ref_storage_format,\n \t\t\t\t   int reinit)\n {\n@@ -2402,35 +2403,35 @@ void initialize_repository_version(int hash_algo,\n \t */\n \tif (hash_algo != GIT_HASH_SHA1_LEGACY ||\n \t    ref_storage_format != REF_STORAGE_FORMAT_FILES ||\n-\t    the_repository->ref_storage_payload)\n+\t    repo->ref_storage_payload)\n \t\ttarget_version = GIT_REPO_VERSION_READ;\n \n \tif (hash_algo != GIT_HASH_SHA1_LEGACY && hash_algo != GIT_HASH_UNKNOWN)\n-\t\trepo_config_set(the_repository, \"extensions.objectformat\",\n+\t\trepo_config_set(repo, \"extensions.objectformat\",\n \t\t\t\thash_algos[hash_algo].name);\n \telse if (reinit)\n-\t\trepo_config_set_gently(the_repository, \"extensions.objectformat\", NULL);\n+\t\trepo_config_set_gently(repo, \"extensions.objectformat\", NULL);\n \n-\tif (the_repository->ref_storage_payload) {\n+\tif (repo->ref_storage_payload) {\n \t\tstruct strbuf ref_uri = STRBUF_INIT;\n \n \t\tstrbuf_addf(&ref_uri, \"%s://%s\",\n \t\t\t    ref_storage_format_to_name(ref_storage_format),\n-\t\t\t    the_repository->ref_storage_payload);\n-\t\trepo_config_set(the_repository, \"extensions.refstorage\", ref_uri.buf);\n+\t\t\t    repo->ref_storage_payload);\n+\t\trepo_config_set(repo, \"extensions.refstorage\", ref_uri.buf);\n \t\tstrbuf_release(&ref_uri);\n \t} else if (ref_storage_format != REF_STORAGE_FORMAT_FILES) {\n-\t\trepo_config_set(the_repository, \"extensions.refstorage\",\n+\t\trepo_config_set(repo, \"extensions.refstorage\",\n \t\t\t\tref_storage_format_to_name(ref_storage_format));\n \t} else if (reinit) {\n-\t\trepo_config_set_gently(the_repository, \"extensions.refstorage\", NULL);\n+\t\trepo_config_set_gently(repo, \"extensions.refstorage\", NULL);\n \t}\n \n \tif (reinit) {\n \t\tstruct strbuf config = STRBUF_INIT;\n \t\tstruct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;\n \n-\t\trepo_common_path_append(the_repository, &config, \"config\");\n+\t\trepo_common_path_append(repo, &config, \"config\");\n \t\tread_repository_format(&repo_fmt, config.buf);\n \n \t\tif (repo_fmt.v1_only_extensions.nr)\n@@ -2440,17 +2441,17 @@ void initialize_repository_version(int hash_algo,\n \t\tclear_repository_format(&repo_fmt);\n \t}\n \n-\trepo_config_get_bool(the_repository, \"init.defaultSubmodulePathConfig\",\n+\trepo_config_get_bool(repo, \"init.defaultSubmodulePathConfig\",\n \t\t\t     &default_submodule_path_config);\n \tif (default_submodule_path_config) {\n \t\t/* extensions.submodulepathconfig requires at least version 1 */\n \t\tif (target_version == 0)\n \t\t\ttarget_version = 1;\n-\t\trepo_config_set(the_repository, \"extensions.submodulepathconfig\", \"true\");\n+\t\trepo_config_set(repo, \"extensions.submodulepathconfig\", \"true\");\n \t}\n \n \tstrbuf_addf(&repo_version, \"%d\", target_version);\n-\trepo_config_set(the_repository, \"core.repositoryformatversion\", repo_version.buf);\n+\trepo_config_set(repo, \"core.repositoryformatversion\", repo_version.buf);\n \n \tstrbuf_release(&repo_version);\n }\n@@ -2551,7 +2552,7 @@ static int create_default_files(struct repository *repo,\n \t\tadjust_shared_perm(repo, repo_get_git_dir(repo));\n \t}\n \n-\tinitialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, reinit);\n+\tinitialize_repository_version(repo, fmt->hash_algo, fmt->ref_storage_format, reinit);\n \n \t/* Check filemode trustability */\n \trepo_git_path_replace(repo, &path, \"config\");\ndiff --git a/setup.h b/setup.h\nindex a820041af0..c33b675ccf 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -232,7 +232,8 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t    enum ref_storage_format ref_storage_format,\n \t    const char *initial_branch, int init_shared_repository,\n \t    unsigned int flags);\n-void initialize_repository_version(int hash_algo,\n+void initialize_repository_version(struct repository *repo,\n+\t\t\t\t   int hash_algo,\n \t\t\t\t   enum ref_storage_format ref_storage_format,\n \t\t\t\t   int reinit);\n void create_reference_database(const char *initial_branch, int quiet);\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543633","messageId":"20260519-pks-setup-wo-the-repository-v3-17-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 17/18] setup: stop using `the_repository` in `create_reference_database()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:21Z","receivedAt":"2026-05-19T09:52:57Z","isPatch":true,"body":"Stop using `the_repository` in `create_reference_database()` and instead\naccept the repository as a parameter. The injection of `the_repository`\nis thus bumped one level higher, where callers now pass it in\nexplicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c |  2 +-\n setup.c         | 13 +++++++------\n setup.h         |  2 +-\n 3 files changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 24fe0eead5..53a41629e6 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1444,7 +1444,7 @@ int cmd_clone(int argc,\n \thash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));\n \tinitialize_repository_version(the_repository, hash_algo, the_repository->ref_storage_format, 1);\n \trepo_set_hash_algo(the_repository, hash_algo);\n-\tcreate_reference_database(NULL, 1);\n+\tcreate_reference_database(the_repository, NULL, 1);\n \n \t/*\n \t * Before fetching from the remote, download and install bundle\ndiff --git a/setup.c b/setup.c\nindex e09483ba34..9c49319568 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2468,13 +2468,14 @@ static int is_reinit(struct repository *repo)\n \treturn ret;\n }\n \n-void create_reference_database(const char *initial_branch, int quiet)\n+void create_reference_database(struct repository *repo,\n+\t\t\t       const char *initial_branch, int quiet)\n {\n \tstruct strbuf err = STRBUF_INIT;\n \tchar *to_free = NULL;\n-\tint reinit = is_reinit(the_repository);\n+\tint reinit = is_reinit(repo);\n \n-\tif (ref_store_create_on_disk(get_main_ref_store(the_repository), 0, &err))\n+\tif (ref_store_create_on_disk(get_main_ref_store(repo), 0, &err))\n \t\tdie(\"failed to set up refs db: %s\", err.buf);\n \n \t/*\n@@ -2486,14 +2487,14 @@ void create_reference_database(const char *initial_branch, int quiet)\n \n \t\tif (!initial_branch)\n \t\t\tinitial_branch = to_free =\n-\t\t\t\trepo_default_branch_name(the_repository, quiet);\n+\t\t\t\trepo_default_branch_name(repo, quiet);\n \n \t\tref = xstrfmt(\"refs/heads/%s\", initial_branch);\n \t\tif (check_refname_format(ref, 0) < 0)\n \t\t\tdie(_(\"invalid initial branch name: '%s'\"),\n \t\t\t    initial_branch);\n \n-\t\tif (refs_update_symref(get_main_ref_store(the_repository), \"HEAD\", ref, NULL) < 0)\n+\t\tif (refs_update_symref(get_main_ref_store(repo), \"HEAD\", ref, NULL) < 0)\n \t\t\texit(1);\n \t\tfree(ref);\n \t}\n@@ -2830,7 +2831,7 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\t\t\t      &repo_fmt, init_shared_repository);\n \n \tif (!(flags & INIT_DB_SKIP_REFDB))\n-\t\tcreate_reference_database(initial_branch, flags & INIT_DB_QUIET);\n+\t\tcreate_reference_database(the_repository, initial_branch, flags & INIT_DB_QUIET);\n \tcreate_object_directory(the_repository);\n \n \tif (repo_settings_get_shared_repository(the_repository)) {\ndiff --git a/setup.h b/setup.h\nindex c33b675ccf..21737e9bd6 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -236,7 +236,7 @@ void initialize_repository_version(struct repository *repo,\n \t\t\t\t   int hash_algo,\n \t\t\t\t   enum ref_storage_format ref_storage_format,\n \t\t\t\t   int reinit);\n-void create_reference_database(const char *initial_branch, int quiet);\n+void create_reference_database(struct repository *repo, const char *initial_branch, int quiet);\n \n /*\n  * NOTE NOTE NOTE!!\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543634","messageId":"20260519-pks-setup-wo-the-repository-v3-18-a00d8ea8b07f@pks.im","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"[PATCH v3 18/18] setup: stop using `the_repository` in `init_db()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-05-19T09:52:22Z","receivedAt":"2026-05-19T09:53:00Z","isPatch":true,"body":"Stop using `the_repository` in `init_db()` and instead accept\nthe repository as a parameter. The injection of `the_repository` is thus\nbumped one level higher, where callers now pass it in explicitly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/clone.c   |  2 +-\n builtin/init-db.c |  2 +-\n setup.c           | 43 ++++++++++++++++++++++---------------------\n setup.h           |  3 ++-\n 4 files changed, 26 insertions(+), 24 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 53a41629e6..d60d1b60bc 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1186,7 +1186,7 @@ int cmd_clone(int argc,\n \t * repository, and reference backends may persist that information into\n \t * their on-disk data structures.\n \t */\n-\tinit_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,\n+\tinit_db(the_repository, git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,\n \t\tref_storage_format, NULL,\n \t\tdo_not_override_repo_unix_permissions, INIT_DB_QUIET | INIT_DB_SKIP_REFDB);\n \ndiff --git a/builtin/init-db.c b/builtin/init-db.c\nindex e626b0d8b7..c55517ad94 100644\n--- a/builtin/init-db.c\n+++ b/builtin/init-db.c\n@@ -252,7 +252,7 @@ int cmd_init_db(int argc,\n \t}\n \n \tflags |= INIT_DB_EXIST_OK;\n-\tret = init_db(git_dir, real_git_dir, template_dir, hash_algo,\n+\tret = init_db(the_repository, git_dir, real_git_dir, template_dir, hash_algo,\n \t\t      ref_storage_format, initial_branch,\n \t\t      init_shared_repository, flags);\n \ndiff --git a/setup.c b/setup.c\nindex 9c49319568..6aee839d8c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -2778,7 +2778,8 @@ static void repository_format_configure(struct repository *repo,\n \t\t\t\t    repo_fmt->ref_storage_payload);\n }\n \n-int init_db(const char *git_dir, const char *real_git_dir,\n+int init_db(struct repository *repo,\n+\t    const char *git_dir, const char *real_git_dir,\n \t    const char *template_dir, int hash,\n \t    enum ref_storage_format ref_storage_format,\n \t    const char *initial_branch,\n@@ -2798,13 +2799,13 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\tif (!exist_ok && !stat(real_git_dir, &st))\n \t\t\tdie(_(\"%s already exists\"), real_git_dir);\n \n-\t\tset_git_dir(the_repository, real_git_dir, 1);\n-\t\tgit_dir = repo_get_git_dir(the_repository);\n+\t\tset_git_dir(repo, real_git_dir, 1);\n+\t\tgit_dir = repo_get_git_dir(repo);\n \t\tseparate_git_dir(git_dir, original_git_dir);\n \t}\n \telse {\n-\t\tset_git_dir(the_repository, git_dir, 1);\n-\t\tgit_dir = repo_get_git_dir(the_repository);\n+\t\tset_git_dir(repo, git_dir, 1);\n+\t\tgit_dir = repo_get_git_dir(repo);\n \t}\n \tstartup_info->have_repository = 1;\n \n@@ -2814,27 +2815,27 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t * config file, so this will not fail.  What we are catching\n \t * is an attempt to reinitialize new repository with an old tool.\n \t */\n-\tcheck_repository_format(the_repository, &repo_fmt);\n+\tcheck_repository_format(repo, &repo_fmt);\n \n-\trepository_format_configure(the_repository, &repo_fmt, hash, ref_storage_format);\n+\trepository_format_configure(repo, &repo_fmt, hash, ref_storage_format);\n \n \t/*\n \t * Ensure `core.hidedotfiles` is processed. This must happen after we\n \t * have set up the repository format such that we can evaluate\n \t * includeIf conditions correctly in the case of re-initialization.\n \t */\n-\trepo_config(the_repository, git_default_core_config, NULL);\n+\trepo_config(repo, git_default_core_config, NULL);\n \n-\tsafe_create_dir(the_repository, git_dir, 0);\n+\tsafe_create_dir(repo, git_dir, 0);\n \n-\treinit = create_default_files(the_repository, template_dir, original_git_dir,\n+\treinit = create_default_files(repo, template_dir, original_git_dir,\n \t\t\t\t      &repo_fmt, init_shared_repository);\n \n \tif (!(flags & INIT_DB_SKIP_REFDB))\n-\t\tcreate_reference_database(the_repository, initial_branch, flags & INIT_DB_QUIET);\n-\tcreate_object_directory(the_repository);\n+\t\tcreate_reference_database(repo, initial_branch, flags & INIT_DB_QUIET);\n+\tcreate_object_directory(repo);\n \n-\tif (repo_settings_get_shared_repository(the_repository)) {\n+\tif (repo_settings_get_shared_repository(repo)) {\n \t\tchar buf[10];\n \t\t/* We do not spell \"group\" and such, so that\n \t\t * the configuration can be read by older version\n@@ -2842,29 +2843,29 @@ int init_db(const char *git_dir, const char *real_git_dir,\n \t\t * and compatibility values for PERM_GROUP and\n \t\t * PERM_EVERYBODY.\n \t\t */\n-\t\tif (repo_settings_get_shared_repository(the_repository) < 0)\n+\t\tif (repo_settings_get_shared_repository(repo) < 0)\n \t\t\t/* force to the mode value */\n-\t\t\txsnprintf(buf, sizeof(buf), \"0%o\", -repo_settings_get_shared_repository(the_repository));\n-\t\telse if (repo_settings_get_shared_repository(the_repository) == PERM_GROUP)\n+\t\t\txsnprintf(buf, sizeof(buf), \"0%o\", -repo_settings_get_shared_repository(repo));\n+\t\telse if (repo_settings_get_shared_repository(repo) == PERM_GROUP)\n \t\t\txsnprintf(buf, sizeof(buf), \"%d\", OLD_PERM_GROUP);\n-\t\telse if (repo_settings_get_shared_repository(the_repository) == PERM_EVERYBODY)\n+\t\telse if (repo_settings_get_shared_repository(repo) == PERM_EVERYBODY)\n \t\t\txsnprintf(buf, sizeof(buf), \"%d\", OLD_PERM_EVERYBODY);\n \t\telse\n \t\t\tBUG(\"invalid value for shared_repository\");\n-\t\trepo_config_set(the_repository, \"core.sharedrepository\", buf);\n-\t\trepo_config_set(the_repository, \"receive.denyNonFastforwards\", \"true\");\n+\t\trepo_config_set(repo, \"core.sharedrepository\", buf);\n+\t\trepo_config_set(repo, \"receive.denyNonFastforwards\", \"true\");\n \t}\n \n \tif (!(flags & INIT_DB_QUIET)) {\n \t\tint len = strlen(git_dir);\n \n \t\tif (reinit)\n-\t\t\tprintf(repo_settings_get_shared_repository(the_repository)\n+\t\t\tprintf(repo_settings_get_shared_repository(repo)\n \t\t\t       ? _(\"Reinitialized existing shared Git repository in %s%s\\n\")\n \t\t\t       : _(\"Reinitialized existing Git repository in %s%s\\n\"),\n \t\t\t       git_dir, len && git_dir[len-1] != '/' ? \"/\" : \"\");\n \t\telse\n-\t\t\tprintf(repo_settings_get_shared_repository(the_repository)\n+\t\t\tprintf(repo_settings_get_shared_repository(repo)\n \t\t\t       ? _(\"Initialized empty shared Git repository in %s%s\\n\")\n \t\t\t       : _(\"Initialized empty Git repository in %s%s\\n\"),\n \t\t\t       git_dir, len && git_dir[len-1] != '/' ? \"/\" : \"\");\ndiff --git a/setup.h b/setup.h\nindex 21737e9bd6..9409326fe4 100644\n--- a/setup.h\n+++ b/setup.h\n@@ -227,7 +227,8 @@ const char *get_template_dir(const char *option_template);\n #define INIT_DB_EXIST_OK   (1 << 1)\n #define INIT_DB_SKIP_REFDB (1 << 2)\n \n-int init_db(const char *git_dir, const char *real_git_dir,\n+int init_db(struct repository *repo,\n+\t    const char *git_dir, const char *real_git_dir,\n \t    const char *template_dir, int hash_algo,\n \t    enum ref_storage_format ref_storage_format,\n \t    const char *initial_branch, int init_shared_repository,\n\n-- \n2.54.0.771.g3ed373ac14.dirty\n\n"},{"id":"543725","messageId":"xmqqse7m4uz8.fsf@gitster.g","threadId":"65515","inReplyTo":"20260519-pks-setup-wo-the-repository-v3-0-a00d8ea8b07f@pks.im","subject":"Re: [PATCH v3 00/18] setup: drop uses of `the_repository`","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-05-20T03:31:55Z","receivedAt":"2026-05-20T03:31:58Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Changes in v3:\n>   - Reverse the order of the commits that refactor `is_inside_gitdir()`\n>     and `is_inside_work_tree()` and clarify the logic around why we do\n>     (or do not) have to use realpath(3p). The code is ultimately not\n>     changed though, we still resolve the realpath for both even though\n>     it's not strictly necessary to do so for the working tree.\n>   - Link to v2: https://patch.msgid.link/20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im\n\nLooking good.  Let me mark the topic for 'next'.\n\nThanks.\n"}]}