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

Re: [BUG] bare repository detection does not work with aliases

From
Jeff King <peff@peff.net>
Date
Mar 8, 2013, 05:48 UTC
Message-ID
<20130308054824.GA24429@sigill.intra.peff.net>
In-Reply-To
<CAHREChhuX82ibNEDQnQUeS9TEeyMFGpuNhyXzt1Pn-Tt2BVOQA@mail.gmail.com>
On Thu, Mar 07, 2013 at 05:47:45PM -0500, Mark Lodato wrote:
> It seems that the fallback bare repository detection in the absence of
> core.bare fails for aliases.

This triggered some deja vu for me, so I went digging. And indeed, this has been a bug since at least 2008. This patch (which never got applied) fixed it:

  http://thread.gmane.org/gmane.comp.version-control.git/72792
The issue is that we treat:
  GIT_DIR=/some/path git ...

as if the current directory is the work tree, unless core.bare is explicitly set, or unless an explicit work tree is given (via GIT_WORK_TREE, "git --work-tree", or in the config). This is handy, and backwards compatible.

Inside setup_git_directory, when we find the directory we put it in $GIT_DIR for later reference by ourselves or sub-programs (since we are typically moving to the top of the working tree next, we need to record the original path, and can't rely on discovery finding the same path again). But we don't set $GIT_WORK_TREE. So if you don't have core.bare set, the above rule will kick in for sub-programs, or for aliases (which will call setup_git_directory again).

The solution is that when we set $GIT_DIR like this, we need to also say "no, there is no working tree; we are bare". And that's what that patch does. It's 5 years old now, so not surprisingly, it does not apply cleanly. The moral equivalent in today's code base would be something like:

diff --git a/environment.c b/environment.c
index 89d6c70..8edaedd 100644
--- a/environment.c
+++ b/environment.c
@@ -200,7 +200,8 @@ void set_git_work_tree(const char *new_work_tree)
 		return;
 	}
 	git_work_tree_initialized = 1;
-	work_tree = xstrdup(real_path(new_work_tree));
+	if (*new_work_tree)
+		work_tree = xstrdup(real_path(new_work_tree));
 }
 
 const char *get_git_work_tree(void)
diff --git a/setup.c b/setup.c
index e1cfa48..f0e1251 100644
--- a/setup.c
+++ b/setup.c
@@ -544,7 +544,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 	worktree = get_git_work_tree();
 
 	/* both get_git_work_tree() and cwd are already normalized */
-	if (!strcmp(cwd, worktree)) { /* cwd == worktree */
+	if (!worktree || !strcmp(cwd, worktree)) { /* cwd == worktree */
 		set_git_dir(gitdirenv);
 		free(gitfile);
 		return NULL;
@@ -636,6 +636,8 @@ static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongi
 	}
 	else
 		set_git_dir(".");
+
+	setenv(GIT_WORK_TREE_ENVIRONMENT, "", 1);
 	return NULL;
 }
 

which passes your test. Unfortunately, this patch runs afoul of the same
complaints that prevented the original from being acceptable (weirdness
on Windows with empty environment variables).

Having read the discussion again, I _think_ the more sane thing is to
actually just have a new variable, $GIT_BARE, which overrides any
core.bare config (just as $GIT_WORK_TREE override core.worktree). And
then we set that explicitly when we are in a bare $GIT_DIR, propagating
our auto-detection to sub-processes.

-Peff
Previous: Mark LodatoNext: Junio C Hamano
Message 2 of 16 in “[BUG] bare repository detection does not work with aliases”
  1. Mark LodatoMar 7, 2013
  2. Jeff KingMar 8, 2013
  3. Junio C HamanoMar 8, 2013
  4. Jeff KingMar 8, 2013
  5. setup: suppress implicit "." work-tree for bare reposJeff King, Mar 8, 2013
  6. Johannes SixtMar 8, 2013
  7. Jeff KingMar 8, 2013
  8. Junio C HamanoMar 8, 2013
  9. Jeff KingMar 8, 2013
  10. [PATCHv2] setup and GIT_IMPLICIT_WORK_TREEJeff King, Mar 8, 2013
  11. 1/3 cache.h: drop LOCAL_REPO_ENV_SIZEJeff King, Mar 8, 2013
  12. 2/3 environment: add GIT_PREFIX to local_repo_envJeff King, Mar 8, 2013
  13. Eric SunshineMar 8, 2013
  14. Jeff KingMar 8, 2013
  15. Junio C HamanoMar 8, 2013
  16. 3/3 setup: suppress implicit "." work-tree for bare reposJeff King, Mar 8, 2013

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.