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

[PATCH] init: don't set core.worktree when initializing /.git

From
Jeff King <peff@peff.net>
Date
Mar 31, 2015, 18:34 UTC
Message-ID
<20150331183423.GD19206@peff.net>
In-Reply-To
<20150331181552.GC19206@peff.net>

If you create a git repository in the root directory with "git init /", we erroneously write a core.worktree entry. That can be surprising if you later move the .git directory to another path (which usually moves the relative working tree, but is foiled if there is an explicit worktree set).

The problem is that we check whether core.worktree is necessary by seeing if we can make the git_dir by concatenating "/.git" onto the working tree. That would lead to "//.git" in this instance, but we actually have "/.git" (without the doubled slash).

We can fix this by special-casing the root directory. I also split the logic out into its own function to make the conditional a bit more readable (and used skip_prefix, which I think makes it a little more obvious what is going on).

No tests, as we would need to be able to write to "/" to do so. I did manually confirm that:

  sudo git init /
  cd /
  git rev-parse --show-toplevel
  git config core.worktree

Still finds the top-level correctly (as "/"), and does not set any core.worktree variable.

Signed-off-by: Jeff King <peff@peff.net>
---
The current behavior isn't _wrong_, in the sense that it's OK to set
core.worktree when we don't need to. But I think it is unnecessarily
confusing to users who expect to be able to move .git directories
around, because it usually just works. So I'd call this an extremely
minor bug.
 builtin/init-db.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 6723d39..6efe2df 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -182,6 +182,21 @@ static int git_init_db_config(const char *k, const char *v, void *cb)
 	return 0;
 }
 
+/*
+ * If the git_dir is not directly inside the working tree, then git will not
+ * find it by default, and we need to set the worktree explicitly.
+ */
+static int needs_work_tree_config(const char *git_dir, const char *work_tree)
+{
+	/* special case that is missed by the general rule below */
+	if (!strcmp(work_tree, "/") && !strcmp(git_dir, "/.git"))
+		return 0;
+	if (skip_prefix(git_dir, work_tree, &git_dir) &&
+	    !strcmp(git_dir, "/.git"))
+		return 0;
+	return 1;
+}
+
 static int create_default_files(const char *template_path)
 {
 	const char *git_dir = get_git_dir();
@@ -274,10 +289,8 @@ static int create_default_files(const char *template_path)
 		/* allow template config file to override the default */
 		if (log_all_ref_updates == -1)
 		    git_config_set("core.logallrefupdates", "true");
-		if (!starts_with(git_dir, work_tree) ||
-		    strcmp(git_dir + strlen(work_tree), "/.git")) {
+		if (needs_work_tree_config(git_dir, work_tree))
 			git_config_set("core.worktree", work_tree);
-		}
 	}
 
 	if (!reinit) {
-- 
2.4.0.rc0.363.gf9f328b
Previous: Jeff KingNext: Jonathan Nieder
Message 3 of 11 in “Forcing git top-level”
  1. Cedric GavaMar 31, 2015
  2. Jeff KingMar 31, 2015
  3. init: don't set core.worktree when initializing /.gitJeff King, Mar 31, 2015
  4. Jonathan NiederMar 31, 2015
  5. init: don't set core.worktree when initializing /.gitJeff King, Apr 2, 2015
  6. Jonathan NiederApr 2, 2015
  7. t1509: update prepare script to be able to run t1509 in chroot againNguyễn Thái Ngọc Duy, Apr 3, 2015
  8. Jeff KingApr 3, 2015
  9. Duy NguyenApr 3, 2015
  10. Junio C HamanoApr 11, 2015
  11. t1509: update prepare script to be able to run t1509 in chroot againNguyễn Thái Ngọc Duy, Apr 18, 2015

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.