fix(mcp): avoid git from non-repo cwd in sibling cwd match (#1138)#1293
Conversation
checkCwdMatch used getGitRoot(cwd), which runs git rev-parse from the launch cwd (often \C:\Users\gergo in MCP stdio). Resolve the cwd git root via ancestor .git checks first, then keep existing remote-based sibling logic. Fixes #1138 Co-authored-by: Cursor <cursoragent@cursor.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @magyargergo's task in 3m 45s —— View job PR #1293 Review — fix(mcp): avoid git from non-repo cwd in sibling cwd matchTasks:
Review bar for this PR
Issue and PR context considered#1138 symptom: MCP stdio servers launch with Changed files: CI status (at time of review):
Local validation claims: focused tests passed, Core risks: Understanding of the changeBefore this PR: After this PR: Unchanged stages:
Findings[medium] No-spawn assertion in sibling drift test is behaviorally weak
[medium] Linked worktree / .git-as-file case not tested
[low] Nonexistent and file-input paths not tested
[critical — blocks merge] Windows CI and Docker still in progress
Definition of Done check
Git root detection assessment
Normal
Nonexistent paths: implementation handles it (initial statSync returns null), not tested File inputs: implementation handles it (dirname step), not tested Invalid Sibling drift assessmentExact/path match precedence: Unchanged. Lines 90–102 in Non-git cwd behavior: Sibling-by-remote behavior: Preserved. Once a Stale hint behavior: Remote fingerprint matching: No subprocess from arbitrary cwd: Confirmed by code inspection. Test assessment
No-spawn proof strength: Strong for Validation assessment
Final verdict
Windows CI ( The code fix itself is correct: Once Windows CI and Docker complete green, and the Vitest worker warning is confirmed non-causal, this can be re-evaluated as |
CI Report✅ All checks passed Pipeline Status
Test Results
✅ All 7790 tests passed 1 test(s) skipped — expand for details
Code CoverageTests
📋 View full run · Generated by CI |
Three test gaps flagged by review on the #1138 fix: - sibling-clone-drift.test.ts: the existing "non-git cwd" test only asserted match=none, which the pre-fix code also returned (by silently failing the spawn). Wrap child_process / node:child_process with passthrough vi.fn() spies and assert no execSync/execFileSync call is recorded when checkCwdMatch runs against a non-git cwd, so a regression that re-introduces the spawn fails loudly. - git.test.ts: add coverage for findGitRootByDotGit's three untested inputs — a `.git` FILE (linked worktree / submodule), a path that does not exist, and a file path inside a repo (must walk from the parent dir). Each asserts no subprocess was spawned. No production code changes. Test additions only.
…atwari#1138) (abhigyanpatwari#1293) * fix(mcp): avoid git shellout from non-repo cwd for sibling match checkCwdMatch used getGitRoot(cwd), which runs git rev-parse from the launch cwd (often \C:\Users\gergo in MCP stdio). Resolve the cwd git root via ancestor .git checks first, then keep existing remote-based sibling logic. Fixes abhigyanpatwari#1138 Co-authored-by: Cursor <cursoragent@cursor.com> * test(mcp): address PR abhigyanpatwari#1293 review follow-ups Three test gaps flagged by review on the abhigyanpatwari#1138 fix: - sibling-clone-drift.test.ts: the existing "non-git cwd" test only asserted match=none, which the pre-fix code also returned (by silently failing the spawn). Wrap child_process / node:child_process with passthrough vi.fn() spies and assert no execSync/execFileSync call is recorded when checkCwdMatch runs against a non-git cwd, so a regression that re-introduces the spawn fails loudly. - git.test.ts: add coverage for findGitRootByDotGit's three untested inputs — a `.git` FILE (linked worktree / submodule), a path that does not exist, and a file path inside a repo (must walk from the parent dir). Each asserts no subprocess was spawned. No production code changes. Test additions only. --------- Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
MCP stdio servers often run with \process.cwd()\ set to a generic directory (for example the user home directory). \LocalBackend.resolveRepo()\ calls \checkCwdMatch(cwd)\ for sibling-clone drift warnings. That path used \getGitRoot(), which shells out to \git rev-parse\ from that cwd even when it is not inside any git work tree.
This change resolves the cwd git root with a cheap ancestor .git\ walk (\indGitRootByDotGit) before any \git\ subprocess runs for sibling detection. If there is no .git\ ancestor, we return \match: none\ immediately.
Related
findfrom $HOME instead of configured repo roots — trips macOS TCC prompts for Desktop / Music / Photos #1138Testing
Definition of Done
Made with Cursor