From: Patrick Steinhardt <ps@pks.im>
To: git@vger.kernel.org
Cc: Justin Tobler <jltobler@gmail.com>, Junio C Hamano <gitster@pobox.com>
Subject: [PATCH v2 04/13] setup: split up concerns of `setup_git_env_internal()`
Date: Tue, 07 Jul 2026 09:21:23 +0200 [thread overview]
Message-ID: <20260707-pks-setup-split-discovery-and-setup-v2-4-aab372cd227c@pks.im> (raw)
In-Reply-To: <20260707-pks-setup-split-discovery-and-setup-v2-0-aab372cd227c@pks.im>
The function `setup_git_env_internal()` does two completely unrelated
things:
- It configures the repository's gitdir and propagates environment
variables into it.
- It configures a couple of global parameters via environment
variables.
The function is called when we initialize the repository's path, but
it's also called via `chdir_notify_register()` whenever we change the
current working directory. While we indeed have to reconfigure the
gitdir in case it's a relative path, it doesn't make sense to reapply
the global environment variables.
Split up concerns of this function along the above delineation. Handling
of the global environment variables is moved into `init_git()`, as they
can be considered part of our setup procedure.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
common-init.c | 20 ++++++++++++++++
setup.c | 73 +++++++++++++++++++++++------------------------------------
2 files changed, 48 insertions(+), 45 deletions(-)
diff --git a/common-init.c b/common-init.c
index 5cc73f058c..d26c9c1f20 100644
--- a/common-init.c
+++ b/common-init.c
@@ -5,7 +5,10 @@
#include "exec-cmd.h"
#include "gettext.h"
#include "attr.h"
+#include "odb.h"
+#include "parse.h"
#include "repository.h"
+#include "replace-object.h"
#include "setup.h"
#include "strbuf.h"
#include "trace2.h"
@@ -31,6 +34,22 @@ static void restore_sigpipe_to_default(void)
signal(SIGPIPE, SIG_DFL);
}
+static void setup_environment(void)
+{
+ char *git_replace_ref_base;
+ const char *replace_ref_base;
+
+ if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
+ disable_replace_refs();
+ replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT);
+ git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base
+ : "refs/replace/");
+ update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base);
+
+ if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0))
+ fetch_if_missing = 0;
+}
+
void init_git(const char **argv)
{
struct strbuf tmp = STRBUF_INIT;
@@ -51,6 +70,7 @@ void init_git(const char **argv)
git_setup_gettext();
initialize_repository(the_repository);
+ setup_environment();
attr_start();
diff --git a/setup.c b/setup.c
index 85fad0d77d..324a235dd1 100644
--- a/setup.c
+++ b/setup.c
@@ -10,7 +10,6 @@
#include "object-file.h"
#include "object-name.h"
#include "refs.h"
-#include "replace-object.h"
#include "repository.h"
#include "config.h"
#include "dir.h"
@@ -1042,38 +1041,19 @@ const char *read_gitfile_gently(const char *path, int *return_error_code)
return error_code ? NULL : path;
}
-static void setup_git_env_internal(struct repository *repo,
- const char *git_dir)
+static void apply_gitdir_and_environment(struct repository *repo, const char *path)
{
- char *git_replace_ref_base;
- const char *replace_ref_base;
- struct set_gitdir_args args = { NULL };
struct strvec to_free = STRVEC_INIT;
+ struct set_gitdir_args args = {
+ .commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT),
+ .graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT),
+ .index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT),
+ .disable_ref_updates = !!getenv(GIT_QUARANTINE_ENVIRONMENT),
+ };
- args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT);
- args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);
- args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);
- if (getenv(GIT_QUARANTINE_ENVIRONMENT))
- args.disable_ref_updates = true;
+ repo_set_gitdir(repo, path, &args);
- repo_set_gitdir(repo, git_dir, &args);
strvec_clear(&to_free);
-
- if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
- disable_replace_refs();
- replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT);
- git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base
- : "refs/replace/");
- update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base);
-
- if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0))
- fetch_if_missing = 0;
-}
-
-static void set_git_dir_1(struct repository *repo, const char *path)
-{
- xsetenv(GIT_DIR_ENVIRONMENT, path, 1);
- setup_git_env_internal(repo, path);
}
static void update_relative_gitdir(const char *name UNUSED,
@@ -1087,11 +1067,12 @@ static void update_relative_gitdir(const char *name UNUSED,
trace_printf_key(&trace_setup_key,
"setup: move $GIT_DIR to '%s'",
path);
- set_git_dir_1(repo, path);
+ apply_gitdir_and_environment(repo, path);
+ xsetenv(GIT_DIR_ENVIRONMENT, path, 1);
free(path);
}
-static void set_git_dir(struct repository *repo, const char *path, int make_realpath)
+static void apply_and_export_relative_gitdir(struct repository *repo, const char *path, int make_realpath)
{
struct strbuf realpath = STRBUF_INIT;
@@ -1100,7 +1081,9 @@ static void set_git_dir(struct repository *repo, const char *path, int make_real
path = realpath.buf;
}
- set_git_dir_1(repo, path);
+ apply_gitdir_and_environment(repo, path);
+ xsetenv(GIT_DIR_ENVIRONMENT, path, 1);
+
if (!is_absolute_path(path))
chdir_notify_register(NULL, update_relative_gitdir, repo);
@@ -1153,7 +1136,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,
set_git_work_tree(repo, work_tree_env);
} else if (repo_fmt->is_bare > 0) {
/* #18, #26 */
- set_git_dir(repo, gitdirenv, 0);
+ apply_and_export_relative_gitdir(repo, gitdirenv, 0);
free(gitfile);
return NULL;
} else if (repo_fmt->work_tree) { /* #6, #14 */
@@ -1173,7 +1156,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,
}
} else if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) {
/* #16d */
- set_git_dir(repo, gitdirenv, 0);
+ apply_and_export_relative_gitdir(repo, gitdirenv, 0);
free(gitfile);
return NULL;
} else { /* #2, #10 */
@@ -1185,14 +1168,14 @@ static const char *setup_explicit_git_dir(struct repository *repo,
/* both repo_get_work_tree() and cwd are already normalized */
if (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */
- set_git_dir(repo, gitdirenv, 0);
+ apply_and_export_relative_gitdir(repo, gitdirenv, 0);
free(gitfile);
return NULL;
}
offset = dir_inside_of(cwd->buf, worktree);
if (offset >= 0) { /* cwd inside worktree? */
- set_git_dir(repo, gitdirenv, 1);
+ apply_and_export_relative_gitdir(repo, gitdirenv, 1);
if (chdir(worktree))
die_errno(_("cannot chdir to '%s'"), worktree);
strbuf_addch(cwd, '/');
@@ -1201,7 +1184,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,
}
/* cwd outside worktree */
- set_git_dir(repo, gitdirenv, 0);
+ apply_and_export_relative_gitdir(repo, gitdirenv, 0);
free(gitfile);
return NULL;
}
@@ -1231,7 +1214,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 (repo_fmt->is_bare > 0) {
- set_git_dir(repo, gitdir, (offset != cwd->len));
+ apply_and_export_relative_gitdir(repo, gitdir, (offset != cwd->len));
if (chdir(cwd->buf))
die_errno(_("cannot come back to cwd"));
return NULL;
@@ -1240,7 +1223,7 @@ static const char *setup_discovered_git_dir(struct repository *repo,
/* #0, #1, #5, #8, #9, #12, #13 */
set_git_work_tree(repo, ".");
if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
- set_git_dir(repo, gitdir, 0);
+ apply_and_export_relative_gitdir(repo, gitdir, 0);
if (offset >= cwd->len)
return NULL;
@@ -1280,10 +1263,10 @@ static const char *setup_bare_git_dir(struct repository *repo,
die_errno(_("cannot come back to cwd"));
root_len = offset_1st_component(cwd->buf);
strbuf_setlen(cwd, offset > root_len ? offset : root_len);
- set_git_dir(repo, cwd->buf, 0);
+ apply_and_export_relative_gitdir(repo, cwd->buf, 0);
}
else
- set_git_dir(repo, ".", 0);
+ apply_and_export_relative_gitdir(repo, ".", 0);
return NULL;
}
@@ -1878,7 +1861,7 @@ const char *enter_repo(struct repository *repo, const char *path, unsigned flags
struct repository_format fmt = REPOSITORY_FORMAT_INIT;
struct strbuf err = STRBUF_INIT;
- set_git_dir(repo, ".", 0);
+ apply_and_export_relative_gitdir(repo, ".", 0);
read_and_verify_repository_format(&fmt, ".", NULL);
if (apply_repository_format(repo, &fmt, APPLY_REPOSITORY_FORMAT_HONOR_ENV, &err) < 0)
die("%s", err.buf);
@@ -2022,7 +2005,7 @@ const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
startup_info->have_repository = 1;
/*
- * Not all paths through the setup code will call 'set_git_dir()' (which
+ * Not all paths through the setup code will call 'apply_and_export_relative_gitdir()' (which
* directly sets up the environment) so in order to guarantee that the
* environment is in a consistent state after setup, explicitly setup
* the environment if we have a repository.
@@ -2040,7 +2023,7 @@ const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
if (!gitdir)
gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
- setup_git_env_internal(repo, gitdir);
+ apply_gitdir_and_environment(repo, gitdir);
}
if (startup_info->have_repository) {
@@ -2825,12 +2808,12 @@ int init_db(struct repository *repo,
if (!exist_ok && !stat(real_git_dir, &st))
die(_("%s already exists"), real_git_dir);
- set_git_dir(repo, real_git_dir, 1);
+ apply_and_export_relative_gitdir(repo, real_git_dir, 1);
git_dir = repo_get_git_dir(repo);
separate_git_dir(git_dir, original_git_dir);
}
else {
- set_git_dir(repo, git_dir, 1);
+ apply_and_export_relative_gitdir(repo, git_dir, 1);
git_dir = repo_get_git_dir(repo);
}
startup_info->have_repository = 1;
--
2.55.0.141.g00534a21ce.dirty
next prev parent reply other threads:[~2026-07-07 7:21 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-30 11:47 [PATCH 00/13] setup: split up repository discovery and setup Patrick Steinhardt
2026-06-30 11:47 ` [PATCH 01/13] setup: rename `check_repository_format_gently()` Patrick Steinhardt
2026-07-06 21:27 ` Justin Tobler
2026-06-30 11:47 ` [PATCH 02/13] setup: mark bogus worktree in `apply_repository_format()` Patrick Steinhardt
2026-06-30 18:26 ` Junio C Hamano
2026-07-01 6:23 ` Patrick Steinhardt
2026-07-06 21:49 ` Justin Tobler
2026-07-07 6:25 ` Patrick Steinhardt
2026-06-30 11:47 ` [PATCH 03/13] setup: unify setup of shallow file Patrick Steinhardt
2026-07-06 22:02 ` Justin Tobler
2026-07-07 6:25 ` Patrick Steinhardt
2026-06-30 11:47 ` [PATCH 04/13] setup: split up concerns of `setup_git_env_internal()` Patrick Steinhardt
2026-06-30 11:47 ` [PATCH 05/13] setup: introduce explicit repository discovery Patrick Steinhardt
2026-07-06 22:19 ` Justin Tobler
2026-07-07 6:25 ` Patrick Steinhardt
2026-06-30 11:47 ` [PATCH 06/13] setup: embed repository format in discovery Patrick Steinhardt
2026-06-30 11:47 ` [PATCH 07/13] setup: move prefix into repository Patrick Steinhardt
2026-07-06 22:33 ` Justin Tobler
2026-06-30 11:47 ` [PATCH 08/13] setup: drop static `cwd` variable Patrick Steinhardt
2026-06-30 11:47 ` [PATCH 09/13] setup: propagate prefix via repository discovery Patrick Steinhardt
2026-06-30 11:47 ` [PATCH 10/13] setup: make repository discovery self-contained Patrick Steinhardt
2026-06-30 11:47 ` [PATCH 11/13] setup: drop redundant configuration of `startup_info->have_repository` Patrick Steinhardt
2026-06-30 11:47 ` [PATCH 12/13] setup: pass worktree to `init_db()` Patrick Steinhardt
2026-06-30 11:47 ` [PATCH 13/13] setup: mark `set_git_work_tree()` as file-local Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 00/13] setup: split up repository discovery and setup Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 01/13] setup: rename `check_repository_format_gently()` Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 02/13] setup: mark bogus worktree in `apply_repository_format()` Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 03/13] setup: unify setup of shallow file Patrick Steinhardt
2026-07-07 7:21 ` Patrick Steinhardt [this message]
2026-07-07 7:21 ` [PATCH v2 05/13] setup: introduce explicit repository discovery Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 06/13] setup: embed repository format in discovery Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 07/13] setup: move prefix into repository Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 08/13] setup: drop static `cwd` variable Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 09/13] setup: propagate prefix via repository discovery Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 10/13] setup: make repository discovery self-contained Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 11/13] setup: drop redundant configuration of `startup_info->have_repository` Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 12/13] setup: pass worktree to `init_db()` Patrick Steinhardt
2026-07-07 7:21 ` [PATCH v2 13/13] setup: mark `set_git_work_tree()` as file-local Patrick Steinhardt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260707-pks-setup-split-discovery-and-setup-v2-4-aab372cd227c@pks.im \
--to=ps@pks.im \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jltobler@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox