Skip to content

Commit 180b1ff

Browse files
Byroncodex
andcommitted
fix: keep bare-repository worktrees non-bare (#2223)
<!-- agent --> Opening a linked worktree created from a bare repository read `core.bare` from the common repository and discarded the worktree path. Keep a discovered linked worktree non-bare when its administrative directory has a `commondir` marker. The regression compares Git rev-parse behavior and verifies Repo.bare and working_tree_dir. Git baseline: 0bd5a6920d7c4238e0d90ddc0e7e08866e84a0f1; environment.c:is_bare_repository() and setup.c:check_repository_format_gently(). Git 2.50.1 reports the linked checkout as non-bare. Assisted-by: GPT 5.6 Co-authored-by: GPT 5.6 <codex@openai.com>
1 parent 589d8af commit 180b1ff

2 files changed

Lines changed: 21 additions & 0 deletions

File tree

git/repo/base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@ def __init__(
386386
# Let's not assume the option exists, although it should.
387387
pass
388388

389+
# A linked worktree is not bare even when its main repository is.
390+
if self._bare and self._working_tree_dir and osp.isfile(osp.join(self.git_dir, "commondir")):
391+
self._bare = False
392+
389393
# Adjust the working directory in case we are actually bare - we didn't know
390394
# that in the first place.
391395
if self._bare:

test/test_repo.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,23 @@ def test_git_work_tree_dotgit(self, rw_dir, use_relative_paths=False):
14591459

14601460
self.assertIsInstance(repo.heads["aaaaaaaa"], Head)
14611461

1462+
@with_rw_directory
1463+
def test_git_work_tree_from_bare_repo(self, rw_dir):
1464+
if Git().version_info[:3] < (2, 5, 1):
1465+
pytest.skip("worktree feature unsupported, needs git 2.5.1 or later")
1466+
1467+
bare_repo = self.rorepo.clone(join_path_native(rw_dir, "bare_repo"), bare=True)
1468+
worktree_path = join_path_native(rw_dir, "worktree_repo")
1469+
if Git.is_cygwin():
1470+
worktree_path = cygpath(worktree_path)
1471+
bare_repo.git.worktree("add", "--detach", worktree_path)
1472+
1473+
repo = Repo(worktree_path)
1474+
1475+
assert Git(worktree_path).rev_parse("--is-bare-repository") == "false"
1476+
assert not repo.bare
1477+
assert osp.samefile(repo.working_tree_dir, worktree_path)
1478+
14621479
def test_git_work_tree_dotgit_relative(self):
14631480
"""Check that we find .git as a worktree file containing a relative path
14641481
and find the worktree based on it."""

0 commit comments

Comments
 (0)