Skip to content

Commit d3cb53c

Browse files
codexByron
authored andcommitted
fix: keep bare-repository worktrees non-bare (#2223)
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. Validation: 12 focused repository discovery/worktree tests and 7 test_base.py tests passed; ruff check, ruff format --check, and codespell passed.
1 parent 589d8af commit d3cb53c

2 files changed

Lines changed: 16 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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,18 @@ 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+
bare_repo = self.rorepo.clone(join_path_native(rw_dir, "bare_repo"), bare=True)
1465+
worktree_path = join_path_native(rw_dir, "worktree_repo")
1466+
bare_repo.git.worktree("add", "--detach", worktree_path)
1467+
1468+
repo = Repo(worktree_path)
1469+
1470+
assert Git(worktree_path).rev_parse("--is-bare-repository") == "false"
1471+
assert not repo.bare
1472+
assert osp.samefile(repo.working_tree_dir, worktree_path)
1473+
14621474
def test_git_work_tree_dotgit_relative(self):
14631475
"""Check that we find .git as a worktree file containing a relative path
14641476
and find the worktree based on it."""

0 commit comments

Comments
 (0)