fix(bootstrap): path-shaped branches ancestry without isdir (#850 review #551)

resolve_canonical_repo_root fallback now uses commonpath only — no
string split and no os.path.isdir gate — so MCP project_root =
branches/<wt> still resolves to the repo root when the path is not yet
on disk (#274 / review #551 regression).
This commit is contained in:
2026-07-24 07:54:07 -04:00
parent 06e95254f0
commit e1d844bfed
2 changed files with 22 additions and 12 deletions
+15 -12
View File
@@ -93,9 +93,10 @@ def resolve_canonical_repo_root(workspace_path: str, fallback_project_root: str)
pass
# Fallback when git metadata is unavailable. Never string-split on
# "/branches/" (review #531 Finding 2 / F-6): recover the repo root only
# via resolved-path commonpath ancestry against a parent that owns a
# real ``branches`` directory containing the fallback path.
# "/branches/" (review #531 F2 / #551): recover the repo root only via
# resolved-path commonpath ancestry. Do **not** require on-disk isdir —
# MCP may launch with project_root = branches/<wt> before that path
# exists, and #274 path-shaped worktree-as-project-root must still resolve.
fallback = os.path.realpath(fallback_project_root or workspace_path or ".")
cur = fallback
for _ in range(64):
@@ -103,16 +104,18 @@ def resolve_canonical_repo_root(workspace_path: str, fallback_project_root: str)
if parent == cur:
break
branches_dir = os.path.realpath(os.path.join(parent, "branches"))
if os.path.isdir(branches_dir):
try:
# Path-shaped: fallback is under parent/branches/ (commonpath).
if os.path.commonpath([branches_dir, fallback]) == branches_dir:
return parent
except ValueError:
pass
# Fallback path itself is the branches directory.
if os.path.basename(os.path.realpath(cur)) == "branches":
try:
if os.path.commonpath([branches_dir, fallback]) == branches_dir:
return parent
except ValueError:
pass
# Also accept fallback itself being the branches directory.
if os.path.basename(cur) == "branches" and os.path.isdir(cur):
try:
if os.path.commonpath([cur, fallback]) == cur:
if os.path.commonpath([os.path.realpath(cur), fallback]) == os.path.realpath(
cur
):
return parent
except ValueError:
pass