[RFC PATCH 3/3] setup: communicate why a directory is not a valid git directory
From: Kaartic Sivaraam <hidden>
Date: 2026-09-24 12:05:20
Subsystem:
the rest · Maintainer:
Linus Torvalds
At the moment, there are a few scenarios in which the error message surrounding an invalid Git repository is a bit blunt: $ GIT_OBJECT_DIRECTORY=/does/not/exist git --git-dir repo.git rev-parse --is-bare-repository fatal: not a git repository: 'repo.git' In this case, even though repo.git is a valid Git repository, we get an output saying it is not since the GIT_OBJECT_DIRECTORY does not point to a valid object directory. At the moment, the user is on their own in figuring this out. Instead, make it more easy for users to figure such issues particularly in cases where they have explicitly specified a Git directory. This intends to improve the error reporting UX by clarifying why the specified repository is not considered valid. We achieve this by means of using the new helper is_git_directory_verbose() that has been introduced. With the same, we get a more helpful error message as follows: $ GIT_OBJECT_DIRECTORY=/does/not/exist git --git-dir repo.git rev-parse --is-bare-repository fatal: not a git repository: 'repo.git' reason: cannot access object directory '/does/not/exist' set via $GIT_OBJECT_DIRECTORY Signed-off-by: Kaartic Sivaraam <redacted> --- setup.c | 13 +++++++++++-- t/t0009-git-dir-validation.sh | 10 ++++++---- 2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/setup.c b/setup.c
index b3b53a1cfc..3e99141474 100644
--- a/setup.c
+++ b/setup.c@@ -1225,6 +1225,7 @@ static void repo_discover_explicit_gitdir(struct repo_discovery *discovery, int *nongit_ok) { const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT); + struct strbuf invalid_gitdir_reason = STRBUF_INIT; char *gitfile; int offset;
@@ -1237,12 +1238,19 @@ static void repo_discover_explicit_gitdir(struct repo_discovery *discovery, gitdirenv = gitfile; } - if (!is_git_directory(gitdirenv)) { + if (!is_git_directory_verbose(gitdirenv, &invalid_gitdir_reason)) { + struct strbuf die_msg = STRBUF_INIT; if (nongit_ok) { *nongit_ok = 1; goto out; } - die(_("not a git repository: '%s'"), gitdirenv); + + strbuf_addf(&die_msg, _("not a git repository: '%s'"), gitdirenv); + strbuf_addch(&die_msg, '\n'); + strbuf_addf(&die_msg, _("reason: %s"), invalid_gitdir_reason.buf); + die("%s", die_msg.buf); + + strbuf_release(&die_msg); } if (read_and_verify_repository_format(&discovery->format, gitdirenv, nongit_ok))
@@ -1304,6 +1312,7 @@ static void repo_discover_explicit_gitdir(struct repo_discovery *discovery, repo_discovery_set_gitdir(discovery, gitdirenv, 0); out: + strbuf_release(&invalid_gitdir_reason); free(gitfile); }
diff --git a/t/t0009-git-dir-validation.sh b/t/t0009-git-dir-validation.sh
index 244dc07c0e..411aac1d9e 100755
--- a/t/t0009-git-dir-validation.sh
+++ b/t/t0009-git-dir-validation.sh@@ -79,7 +79,8 @@ test_expect_success 'setup: custom git directory with missing HEAD is rejected' mkdir -p parent/empty-dir && ( test_must_fail git --git-dir parent/empty-dir rev-parse --is-bare-repository 2>stderr && - test_grep "not a git repository" stderr + test_grep "not a git repository" stderr && + test_grep "reason: could not stat HEAD at" stderr ) '
@@ -93,7 +94,8 @@ test_expect_success 'setup: custom git directory with HEAD as a symlink outside rm real-repo/HEAD && ln -s ../garbage real-repo/HEAD && test_must_fail git --git-dir real-repo rev-parse --is-bare-repository 2>stderr && - test_grep "not a git repository" stderr + test_grep "not a git repository" stderr && + test_grep "reason: HEAD is a symlink .* but target lives outside refs" stderr ) '
@@ -105,9 +107,9 @@ test_expect_success 'setup: custom git directory with invalid GIT_OBJECT_DIRECTO git init --bare real-repo && test_must_fail env GIT_OBJECT_DIRECTORY="$(pwd)/does-not-exist" \ git --git-dir real-repo rev-parse --is-bare-repository 2>stderr && - test_grep "not a git repository" stderr + test_grep "not a git repository" stderr && + test_grep "reason: cannot access object directory .* set via \$GIT_OBJECT_DIRECTORY" stderr ) ' - test_done
--
2.56.0.rc1.12.g2c9c8d64bb