mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-06 09:28:34 +00:00
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:
parent
ff5b97dc34
commit
e08507f3ce
@ -180,11 +180,14 @@ class GitStore:
|
|||||||
"""Check if self._workspace is already inside a git repository.
|
"""Check if self._workspace is already inside a git repository.
|
||||||
|
|
||||||
Walks up from self._workspace to the filesystem root, returning True
|
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()
|
current = self._workspace.resolve()
|
||||||
while current != current.parent:
|
while current != current.parent:
|
||||||
if (current / ".git").is_dir():
|
if (current / ".git").exists():
|
||||||
return True
|
return True
|
||||||
current = current.parent
|
current = current.parent
|
||||||
return False
|
return False
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
"""Tests for GitStore — line_ages() and core git operations."""
|
"""Tests for GitStore — line_ages() and core git operations."""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
@ -172,3 +173,44 @@ class TestNestedRepoProtection:
|
|||||||
|
|
||||||
assert result is True
|
assert result is True
|
||||||
assert (workspace / ".git").is_dir()
|
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()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user