Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

worktree: detect from secondary worktree if main worktree is bare #1829

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions t/t3200-branch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,20 @@ test_expect_success 'bare main worktree has HEAD at branch deleted by secondary
git -C secondary branch -D main
'

test_expect_success 'secondary worktree can switch to main if common dir is bare worktree' '
test_when_finished "rm -rf bare_repo non_bare_repo secondary_worktree" &&
git init -b main non_bare_repo &&
test_commit -C non_bare_repo x &&

git clone --bare non_bare_repo bare_repo &&
git -C bare_repo config extensions.worktreeConfig true &&
git -C bare_repo config unset core.bare &&
git -C bare_repo config --worktree core.bare true &&

git -C bare_repo worktree add ../secondary_worktree &&
git -C secondary_worktree checkout main
'

test_expect_success 'git branch --list -v with --abbrev' '
test_when_finished "git branch -D t" &&
git branch t &&
Expand Down
38 changes: 29 additions & 9 deletions worktree.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,28 @@ static int is_current_worktree(struct worktree *wt)
return is_current;
}

static int is_bare_git_dir(const char *git_dir)
{
int bare = 0;
struct config_set cs = { { 0 } };
char *config_file;
char *worktree_config_file;

config_file = xstrfmt("%s/config", git_dir);
worktree_config_file = xstrfmt("%s/config.worktree", git_dir);

git_configset_init(&cs);
git_configset_add_file(&cs, config_file);
git_configset_add_file(&cs, worktree_config_file);

git_configset_get_bool(&cs, "core.bare", &bare);

git_configset_clear(&cs);
free(config_file);
free(worktree_config_file);
return bare;
}

/**
* get the main worktree
*/
Expand All @@ -76,18 +98,16 @@ static struct worktree *get_main_worktree(int skip_reading_head)
strbuf_strip_suffix(&worktree_path, "/.git");

CALLOC_ARRAY(worktree, 1);
/*
* NEEDSWORK: the_repository is not always main worktree's repository
*/
worktree->repo = the_repository;
worktree->path = strbuf_detach(&worktree_path, NULL);
/*
* NEEDSWORK: If this function is called from a secondary worktree and
* config.worktree is present, is_bare_repository_cfg will reflect the
* contents of config.worktree, not the contents of the main worktree.
* This means that worktree->is_bare may be set to 0 even if the main
* worktree is configured to be bare.
*/
worktree->is_bare = (is_bare_repository_cfg == 1) ||
is_bare_repository();
worktree->is_current = is_current_worktree(worktree);
worktree->is_bare = (is_bare_repository_cfg == 1) ||
is_bare_repository() ||
(!worktree->is_current && is_bare_git_dir(repo_get_common_dir(the_repository)));

if (!skip_reading_head)
add_head_info(worktree);
return worktree;
Expand Down
Loading