Skip to content

Commit 09e74b0

Browse files
committed
Merge branch 'op/worktree-is-main-bare-fix'
Going into a secondary worktree and asking "is the main worktree bare?" did not work correctly when per-worktree configuration option was in use, which has been corrected. * op/worktree-is-main-bare-fix: worktree: detect from secondary worktree if main worktree is bare
2 parents 5785d91 + 78a95e0 commit 09e74b0

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed

t/t3200-branch.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,20 @@ test_expect_success 'bare main worktree has HEAD at branch deleted by secondary
410410
git -C secondary branch -D main
411411
'
412412

413+
test_expect_success 'secondary worktrees recognize core.bare=true in main config.worktree' '
414+
test_when_finished "rm -rf bare_repo non_bare_repo secondary_worktree" &&
415+
git init -b main non_bare_repo &&
416+
test_commit -C non_bare_repo x &&
417+
418+
git clone --bare non_bare_repo bare_repo &&
419+
git -C bare_repo config extensions.worktreeConfig true &&
420+
git -C bare_repo config unset core.bare &&
421+
git -C bare_repo config --worktree core.bare true &&
422+
423+
git -C bare_repo worktree add ../secondary_worktree &&
424+
git -C secondary_worktree checkout main
425+
'
426+
413427
test_expect_success 'git branch --list -v with --abbrev' '
414428
test_when_finished "git branch -D t" &&
415429
git branch t &&

worktree.c

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,28 @@ static int is_current_worktree(struct worktree *wt)
6565
return is_current;
6666
}
6767

68+
/*
69+
* When in a secondary worktree, and when extensions.worktreeConfig
70+
* is true, only $commondir/config and $commondir/worktrees/<id>/
71+
* config.worktree are consulted, hence any core.bare=true setting in
72+
* $commondir/config.worktree gets overlooked. Thus, check it manually
73+
* to determine if the repository is bare.
74+
*/
75+
static int is_main_worktree_bare(struct repository *repo)
76+
{
77+
int bare = 0;
78+
struct config_set cs = {0};
79+
char *worktree_config = xstrfmt("%s/config.worktree", repo_get_common_dir(repo));
80+
81+
git_configset_init(&cs);
82+
git_configset_add_file(&cs, worktree_config);
83+
git_configset_get_bool(&cs, "core.bare", &bare);
84+
85+
git_configset_clear(&cs);
86+
free(worktree_config);
87+
return bare;
88+
}
89+
6890
/**
6991
* get the main worktree
7092
*/
@@ -79,16 +101,17 @@ static struct worktree *get_main_worktree(int skip_reading_head)
79101
CALLOC_ARRAY(worktree, 1);
80102
worktree->repo = the_repository;
81103
worktree->path = strbuf_detach(&worktree_path, NULL);
82-
/*
83-
* NEEDSWORK: If this function is called from a secondary worktree and
84-
* config.worktree is present, is_bare_repository_cfg will reflect the
85-
* contents of config.worktree, not the contents of the main worktree.
86-
* This means that worktree->is_bare may be set to 0 even if the main
87-
* worktree is configured to be bare.
88-
*/
89-
worktree->is_bare = (is_bare_repository_cfg == 1) ||
90-
is_bare_repository();
91104
worktree->is_current = is_current_worktree(worktree);
105+
worktree->is_bare = (is_bare_repository_cfg == 1) ||
106+
is_bare_repository() ||
107+
/*
108+
* When in a secondary worktree we have to also verify if the main
109+
* worktree is bare in $commondir/config.worktree.
110+
* This check is unnecessary if we're currently in the main worktree,
111+
* as prior checks already consulted all configs of the current worktree.
112+
*/
113+
(!worktree->is_current && is_main_worktree_bare(the_repository));
114+
92115
if (!skip_reading_head)
93116
add_head_info(worktree);
94117
return worktree;

0 commit comments

Comments
 (0)