]> git.ipfire.org Git - thirdparty/git.git/commitdiff
setup: stop using `the_repository` in `is_inside_git_dir()`
authorPatrick Steinhardt <ps@pks.im>
Tue, 19 May 2026 09:52:06 +0000 (11:52 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 19 May 2026 10:36:23 +0000 (19:36 +0900)
The function `is_inside_git_dir()` verifies whether or not the current
working directory is located inside the gitdir of `the_repository`. This
is done by taking the gitdir path and verifying that it's a prefix of
the current working directory.

This information is cached so that we don't have to re-do this change
multiple times. Furthermore, we proactively set the value in multiple
locations so that we don't even have to perform the check when we have
discovered the repository.

While we could simply move the caching variable into the repository, the
current layout doesn't really feel sensible in the first place:

  - It can easily lead to false positives or negatives if at any point
    in time we may switch the current working directory.

  - We don't call the function in a hot loop, and neither is it overly
    expensive to compute.

Drop the caching infrastructure and instead compute the property ad-hoc
via an injected repository.

Note that there is one small gotcha: we often end up with relative
gitdir paths, and if so `is_inside_dir()` might fail. This wasn't an
issue before because of how we proactively set the cached value during
repository discovery. Now that we stop doing that it becomes a problem
though, which we work around by resolving the gitdir via `realpath()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/rev-parse.c
setup.c
setup.h

index 218b5f34d6a893a942e846eb1fccaf781b77c448..a216be63cf7cecb7c0180dac13255b18bb692d8c 100644 (file)
@@ -1063,7 +1063,7 @@ int cmd_rev_parse(int argc,
                                continue;
                        }
                        if (!strcmp(arg, "--is-inside-git-dir")) {
-                               printf("%s\n", is_inside_git_dir() ? "true"
+                               printf("%s\n", is_inside_git_dir(the_repository) ? "true"
                                                : "false");
                                continue;
                        }
diff --git a/setup.c b/setup.c
index ba2898473a58a3710ef47fb0317e56cac978036a..80f3ba0d621f44a74a19530685652e3a9916e830 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -26,7 +26,6 @@
 #include "trace2.h"
 #include "worktree.h"
 
-static int inside_git_dir = -1;
 static int inside_work_tree = -1;
 static int work_tree_config_is_bogus;
 enum allowed_bare_repo {
@@ -299,7 +298,7 @@ void verify_filename(const char *prefix,
  */
 void verify_non_filename(const char *prefix, const char *arg)
 {
-       if (!is_inside_work_tree() || is_inside_git_dir())
+       if (!is_inside_work_tree() || is_inside_git_dir(the_repository))
                return;
        if (*arg == '-')
                return; /* flag */
@@ -470,11 +469,12 @@ int is_nonbare_repository_dir(struct strbuf *path)
        return ret;
 }
 
-int is_inside_git_dir(void)
+int is_inside_git_dir(struct repository *repo)
 {
-       if (inside_git_dir < 0)
-               inside_git_dir = is_inside_dir(repo_get_git_dir(the_repository));
-       return inside_git_dir;
+       struct strbuf buf = STRBUF_INIT;
+       int ret = is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));
+       strbuf_release(&buf);
+       return ret;
 }
 
 int is_inside_work_tree(void)
@@ -1251,7 +1251,6 @@ static const char *setup_discovered_git_dir(struct repository *repo,
        set_git_work_tree(".");
        if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
                set_git_dir(repo, gitdir, 0);
-       inside_git_dir = 0;
        inside_work_tree = 1;
        if (offset >= cwd->len)
                return NULL;
@@ -1287,7 +1286,6 @@ static const char *setup_bare_git_dir(struct repository *repo,
                return setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);
        }
 
-       inside_git_dir = 1;
        inside_work_tree = 0;
        if (offset != cwd->len) {
                if (chdir(cwd->buf))
diff --git a/setup.h b/setup.h
index 80bc6e5f078af8a94aa2488be90d0201ace2f305..115bda647c6e948eb956442babade14530333c32 100644 (file)
--- a/setup.h
+++ b/setup.h
@@ -4,7 +4,7 @@
 #include "refs.h"
 #include "string-list.h"
 
-int is_inside_git_dir(void);
+int is_inside_git_dir(struct repository *repo);
 int is_inside_work_tree(void);
 int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);
 int get_common_dir(struct strbuf *sb, const char *gitdir);