Skip to content

Commit 84ccad8

Browse files
peffgitster
authored andcommitted
init: don't set core.worktree when initializing /.git
If you create a git repository in the root directory with "git init /", we erroneously write a core.worktree entry. This isn't _wrong_, in the sense that it's OK to set core.worktree when we don't need to. But it is unnecessarily 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 <[email protected]> Reviewed-by: Jonathan Nieder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 282616c commit 84ccad8

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

builtin/init-db.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,20 @@ static int git_init_db_config(const char *k, const char *v, void *cb)
177177
return 0;
178178
}
179179

180+
/*
181+
* If the git_dir is not directly inside the working tree, then git will not
182+
* find it by default, and we need to set the worktree explicitly.
183+
*/
184+
static int needs_work_tree_config(const char *git_dir, const char *work_tree)
185+
{
186+
if (!strcmp(work_tree, "/") && !strcmp(git_dir, "/.git"))
187+
return 0;
188+
if (skip_prefix(git_dir, work_tree, &git_dir) &&
189+
!strcmp(git_dir, "/.git"))
190+
return 0;
191+
return 1;
192+
}
193+
180194
static int create_default_files(const char *template_path)
181195
{
182196
const char *git_dir = get_git_dir();
@@ -266,10 +280,8 @@ static int create_default_files(const char *template_path)
266280
/* allow template config file to override the default */
267281
if (log_all_ref_updates == -1)
268282
git_config_set("core.logallrefupdates", "true");
269-
if (!starts_with(git_dir, work_tree) ||
270-
strcmp(git_dir + strlen(work_tree), "/.git")) {
283+
if (needs_work_tree_config(git_dir, work_tree))
271284
git_config_set("core.worktree", work_tree);
272-
}
273285
}
274286

275287
if (!reinit) {

0 commit comments

Comments
 (0)