From 9bef2cf33111dc844e46a8a19c266320774f4bd6 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 11 Jun 2026 08:44:39 +0200 Subject: [PATCH 1/7] builtin/init: stop modifying global `git_work_tree_cfg` variable When executing git-init(1) we need to figure out the final location of the worktree. This location can be configured in a couple of ways: via an environment variable, via the preexisting "core.worktree" config in case we're reinitializing, or implicitly when reinitializing a non-bare repository. When checking for the worktree location in "builtin/init-db.c" we populate any potentially-discovered value both by setting the global `git_work_tree_cfg` variable and via `set_git_work_tree()`, which ultimately ends up modifying `struct repository::worktree`. Modifying `git_work_tree_cfg` is unnecessary though: we configure the worktree in `create_default_files()`, and that function derives the worktree location via `repo_get_work_tree()`. Consequently, propagating the worktree via `set_git_work_tree()` is sufficient. Stop munging `git_work_tree_cfg` and make it file-local to "setup.c" and function-local to `cmd_init_db()`. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/init-db.c | 4 ++++ environment.c | 3 --- environment.h | 1 - setup.c | 3 +++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/builtin/init-db.c b/builtin/init-db.c index c55517ad94..01bc27904e 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -229,6 +229,8 @@ int cmd_init_db(int argc, if (!is_bare_repository_cfg) { const char *git_dir_parent = strrchr(git_dir, '/'); + char *git_work_tree_cfg = NULL; + if (git_dir_parent) { char *rel = xstrndup(git_dir, git_dir_parent - git_dir); git_work_tree_cfg = real_pathdup(rel, 1); @@ -243,6 +245,8 @@ int cmd_init_db(int argc, if (access(repo_get_work_tree(the_repository), X_OK)) die_errno (_("Cannot access work tree '%s'"), repo_get_work_tree(the_repository)); + + free(git_work_tree_cfg); } else { if (real_git_dir) diff --git a/environment.c b/environment.c index fc3ed8bb1c..4e86335f25 100644 --- a/environment.c +++ b/environment.c @@ -100,9 +100,6 @@ int auto_comment_line_char; bool warn_on_auto_comment_char; #endif /* !WITH_BREAKING_CHANGES */ -/* This is set by setup_git_directory_gently() and/or git_default_config() */ -char *git_work_tree_cfg; - /* * Repository-local GIT_* environment variables; see environment.h for details. */ diff --git a/environment.h b/environment.h index ccfcf37bfb..5d6e4e6c1b 100644 --- a/environment.h +++ b/environment.h @@ -149,7 +149,6 @@ int have_git_dir(void); extern int is_bare_repository_cfg; int is_bare_repository(void); -extern char *git_work_tree_cfg; /* Environment bits from configuration mechanism */ extern int trust_executable_bit; diff --git a/setup.c b/setup.c index b4652651df..52228b42a1 100644 --- a/setup.c +++ b/setup.c @@ -31,6 +31,9 @@ enum allowed_bare_repo { ALLOWED_BARE_REPO_ALL, }; +/* This is set by setup_git_directory_gently() and/or git_default_config() */ +static char *git_work_tree_cfg; + static struct startup_info the_startup_info; struct startup_info *startup_info = &the_startup_info; const char *tmp_original_cwd; From 65eb5b989aa6d7f764d097c6759f6b6189eb0d27 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 11 Jun 2026 08:44:40 +0200 Subject: [PATCH 2/7] builtin/init: simplify logic to configure worktree In the preceding commit we have stopped modifying the global `git_work_tree_cfg` variable. With this change there's now some code paths where we end up setting the local `git_work_tree_cfg` variable, but without actually using the value for anything. Refactor the code a bit so that we only set the worktree configuration in case it's actually needed. Furthermore, reflow it a bit to make the code easier to follow. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/init-db.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/builtin/init-db.c b/builtin/init-db.c index 01bc27904e..b4343c2804 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -229,24 +229,29 @@ int cmd_init_db(int argc, if (!is_bare_repository_cfg) { const char *git_dir_parent = strrchr(git_dir, '/'); - char *git_work_tree_cfg = NULL; - if (git_dir_parent) { - char *rel = xstrndup(git_dir, git_dir_parent - git_dir); - git_work_tree_cfg = real_pathdup(rel, 1); - free(rel); - } - if (!git_work_tree_cfg) - git_work_tree_cfg = xgetcwd(); - if (work_tree) + if (work_tree) { set_git_work_tree(the_repository, work_tree); - else - set_git_work_tree(the_repository, git_work_tree_cfg); + } else { + char *work_tree_cfg = NULL; + + if (git_dir_parent) { + char *rel = xstrndup(git_dir, git_dir_parent - git_dir); + work_tree_cfg = real_pathdup(rel, 1); + free(rel); + } + + if (!work_tree_cfg) + work_tree_cfg = xgetcwd(); + + set_git_work_tree(the_repository, work_tree_cfg); + + free(work_tree_cfg); + } + if (access(repo_get_work_tree(the_repository), X_OK)) die_errno (_("Cannot access work tree '%s'"), repo_get_work_tree(the_repository)); - - free(git_work_tree_cfg); } else { if (real_git_dir) From 85f5f504f046bccf86b78ba02064a4b013d7264f Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 11 Jun 2026 08:44:41 +0200 Subject: [PATCH 3/7] setup: remove global `git_work_tree_cfg` variable The global `git_work_tree_cfg` variable used to be modified by both "setup.c" and by "builtin/init-db.c". We have refactored the latter user to not use that variable at all anymore in a preceding commit, which makes "setup.c" the only remaining user. Even for "setup.c" it is unnecessary though, as we only ever set it to the value we have stored in the discovered repository format. The consequence is that we only ever set it in case we already have it set to the same value in our discovered repository format, which makes it redundant. Refactor the code so that we instead use the worktree configuration as discovered via the repository format. Drop the global variable. Note that in `check_repository_format_gently()` we now have to free the candidate work tree variable. This change is required to retain previous semantics: before we essentially had an implicit `else` branch where we set `git_work_tree_cfg = NULL`, but we were able to elide that branch because we already knew that it would be `NULL` anyway. Now that we use the candidate work tree directly to populate the repository's work tree though we have to clear it to retain those semantics. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- setup.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/setup.c b/setup.c index 52228b42a1..71fc6b33da 100644 --- a/setup.c +++ b/setup.c @@ -31,9 +31,6 @@ enum allowed_bare_repo { ALLOWED_BARE_REPO_ALL, }; -/* This is set by setup_git_directory_gently() and/or git_default_config() */ -static char *git_work_tree_cfg; - static struct startup_info the_startup_info; struct startup_info *startup_info = &the_startup_info; const char *tmp_original_cwd; @@ -799,13 +796,10 @@ static int check_repository_format_gently(const char *gitdir, } if (!has_common) { - if (candidate->is_bare != -1) { + if (candidate->is_bare != -1) is_bare_repository_cfg = candidate->is_bare; - } - if (candidate->work_tree) { - free(git_work_tree_cfg); - git_work_tree_cfg = xstrdup(candidate->work_tree); - } + } else { + FREE_AND_NULL(candidate->work_tree); } return 0; @@ -1145,7 +1139,7 @@ static const char *setup_explicit_git_dir(struct repository *repo, if (work_tree_env) set_git_work_tree(repo, work_tree_env); else if (is_bare_repository_cfg > 0) { - if (git_work_tree_cfg) { + if (repo_fmt->work_tree) { /* #22.2, #30 */ warning("core.bare and core.worktree do not make sense"); repo->worktree_config_is_bogus = true; @@ -1156,15 +1150,15 @@ static const char *setup_explicit_git_dir(struct repository *repo, free(gitfile); return NULL; } - else if (git_work_tree_cfg) { /* #6, #14 */ - if (is_absolute_path(git_work_tree_cfg)) - set_git_work_tree(repo, git_work_tree_cfg); + else if (repo_fmt->work_tree) { /* #6, #14 */ + if (is_absolute_path(repo_fmt->work_tree)) + set_git_work_tree(repo, repo_fmt->work_tree); else { char *core_worktree; if (chdir(gitdirenv)) die_errno(_("cannot chdir to '%s'"), gitdirenv); - if (chdir(git_work_tree_cfg)) - die_errno(_("cannot chdir to '%s'"), git_work_tree_cfg); + if (chdir(repo_fmt->work_tree)) + die_errno(_("cannot chdir to '%s'"), repo_fmt->work_tree); core_worktree = xgetcwd(); if (chdir(cwd->buf)) die_errno(_("cannot come back to cwd")); @@ -1217,7 +1211,7 @@ static const char *setup_discovered_git_dir(struct repository *repo, return NULL; /* --work-tree is set without --git-dir; use discovered one */ - if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) { + if (getenv(GIT_WORK_TREE_ENVIRONMENT) || repo_fmt->work_tree) { char *to_free = NULL; const char *ret; @@ -1267,7 +1261,7 @@ static const char *setup_bare_git_dir(struct repository *repo, setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1); /* --work-tree is set without --git-dir; use discovered one */ - if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) { + if (getenv(GIT_WORK_TREE_ENVIRONMENT) || repo_fmt->work_tree) { static const char *gitdir; gitdir = offset == cwd->len ? "." : xmemdupz(cwd->buf, offset); From f12d73132ea23788167a6b21fad63d85c76fa863 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 11 Jun 2026 08:44:42 +0200 Subject: [PATCH 4/7] builtin/init: stop modifying `is_bare_repository_cfg` We're modifying `is_bare_repository_cfg` in "builtin/init.c" to indicate whether the newly created repository is supposed to be a bare repository or not. This is ultimately unnecessary though: when initializing the repository in `init_db()` we eventually set `is_bare_repository_cfg = !work_tree`, so all that matters is whether or not we have a working tree configured, and the working tree is set up in the non-bare in "builtin/init.c". Stop modifying the global variable in "builtin/init.c" in favor of a local variable. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/init-db.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/builtin/init-db.c b/builtin/init-db.c index b4343c2804..52aa92fb0a 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -81,6 +81,7 @@ int cmd_init_db(int argc, const char *template_dir = NULL; char *template_dir_to_free = NULL; unsigned int flags = 0; + int bare = is_bare_repository_cfg; const char *object_format = NULL; const char *ref_format = NULL; const char *initial_branch = NULL; @@ -90,7 +91,7 @@ int cmd_init_db(int argc, const struct option init_db_options[] = { OPT_STRING(0, "template", &template_dir, N_("template-directory"), N_("directory from which templates will be used")), - OPT_SET_INT(0, "bare", &is_bare_repository_cfg, + OPT_SET_INT(0, "bare", &bare, N_("create a bare repository"), 1), { .type = OPTION_CALLBACK, @@ -116,7 +117,7 @@ int cmd_init_db(int argc, argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0); - if (real_git_dir && is_bare_repository_cfg == 1) + if (real_git_dir && bare == 1) die(_("options '%s' and '%s' cannot be used together"), "--separate-git-dir", "--bare"); if (real_git_dir && !is_absolute_path(real_git_dir)) @@ -160,7 +161,7 @@ int cmd_init_db(int argc, } else if (0 < argc) { usage(init_db_usage[0]); } - if (is_bare_repository_cfg == 1) { + if (bare == 1) { char *cwd = xgetcwd(); setenv(GIT_DIR_ENVIRONMENT, cwd, argc > 0); free(cwd); @@ -187,7 +188,7 @@ int cmd_init_db(int argc, */ git_dir = xstrdup_or_null(getenv(GIT_DIR_ENVIRONMENT)); work_tree = xstrdup_or_null(getenv(GIT_WORK_TREE_ENVIRONMENT)); - if ((!git_dir || is_bare_repository_cfg == 1) && work_tree) + if ((!git_dir || bare == 1) && work_tree) die(_("%s (or --work-tree=) not allowed without " "specifying %s (or --git-dir=)"), GIT_WORK_TREE_ENVIRONMENT, @@ -224,10 +225,10 @@ int cmd_init_db(int argc, strbuf_release(&sb); } - if (is_bare_repository_cfg < 0) - is_bare_repository_cfg = guess_repository_type(git_dir); + if (bare < 0) + bare = guess_repository_type(git_dir); - if (!is_bare_repository_cfg) { + if (!bare) { const char *git_dir_parent = strrchr(git_dir, '/'); if (work_tree) { From 7ff3a5895b6bf4c14d361e4c845d2de7e4006259 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 11 Jun 2026 08:44:43 +0200 Subject: [PATCH 5/7] environment: split up concerns of `is_bare_repository_cfg` The `is_bare_repository_cfg` variable tracks two different pieces of information: - It tracks whether the user has invoked git with the "--bare" flag, which makes us treat any discovered Git repository as if it was a bare repository. - Otherwise it tracks whether the discovered `the_repository` is bare. This makes the flag extremely confusing and creates a bit of a challenge when handling multiple repositories in the same process. Split up the concerns of this variable into two pieces: - `startup_info.force_bare_repository` tracks whether the user has passed the "--bare" flag. This is used as a hint to treat newly set up repositories as bare regardless of whether or not they have a worktree. - `struct repository::bare_cfg` tracks whether or not a repository is considered bare. This takes into account both whether the user has passed "--bare" and the discovered state of the repository itself. Whether or not a repository is bare is now resolved when checking the repository's format, and is then later applied to the repository itself via `apply_repository_format()`. This enables a subsequent change where we make `is_bare_repository()` not depend on global state anymore. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/init-db.c | 2 +- environment.c | 5 ++--- environment.h | 1 - git.c | 2 +- repository.c | 1 + repository.h | 7 +++++++ setup.c | 27 ++++++++++++++++++++------- setup.h | 6 ++++++ worktree.c | 2 +- 9 files changed, 39 insertions(+), 14 deletions(-) diff --git a/builtin/init-db.c b/builtin/init-db.c index 52aa92fb0a..566732c9f4 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -81,7 +81,7 @@ int cmd_init_db(int argc, const char *template_dir = NULL; char *template_dir_to_free = NULL; unsigned int flags = 0; - int bare = is_bare_repository_cfg; + int bare = startup_info->force_bare_repository ? 1 : -1; const char *object_format = NULL; const char *ref_format = NULL; const char *initial_branch = NULL; diff --git a/environment.c b/environment.c index 4e86335f25..9d7c908c55 100644 --- a/environment.c +++ b/environment.c @@ -48,7 +48,6 @@ int has_symlinks = 1; int minimum_abbrev = 4, default_abbrev = -1; int ignore_case; int assume_unchanged; -int is_bare_repository_cfg = -1; /* unspecified */ int warn_on_object_refname_ambiguity = 1; char *git_commit_encoding; char *git_log_output_encoding; @@ -136,7 +135,7 @@ const char *getenv_safe(struct strvec *argv, const char *name) int is_bare_repository(void) { /* if core.bare is not 'false', let's see if there is a work tree */ - return is_bare_repository_cfg && !repo_get_work_tree(the_repository); + return the_repository->bare_cfg && !repo_get_work_tree(the_repository); } int have_git_dir(void) @@ -342,7 +341,7 @@ int git_default_core_config(const char *var, const char *value, } if (!strcmp(var, "core.bare")) { - is_bare_repository_cfg = git_config_bool(var, value); + the_repository->bare_cfg = git_config_bool(var, value); return 0; } diff --git a/environment.h b/environment.h index 5d6e4e6c1b..afb5bcf197 100644 --- a/environment.h +++ b/environment.h @@ -147,7 +147,6 @@ void repo_config_values_init(struct repo_config_values *cfg); */ int have_git_dir(void); -extern int is_bare_repository_cfg; int is_bare_repository(void); /* Environment bits from configuration mechanism */ diff --git a/git.c b/git.c index 36f08891ef..387eabe38c 100644 --- a/git.c +++ b/git.c @@ -255,7 +255,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--bare")) { char *cwd = xgetcwd(); - is_bare_repository_cfg = 1; + startup_info->force_bare_repository = true; setenv(GIT_DIR_ENVIRONMENT, cwd, 0); free(cwd); setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1); diff --git a/repository.c b/repository.c index 187dd471c4..c1e91eb0da 100644 --- a/repository.c +++ b/repository.c @@ -73,6 +73,7 @@ void initialize_repository(struct repository *repo) ALLOC_ARRAY(repo->index, 1); index_state_init(repo->index, repo); repo->check_deprecated_config = true; + repo->bare_cfg = -1; repo_config_values_init(&repo->config_values_private_); /* diff --git a/repository.h b/repository.h index 36e2db2633..7d649e32e7 100644 --- a/repository.h +++ b/repository.h @@ -117,6 +117,13 @@ struct repository { bool worktree_initialized; bool worktree_config_is_bogus; + /* + * Whether the repository is bare, as set by "core.bare" config or + * inferred during repository discovery. -1 means unset/unknown, 0 + * means non-bare, 1 means bare. + */ + int bare_cfg; + /* * Path from the root of the top-level superproject down to this * repository. This is only non-NULL if the repository is initialized diff --git a/setup.c b/setup.c index 71fc6b33da..32f14a8688 100644 --- a/setup.c +++ b/setup.c @@ -795,10 +795,22 @@ static int check_repository_format_gently(const char *gitdir, has_common = 0; } - if (!has_common) { - if (candidate->is_bare != -1) - is_bare_repository_cfg = candidate->is_bare; - } else { + if (startup_info->force_bare_repository) { + candidate->is_bare = 1; + FREE_AND_NULL(candidate->work_tree); + } else if (has_common) { + /* + * When sharing a common dir with another repository (e.g. a + * linked worktree), do not let this repository's config + * dictate bareness; it is inherited from the main worktree. + */ + candidate->is_bare = -1; + + /* + * Furthermore, "core.worktree" is supposed to be ignored when + * we have a commondir configured, unless it comes from the + * per-worktree configuration. + */ FREE_AND_NULL(candidate->work_tree); } @@ -1138,7 +1150,7 @@ static const char *setup_explicit_git_dir(struct repository *repo, /* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */ if (work_tree_env) set_git_work_tree(repo, work_tree_env); - else if (is_bare_repository_cfg > 0) { + else if (repo_fmt->is_bare > 0) { if (repo_fmt->work_tree) { /* #22.2, #30 */ warning("core.bare and core.worktree do not make sense"); @@ -1225,7 +1237,7 @@ static const char *setup_discovered_git_dir(struct repository *repo, } /* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */ - if (is_bare_repository_cfg > 0) { + if (repo_fmt->is_bare > 0) { set_git_dir(repo, gitdir, (offset != cwd->len)); if (chdir(cwd->buf)) die_errno(_("cannot come back to cwd")); @@ -1762,6 +1774,7 @@ int apply_repository_format(struct repository *repo, alternate_object_directories = xstrdup_or_null(getenv(ALTERNATE_DB_ENVIRONMENT)); } + repo->bare_cfg = format->is_bare; repo_set_hash_algo(repo, format->hash_algo); repo->objects = odb_new(repo, object_directory, alternate_object_directories); @@ -2571,7 +2584,7 @@ static int create_default_files(struct repository *repo, repo_settings_set_shared_repository(repo, init_shared_repository); - is_bare_repository_cfg = !work_tree; + repo->bare_cfg = !work_tree; /* * We would have created the above under user's umask -- under diff --git a/setup.h b/setup.h index 705d1d6ff7..b9fd96bea6 100644 --- a/setup.h +++ b/setup.h @@ -292,6 +292,12 @@ enum sharedrepo { int git_config_perm(const char *var, const char *value); struct startup_info { + /* + * Whether the user is asking us to treat the repository as bare via + * `git --bare`, even if it's not. + */ + bool force_bare_repository; + int have_repository; const char *prefix; const char *original_cwd; diff --git a/worktree.c b/worktree.c index 97eddc3916..7d70f2c1da 100644 --- a/worktree.c +++ b/worktree.c @@ -123,7 +123,7 @@ static struct worktree *get_main_worktree(int skip_reading_head) worktree->repo = the_repository; worktree->path = strbuf_detach(&worktree_path, NULL); worktree->is_current = is_current_worktree(worktree); - worktree->is_bare = (is_bare_repository_cfg == 1) || + worktree->is_bare = (the_repository->bare_cfg == 1) || is_bare_repository() || /* * When in a secondary worktree we have to also verify if the main From 2e1d55626f06be7b9374c0a6f579959d750f0cfb Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 11 Jun 2026 08:44:44 +0200 Subject: [PATCH 6/7] environment: stop using `the_repository` in `is_bare_repository()` Refactor `is_bare_repository()` to take in a repository parameter so that we no longer depend on `the_repository`. Adjust callers accordingly. Furthermore, move the function outside of the declarations that are only available when `USE_THE_REPOSITORY_VARIABLE` is set, as it no longer depends on that variable. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- attr.c | 4 ++-- builtin/bisect.c | 2 +- builtin/blame.c | 2 +- builtin/check-attr.c | 2 +- builtin/fetch.c | 2 +- builtin/gc.c | 2 +- builtin/history.c | 2 +- builtin/repack.c | 2 +- builtin/repo.c | 2 +- builtin/reset.c | 2 +- builtin/rev-parse.c | 2 +- environment.c | 4 ++-- environment.h | 4 ++-- mailmap.c | 4 ++-- refs/files-backend.c | 2 +- refs/reftable-backend.c | 2 +- setup.c | 2 +- transport.c | 4 ++-- worktree.c | 2 +- 19 files changed, 24 insertions(+), 24 deletions(-) diff --git a/attr.c b/attr.c index 75369547b3..04cb284954 100644 --- a/attr.c +++ b/attr.c @@ -681,7 +681,7 @@ static enum git_attr_direction direction; void git_attr_set_direction(enum git_attr_direction new_direction) { - if (is_bare_repository() && new_direction != GIT_ATTR_INDEX) + if (is_bare_repository(the_repository) && new_direction != GIT_ATTR_INDEX) BUG("non-INDEX attr direction in a bare repo"); if (new_direction != direction) @@ -848,7 +848,7 @@ static struct attr_stack *read_attr(struct index_state *istate, res = read_attr_from_index(istate, path, flags); } else if (tree_oid) { res = read_attr_from_blob(istate, tree_oid, path, flags); - } else if (!is_bare_repository()) { + } else if (!is_bare_repository(the_repository)) { if (direction == GIT_ATTR_CHECKOUT) { res = read_attr_from_index(istate, path, flags); if (!res) diff --git a/builtin/bisect.c b/builtin/bisect.c index e7c2d2f3bb..798e28f501 100644 --- a/builtin/bisect.c +++ b/builtin/bisect.c @@ -724,7 +724,7 @@ static enum bisect_error bisect_start(struct bisect_terms *terms, int argc, struct object_id oid; const char *head; - if (is_bare_repository()) + if (is_bare_repository(the_repository)) no_checkout = 1; /* diff --git a/builtin/blame.c b/builtin/blame.c index ffbd3ce5c5..553f4cb780 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1163,7 +1163,7 @@ parse_done: revs.disable_stdin = 1; setup_revisions(argc, argv, &revs, NULL); - if (!revs.pending.nr && is_bare_repository()) { + if (!revs.pending.nr && is_bare_repository(the_repository)) { struct commit *head_commit; struct object_id head_oid; diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 98f64d5b92..217d83ea7d 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -116,7 +116,7 @@ int cmd_check_attr(int argc, struct object_id initialized_oid; int cnt, i, doubledash, filei; - if (!is_bare_repository()) + if (!is_bare_repository(the_repository)) setup_work_tree(the_repository); repo_config(the_repository, git_default_config, NULL); diff --git a/builtin/fetch.c b/builtin/fetch.c index c1d7c672f4..44b8c70da1 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1764,7 +1764,7 @@ static int set_head(const struct ref *remote_refs, struct remote *remote) if (!head_name) goto cleanup; - baremirror = is_bare_repository() && remote->mirror; + baremirror = is_bare_repository(the_repository) && remote->mirror; create_only = follow_remote_head == FOLLOW_REMOTE_ALWAYS ? 0 : !baremirror; if (baremirror) { strbuf_addstr(&b_head, "HEAD"); diff --git a/builtin/gc.c b/builtin/gc.c index 84a66d3240..61da30de9f 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -902,7 +902,7 @@ int cmd_gc(int argc, die(_("failed to parse gc.logExpiry value %s"), cfg.gc_log_expire); if (cfg.pack_refs < 0) - cfg.pack_refs = !is_bare_repository(); + cfg.pack_refs = !is_bare_repository(the_repository); argc = parse_options(argc, argv, prefix, builtin_gc_options, builtin_gc_usage, 0); diff --git a/builtin/history.c b/builtin/history.c index 091465a59e..fd83de8265 100644 --- a/builtin/history.c +++ b/builtin/history.c @@ -525,7 +525,7 @@ static int cmd_history_fixup(int argc, if (action == REF_ACTION_DEFAULT) action = REF_ACTION_BRANCHES; - if (is_bare_repository()) { + if (is_bare_repository(repo)) { ret = error(_("cannot run fixup in a bare repository")); goto out; } diff --git a/builtin/repack.c b/builtin/repack.c index 1524a9c13a..bbc6f51639 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -265,7 +265,7 @@ int cmd_repack(int argc, if (write_bitmaps < 0) { if (write_midx == REPACK_WRITE_MIDX_NONE && - (!(pack_everything & ALL_INTO_ONE) || !is_bare_repository())) + (!(pack_everything & ALL_INTO_ONE) || !is_bare_repository(the_repository))) write_bitmaps = 0; } if (po_args.pack_kept_objects < 0) diff --git a/builtin/repo.c b/builtin/repo.c index 71a5c1c29c..34e96514bc 100644 --- a/builtin/repo.c +++ b/builtin/repo.c @@ -58,7 +58,7 @@ struct repo_info_field { static int get_layout_bare(struct repository *repo UNUSED, struct strbuf *buf) { - strbuf_addstr(buf, is_bare_repository() ? "true" : "false"); + strbuf_addstr(buf, is_bare_repository(the_repository) ? "true" : "false"); return 0; } diff --git a/builtin/reset.c b/builtin/reset.c index 3be6bd0121..78e69bd84b 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -470,7 +470,7 @@ int cmd_reset(int argc, if (reset_type != SOFT && (reset_type != MIXED || repo_get_work_tree(the_repository))) setup_work_tree(the_repository); - if (reset_type == MIXED && is_bare_repository()) + if (reset_type == MIXED && is_bare_repository(the_repository)) die(_("%s reset is not allowed in a bare repository"), _(reset_type_names[reset_type])); diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index bb882678fe..090e5cfbb0 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -1084,7 +1084,7 @@ int cmd_rev_parse(int argc, continue; } if (!strcmp(arg, "--is-bare-repository")) { - printf("%s\n", is_bare_repository() ? "true" + printf("%s\n", is_bare_repository(the_repository) ? "true" : "false"); continue; } diff --git a/environment.c b/environment.c index 9d7c908c55..bf20953415 100644 --- a/environment.c +++ b/environment.c @@ -132,10 +132,10 @@ const char *getenv_safe(struct strvec *argv, const char *name) return argv->v[argv->nr - 1]; } -int is_bare_repository(void) +int is_bare_repository(struct repository *repo) { /* if core.bare is not 'false', let's see if there is a work tree */ - return the_repository->bare_cfg && !repo_get_work_tree(the_repository); + return repo->bare_cfg && !repo_get_work_tree(repo); } int have_git_dir(void) diff --git a/environment.h b/environment.h index afb5bcf197..164a55df2c 100644 --- a/environment.h +++ b/environment.h @@ -125,6 +125,8 @@ int git_default_core_config(const char *var, const char *value, void repo_config_values_init(struct repo_config_values *cfg); +int is_bare_repository(struct repository *repo); + /* * TODO: All the below state either explicitly or implicitly relies on * `the_repository`. We should eventually get rid of these and make the @@ -147,8 +149,6 @@ void repo_config_values_init(struct repo_config_values *cfg); */ int have_git_dir(void); -int is_bare_repository(void); - /* Environment bits from configuration mechanism */ extern int trust_executable_bit; extern int trust_ctime; diff --git a/mailmap.c b/mailmap.c index 3b2691781d..7d8590cdd6 100644 --- a/mailmap.c +++ b/mailmap.c @@ -219,10 +219,10 @@ int read_mailmap(struct repository *repo, struct string_list *map) map->strdup_strings = 1; map->cmp = namemap_cmp; - if (!mailmap_blob && is_bare_repository()) + if (!mailmap_blob && is_bare_repository(the_repository)) mailmap_blob = xstrdup("HEAD:.mailmap"); - if (!startup_info->have_repository || !is_bare_repository()) + if (!startup_info->have_repository || !is_bare_repository(the_repository)) err |= read_mailmap_file(map, ".mailmap", startup_info->have_repository ? MAILMAP_NOFOLLOW : 0); diff --git a/refs/files-backend.c b/refs/files-backend.c index a4c7858787..2b27091484 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1865,7 +1865,7 @@ static int log_ref_setup(struct files_ref_store *refs, char *logfile; if (log_refs_cfg == LOG_REFS_UNSET) - log_refs_cfg = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL; + log_refs_cfg = is_bare_repository(the_repository) ? LOG_REFS_NONE : LOG_REFS_NORMAL; files_reflog_path(refs, &logfile_sb, refname); logfile = strbuf_detach(&logfile_sb, NULL); diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 4ae22922de..101ef29ac8 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -288,7 +288,7 @@ static int should_write_log(struct reftable_ref_store *refs, const char *refname { enum log_refs_config log_refs_cfg = refs->log_all_ref_updates; if (log_refs_cfg == LOG_REFS_UNSET) - log_refs_cfg = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL; + log_refs_cfg = is_bare_repository(the_repository) ? LOG_REFS_NONE : LOG_REFS_NORMAL; switch (log_refs_cfg) { case LOG_REFS_NONE: diff --git a/setup.c b/setup.c index 32f14a8688..e6db80ab07 100644 --- a/setup.c +++ b/setup.c @@ -2610,7 +2610,7 @@ static int create_default_files(struct repository *repo, } repo_config_set(repo, "core.filemode", filemode ? "true" : "false"); - if (is_bare_repository()) + if (is_bare_repository(the_repository)) repo_config_set(repo, "core.bare", "true"); else { repo_config_set(repo, "core.bare", "false"); diff --git a/transport.c b/transport.c index 0f5ec30247..fc144f0aed 100644 --- a/transport.c +++ b/transport.c @@ -1482,7 +1482,7 @@ int transport_push(struct repository *r, if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND | TRANSPORT_RECURSE_SUBMODULES_ONLY)) && - !is_bare_repository()) { + !is_bare_repository(the_repository)) { struct ref *ref = remote_refs; struct oid_array commits = OID_ARRAY_INIT; @@ -1509,7 +1509,7 @@ int transport_push(struct repository *r, if (((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) || ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND | TRANSPORT_RECURSE_SUBMODULES_ONLY)) && - !pretend)) && !is_bare_repository()) { + !pretend)) && !is_bare_repository(the_repository)) { struct ref *ref = remote_refs; struct string_list needs_pushing = STRING_LIST_INIT_DUP; struct oid_array commits = OID_ARRAY_INIT; diff --git a/worktree.c b/worktree.c index 7d70f2c1da..30125827fd 100644 --- a/worktree.c +++ b/worktree.c @@ -124,7 +124,7 @@ static struct worktree *get_main_worktree(int skip_reading_head) worktree->path = strbuf_detach(&worktree_path, NULL); worktree->is_current = is_current_worktree(worktree); worktree->is_bare = (the_repository->bare_cfg == 1) || - is_bare_repository() || + is_bare_repository(the_repository) || /* * When in a secondary worktree we have to also verify if the main * worktree is bare in $commondir/config.worktree. From 1ceee7431b40aba69707835b9b65b0ed7a9cb973 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 11 Jun 2026 08:44:45 +0200 Subject: [PATCH 7/7] treewide: drop USE_THE_REPOSITORY_VARIABLE Adapt a couple of trivial callers of `is_bare_repository()` to instead use a repository available via the caller's context so that we can drop the `USE_THE_REPOSITORY_VARIABLE` macro. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/repack.c | 3 +-- mailmap.c | 6 ++---- refs/reftable-backend.c | 4 +--- setup.c | 3 +-- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/builtin/repack.c b/builtin/repack.c index bbc6f51639..d0465fb4f5 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -1,4 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE #define DISABLE_SIGN_COMPARE_WARNINGS #include "builtin.h" @@ -265,7 +264,7 @@ int cmd_repack(int argc, if (write_bitmaps < 0) { if (write_midx == REPACK_WRITE_MIDX_NONE && - (!(pack_everything & ALL_INTO_ONE) || !is_bare_repository(the_repository))) + (!(pack_everything & ALL_INTO_ONE) || !is_bare_repository(repo))) write_bitmaps = 0; } if (po_args.pack_kept_objects < 0) diff --git a/mailmap.c b/mailmap.c index 7d8590cdd6..2d5514f833 100644 --- a/mailmap.c +++ b/mailmap.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" #include "environment.h" #include "string-list.h" @@ -219,10 +217,10 @@ int read_mailmap(struct repository *repo, struct string_list *map) map->strdup_strings = 1; map->cmp = namemap_cmp; - if (!mailmap_blob && is_bare_repository(the_repository)) + if (!mailmap_blob && is_bare_repository(repo)) mailmap_blob = xstrdup("HEAD:.mailmap"); - if (!startup_info->have_repository || !is_bare_repository(the_repository)) + if (!startup_info->have_repository || !is_bare_repository(repo)) err |= read_mailmap_file(map, ".mailmap", startup_info->have_repository ? MAILMAP_NOFOLLOW : 0); diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 101ef29ac8..c151d331e7 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "../git-compat-util.h" #include "../abspath.h" #include "../chdir-notify.h" @@ -288,7 +286,7 @@ static int should_write_log(struct reftable_ref_store *refs, const char *refname { enum log_refs_config log_refs_cfg = refs->log_all_ref_updates; if (log_refs_cfg == LOG_REFS_UNSET) - log_refs_cfg = is_bare_repository(the_repository) ? LOG_REFS_NONE : LOG_REFS_NORMAL; + log_refs_cfg = is_bare_repository(refs->base.repo) ? LOG_REFS_NONE : LOG_REFS_NORMAL; switch (log_refs_cfg) { case LOG_REFS_NONE: diff --git a/setup.c b/setup.c index e6db80ab07..65f4ac95a8 100644 --- a/setup.c +++ b/setup.c @@ -1,4 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE #define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" @@ -2610,7 +2609,7 @@ static int create_default_files(struct repository *repo, } repo_config_set(repo, "core.filemode", filemode ? "true" : "false"); - if (is_bare_repository(the_repository)) + if (is_bare_repository(repo)) repo_config_set(repo, "core.bare", "true"); else { repo_config_set(repo, "core.bare", "false");