init: do not set unnecessary core.worktree

The function needs_work_tree_config() that is called from create_default_files() is supposed to be fed the path to ".git" that looks as if it is at the top of the working tree, and decide if that location matches the actual worktree being used. This comparison allows "git init" to decide if core.worktree needs to be recorded in the working tree. In the current code, however, we feed the return value from get_git_dir(), which can be totally different from what the function expects when "gitdir" file is involved. Instead of giving the path to the ".git" at the top of the working tree, we end up feeding the actual path that the file points at. This original location of ".git" however is only known to init_db(). Make init_db() save it and have it passed to create_default_files() as a new parameter, which passes the correct location down to needs_work_tree_config() to fix this. Noticed-by: Max Nordlund <max.nordlund@sqore.com> Helped-by: Michael J Gruber <git@drmicha.warpmail.net> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Sep 25, 2016 at 10:14 UTC 6311cfaf93716bcc43dd1151cb1763e3f80d8099
2 files changed +8 -3
builtin/init-db.c
+6 -3
@@ -171,7 +171,8 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree)
171 return 1;
172 }
173
174 -static int create_default_files(const char *template_path)
174 +static int create_default_files(const char *template_path,
175 + const char *original_git_dir)
176 {
177 struct stat st1;
178 struct strbuf buf = STRBUF_INIT;
@@ -263,7 +264,7 @@ static int create_default_files(const char *template_path)
264 /* allow template config file to override the default */
265 if (log_all_ref_updates == -1)
266 git_config_set("core.logallrefupdates", "true");
266 - if (needs_work_tree_config(get_git_dir(), work_tree))
267 + if (needs_work_tree_config(original_git_dir, work_tree))
268 git_config_set("core.worktree", work_tree);
269 }
270
@@ -337,6 +338,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
338 {
339 int reinit;
340 int exist_ok = flags & INIT_DB_EXIST_OK;
341 + char *original_git_dir = xstrdup(real_path(git_dir));
342
343 if (real_git_dir) {
344 struct stat st;
@@ -375,7 +377,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
377 */
378 check_repository_format();
379
378 - reinit = create_default_files(template_dir);
380 + reinit = create_default_files(template_dir, original_git_dir);
381
382 create_object_directory();
383
@@ -412,6 +414,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
414 git_dir, len && git_dir[len-1] != '/' ? "/" : "");
415 }
416
417 + free(original_git_dir);
418 return 0;
419 }
420
t/t0001-init.sh
+2
@@ -400,9 +400,11 @@ test_expect_success 're-init from a linked worktree' '
400 test_commit first &&
401 git worktree add ../linked-worktree &&
402 mv .git/info/exclude expected-exclude &&
403 + cp .git/config expected-config &&
404 find .git/worktrees -print | sort >expected &&
405 git -C ../linked-worktree init &&
406 test_cmp expected-exclude .git/info/exclude &&
407 + test_cmp expected-config .git/config &&
408 find .git/worktrees -print | sort >actual &&
409 test_cmp expected actual
410 )