Skip to content

Commit ec2642a

Browse files
committed
Merge branch 'jt/submodule-repo-is-with-worktree'
The logic to tell if a Git repository has a working tree protects "git branch -D" from removing the branch that is currently checked out by mistake. The implementation of this logic was broken for repositories with unusual name, which unfortunately is the norm for submodules these days. This has been fixed. * jt/submodule-repo-is-with-worktree: worktree: update is_bare heuristics
2 parents 5b5def9 + f3534c9 commit ec2642a

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

t/t3200-branch.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,30 @@ test_expect_success 'git branch --list -d t should fail' '
264264
test_must_fail git rev-parse refs/heads/t
265265
'
266266

267+
test_expect_success 'deleting checked-out branch from repo that is a submodule' '
268+
test_when_finished "rm -rf repo1 repo2" &&
269+
270+
git init repo1 &&
271+
git init repo1/sub &&
272+
test_commit -C repo1/sub x &&
273+
git -C repo1 submodule add ./sub &&
274+
git -C repo1 commit -m "adding sub" &&
275+
276+
git clone --recurse-submodules repo1 repo2 &&
277+
git -C repo2/sub checkout -b work &&
278+
test_must_fail git -C repo2/sub branch -D work
279+
'
280+
281+
test_expect_success 'bare main worktree has HEAD at branch deleted by secondary worktree' '
282+
test_when_finished "rm -rf nonbare base secondary" &&
283+
284+
git init nonbare &&
285+
test_commit -C nonbare x &&
286+
git clone --bare nonbare bare &&
287+
git -C bare worktree add --detach ../secondary master &&
288+
git -C secondary branch -D master
289+
'
290+
267291
test_expect_success 'git branch --list -v with --abbrev' '
268292
test_when_finished "git branch -D t" &&
269293
git branch t &&

worktree.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,24 @@ static struct worktree *get_main_worktree(void)
4949
struct worktree *worktree = NULL;
5050
struct strbuf path = STRBUF_INIT;
5151
struct strbuf worktree_path = STRBUF_INIT;
52-
int is_bare = 0;
5352

5453
strbuf_add_absolute_path(&worktree_path, get_git_common_dir());
55-
is_bare = !strbuf_strip_suffix(&worktree_path, "/.git");
56-
if (is_bare)
54+
if (!strbuf_strip_suffix(&worktree_path, "/.git"))
5755
strbuf_strip_suffix(&worktree_path, "/.");
5856

5957
strbuf_addf(&path, "%s/HEAD", get_git_common_dir());
6058

6159
worktree = xcalloc(1, sizeof(*worktree));
6260
worktree->path = strbuf_detach(&worktree_path, NULL);
63-
worktree->is_bare = is_bare;
61+
/*
62+
* NEEDSWORK: If this function is called from a secondary worktree and
63+
* config.worktree is present, is_bare_repository_cfg will reflect the
64+
* contents of config.worktree, not the contents of the main worktree.
65+
* This means that worktree->is_bare may be set to 0 even if the main
66+
* worktree is configured to be bare.
67+
*/
68+
worktree->is_bare = (is_bare_repository_cfg == 1) ||
69+
is_bare_repository();
6470
add_head_info(worktree);
6571

6672
strbuf_release(&path);

0 commit comments

Comments
 (0)