fix: handle git worktrees in GitStore nested repo protection
Treat `.git` files the same as `.git` directories so GitStore refuses to initialize inside git worktrees, and add a focused regression test for that checkout shape. Made-with: Cursor
This commit is contained in:
@@ -180,11 +180,14 @@ class GitStore:
|
||||
"""Check if self._workspace is already inside a git repository.
|
||||
|
||||
Walks up from self._workspace to the filesystem root, returning True
|
||||
if any parent directory contains a .git directory.
|
||||
if any parent directory contains a .git entry.
|
||||
|
||||
Git worktrees and submodules can use a ``.git`` file instead of a
|
||||
directory, so we must treat either form as "already inside a repo".
|
||||
"""
|
||||
current = self._workspace.resolve()
|
||||
while current != current.parent:
|
||||
if (current / ".git").is_dir():
|
||||
if (current / ".git").exists():
|
||||
return True
|
||||
current = current.parent
|
||||
return False
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Tests for GitStore — line_ages() and core git operations."""
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from unittest.mock import patch
|
||||
@@ -172,3 +173,44 @@ class TestNestedRepoProtection:
|
||||
|
||||
assert result is True
|
||||
assert (workspace / ".git").is_dir()
|
||||
|
||||
def test_init_refuses_inside_git_worktree(self, tmp_path):
|
||||
"""init() should refuse when the parent checkout is a git worktree."""
|
||||
repo = tmp_path / "repo"
|
||||
repo.mkdir()
|
||||
subprocess.run(["git", "init", "-q", str(repo)], check=True)
|
||||
(repo / "README.md").write_text("x\n", encoding="utf-8")
|
||||
subprocess.run(["git", "-C", str(repo), "add", "README.md"], check=True)
|
||||
subprocess.run(
|
||||
[
|
||||
"git",
|
||||
"-C",
|
||||
str(repo),
|
||||
"-c",
|
||||
"user.name=test",
|
||||
"-c",
|
||||
"user.email=test@example.com",
|
||||
"commit",
|
||||
"-q",
|
||||
"-m",
|
||||
"init",
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
subprocess.run(["git", "-C", str(repo), "branch", "wt-branch"], check=True)
|
||||
|
||||
worktree = tmp_path / "worktree"
|
||||
subprocess.run(
|
||||
["git", "-C", str(repo), "worktree", "add", "-q", str(worktree), "wt-branch"],
|
||||
check=True,
|
||||
)
|
||||
assert (worktree / ".git").is_file()
|
||||
|
||||
workspace = worktree / "workspace"
|
||||
workspace.mkdir()
|
||||
|
||||
g = GitStore(workspace, tracked_files=["MEMORY.md"])
|
||||
result = g.init()
|
||||
|
||||
assert result is False
|
||||
assert not (workspace / ".git").exists()
|
||||
|
||||
Reference in New Issue
Block a user