git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[RFC PATCH 3/3] setup: communicate why a directory is not a valid git directory

From
Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
Date
Sep 24, 2026, 12:02 UTC
Message-ID
<20260924120502.2642141-4-kaartic.sivaraam@gmail.com>
In-Reply-To
<20260924120502.2642141-1-kaartic.sivaraam@gmail.com>

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 <kaartic.sivaraam@gmail.com>
---
 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
Previous: Kaartic SivaraamNext: Junio C Hamano
Message 4 of 20 in “Improve error reporting to mention "why" a directory is not a repository”
  1. 0/3 Improve error reporting to mention "why" a directory is not a repositoryKaartic Sivaraam, Sep 24, 2026
  2. 1/3 t0009: add tests to cover more error reporting scenariosKaartic Sivaraam, Sep 24, 2026
  3. 2/3 setup: introduce new helper 'is_git_directory_verbose'Kaartic Sivaraam, Sep 24, 2026
  4. 3/3 setup: communicate why a directory is not a valid git directoryKaartic Sivaraam, Sep 24, 2026
  5. Junio C HamanoSep 24, 2026
  6. Junio C HamanoSep 24, 2026
  7. Junio C HamanoSep 24, 2026
  8. Kaartic SivaraamSep 25, 2026
  9. Kaartic SivaraamSep 25, 2026
  10. Kaartic SivaraamSep 25, 2026
  11. 1/4 setup: normalize an if-else to follow our conventionKaartic Sivaraam, Sep 29, 2026
  12. 0/4 Improve error reporting to mention "why" a directory is not a repositoryKaartic Sivaraam, Sep 29, 2026
  13. 2/4 t0009: add tests to cover more error reporting scenariosKaartic Sivaraam, Sep 29, 2026
  14. 3/4 setup: introduce new helper 'is_git_directory_verbose'Kaartic Sivaraam, Sep 29, 2026
  15. 4/4 setup: communicate why a directory is not a valid git directoryKaartic Sivaraam, Sep 29, 2026
  16. Patrick SteinhardtSep 30, 2026
  17. Patrick SteinhardtSep 30, 2026
  18. Junio C HamanoSep 30, 2026
  19. Kaartic SivaraamOct 5, 2026
  20. Kaartic SivaraamOct 5, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.