Skip to content

Commit 53eb85e

Browse files
committed
Merge branch 'nd/init-core-worktree-in-multi-worktree-world'
"git init" tried to record core.worktree in the repository's 'config' file when GIT_WORK_TREE environment variable was set and it was different from where GIT_DIR appears as ".git" at its top, but the logic was faulty when .git is a "gitdir:" file that points at the real place, causing trouble in working trees that are managed by "git worktree". This has been corrected. * nd/init-core-worktree-in-multi-worktree-world: init: kill git_link variable init: do not set unnecessary core.worktree init: kill set_git_dir_init() init: call set_git_dir_init() from within init_db() init: correct re-initialization from a linked worktree
2 parents 3474084 + 822d940 commit 53eb85e

File tree

4 files changed

+57
-50
lines changed

4 files changed

+57
-50
lines changed

builtin/clone.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -935,16 +935,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
935935
set_git_work_tree(work_tree);
936936
}
937937

938-
junk_git_dir = git_dir;
938+
junk_git_dir = real_git_dir ? real_git_dir : git_dir;
939939
if (safe_create_leading_directories_const(git_dir) < 0)
940940
die(_("could not create leading directories of '%s'"), git_dir);
941941

942-
set_git_dir_init(git_dir, real_git_dir, 0);
943-
if (real_git_dir) {
944-
git_dir = real_git_dir;
945-
junk_git_dir = real_git_dir;
946-
}
947-
948942
if (0 <= option_verbosity) {
949943
if (option_bare)
950944
fprintf(stderr, _("Cloning into bare repository '%s'...\n"), dir);
@@ -970,7 +964,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
970964
}
971965
}
972966

973-
init_db(option_template, INIT_DB_QUIET);
967+
init_db(git_dir, real_git_dir, option_template, INIT_DB_QUIET);
968+
969+
if (real_git_dir)
970+
git_dir = real_git_dir;
971+
974972
write_config(&option_config);
975973

976974
git_config(git_default_config, NULL);

builtin/init-db.c

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
static int init_is_bare_repository = 0;
2323
static int init_shared_repository = -1;
2424
static const char *init_db_template_dir;
25-
static const char *git_link;
2625

2726
static void copy_templates_1(struct strbuf *path, struct strbuf *template,
2827
DIR *dir)
@@ -138,7 +137,7 @@ static void copy_templates(const char *template_dir)
138137
goto close_free_return;
139138
}
140139

141-
strbuf_addstr(&path, get_git_dir());
140+
strbuf_addstr(&path, get_git_common_dir());
142141
strbuf_complete(&path, '/');
143142
copy_templates_1(&path, &template_path, dir);
144143
close_free_return:
@@ -171,7 +170,8 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree)
171170
return 1;
172171
}
173172

174-
static int create_default_files(const char *template_path)
173+
static int create_default_files(const char *template_path,
174+
const char *original_git_dir)
175175
{
176176
struct stat st1;
177177
struct strbuf buf = STRBUF_INIT;
@@ -264,7 +264,7 @@ static int create_default_files(const char *template_path)
264264
/* allow template config file to override the default */
265265
if (log_all_ref_updates == -1)
266266
git_config_set("core.logallrefupdates", "true");
267-
if (needs_work_tree_config(get_git_dir(), work_tree))
267+
if (needs_work_tree_config(original_git_dir, work_tree))
268268
git_config_set("core.worktree", work_tree);
269269
}
270270

@@ -312,34 +312,7 @@ static void create_object_directory(void)
312312
strbuf_release(&path);
313313
}
314314

315-
int set_git_dir_init(const char *git_dir, const char *real_git_dir,
316-
int exist_ok)
317-
{
318-
if (real_git_dir) {
319-
struct stat st;
320-
321-
if (!exist_ok && !stat(git_dir, &st))
322-
die(_("%s already exists"), git_dir);
323-
324-
if (!exist_ok && !stat(real_git_dir, &st))
325-
die(_("%s already exists"), real_git_dir);
326-
327-
/*
328-
* make sure symlinks are resolved because we'll be
329-
* moving the target repo later on in separate_git_dir()
330-
*/
331-
git_link = xstrdup(real_path(git_dir));
332-
set_git_dir(real_path(real_git_dir));
333-
}
334-
else {
335-
set_git_dir(real_path(git_dir));
336-
git_link = NULL;
337-
}
338-
startup_info->have_repository = 1;
339-
return 0;
340-
}
341-
342-
static void separate_git_dir(const char *git_dir)
315+
static void separate_git_dir(const char *git_dir, const char *git_link)
343316
{
344317
struct stat st;
345318

@@ -360,13 +333,31 @@ static void separate_git_dir(const char *git_dir)
360333
write_file(git_link, "gitdir: %s", git_dir);
361334
}
362335

363-
int init_db(const char *template_dir, unsigned int flags)
336+
int init_db(const char *git_dir, const char *real_git_dir,
337+
const char *template_dir, unsigned int flags)
364338
{
365339
int reinit;
366-
const char *git_dir = get_git_dir();
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;
345+
346+
if (!exist_ok && !stat(git_dir, &st))
347+
die(_("%s already exists"), git_dir);
348+
349+
if (!exist_ok && !stat(real_git_dir, &st))
350+
die(_("%s already exists"), real_git_dir);
367351

368-
if (git_link)
369-
separate_git_dir(git_dir);
352+
set_git_dir(real_path(real_git_dir));
353+
git_dir = get_git_dir();
354+
separate_git_dir(git_dir, original_git_dir);
355+
}
356+
else {
357+
set_git_dir(real_path(git_dir));
358+
git_dir = get_git_dir();
359+
}
360+
startup_info->have_repository = 1;
370361

371362
safe_create_dir(git_dir, 0);
372363

@@ -379,7 +370,7 @@ int init_db(const char *template_dir, unsigned int flags)
379370
*/
380371
check_repository_format();
381372

382-
reinit = create_default_files(template_dir);
373+
reinit = create_default_files(template_dir, original_git_dir);
383374

384375
create_object_directory();
385376

@@ -419,6 +410,7 @@ int init_db(const char *template_dir, unsigned int flags)
419410
git_dir, len && git_dir[len-1] != '/' ? "/" : "");
420411
}
421412

413+
free(original_git_dir);
422414
return 0;
423415
}
424416

@@ -586,7 +578,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
586578
set_git_work_tree(work_tree);
587579
}
588580

589-
set_git_dir_init(git_dir, real_git_dir, 1);
590-
591-
return init_db(template_dir, flags);
581+
flags |= INIT_DB_EXIST_OK;
582+
return init_db(git_dir, real_git_dir, template_dir, flags);
592583
}

cache.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -526,9 +526,10 @@ extern void verify_non_filename(const char *prefix, const char *name);
526526
extern int path_inside_repo(const char *prefix, const char *path);
527527

528528
#define INIT_DB_QUIET 0x0001
529+
#define INIT_DB_EXIST_OK 0x0002
529530

530-
extern int set_git_dir_init(const char *git_dir, const char *real_git_dir, int);
531-
extern int init_db(const char *template_dir, unsigned int flags);
531+
extern int init_db(const char *git_dir, const char *real_git_dir,
532+
const char *template_dir, unsigned int flags);
532533

533534
extern void sanitize_stdfds(void);
534535
extern int daemonize(void);

t/t0001-init.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,4 +393,21 @@ test_expect_success 'remote init from does not use config from cwd' '
393393
test_cmp expect actual
394394
'
395395

396+
test_expect_success 're-init from a linked worktree' '
397+
git init main-worktree &&
398+
(
399+
cd main-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+
)
411+
'
412+
396413
test_done

0 commit comments

Comments
 (0)