fix(agent): a parent directory the process cannot stat is not a crash while locating .git (#8751)
_find_git_root walked cwd's parents with Path.exists(); on hosts where a parent is mode 700 for another user that raised PermissionError out of prompt construction. Treat an unreadable ancestor as 'no .git here'.
This commit is contained in:
@@ -96,7 +96,15 @@ def _scan_context_content(content: str, filename: str) -> str:
|
||||
def _find_git_root(start: Path) -> Optional[Path]:
|
||||
"""Nearest ancestor (or *start* itself) containing ``.git``, else None."""
|
||||
current = start.resolve()
|
||||
return next((p for p in (current, *current.parents) if (p / ".git").exists()), None)
|
||||
# A parent the process may not stat (locked-down /home on shared hosts) is "no .git here", not a crash.
|
||||
return next((p for p in (current, *current.parents) if _exists_or_denied(p / ".git")), None)
|
||||
|
||||
|
||||
def _exists_or_denied(path: Path) -> bool:
|
||||
try:
|
||||
return path.exists()
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
def _find_hermes_md(cwd: Path) -> Optional[Path]:
|
||||
|
||||
@@ -586,6 +586,21 @@ class TestFindHermesMd:
|
||||
|
||||
|
||||
|
||||
def test_unreadable_parent_is_treated_as_no_git_root(self, tmp_path, monkeypatch):
|
||||
"""A parent the process cannot stat (#8751) must not raise out of prompt construction."""
|
||||
import os as _os
|
||||
project = tmp_path / "locked" / "proj"
|
||||
project.mkdir(parents=True)
|
||||
real_exists = Path.exists
|
||||
|
||||
def _exists(self):
|
||||
if self.parent == tmp_path / "locked" and self.name == ".git":
|
||||
raise PermissionError(13, "Permission denied", str(self))
|
||||
return real_exists(self)
|
||||
|
||||
monkeypatch.setattr(Path, "exists", _exists)
|
||||
assert _find_git_root(project) is None
|
||||
|
||||
def test_walks_to_git_root(self, tmp_path):
|
||||
(tmp_path / ".git").mkdir()
|
||||
(tmp_path / ".hermes.md").write_text("root rules")
|
||||
|
||||
Reference in New Issue
Block a user