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:
kshitijk4poor
2026-09-05 18:55:47 +05:30
committed by kshitij
parent bb504a2e14
commit 337113c1b8
2 changed files with 24 additions and 1 deletions

View File

@@ -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]:

View File

@@ -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")