-
Notifications
You must be signed in to change notification settings - Fork 2.9k
fix(checkpoints): canonicalize core.worktree comparison to prevent Windows path mismatch failures #11346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix(checkpoints): canonicalize core.worktree comparison to prevent Windows path mismatch failures #11346
Conversation
Both issues from the previous review are resolved. No new issues found.
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
| /** | ||
| * Normalizes a file path for comparison by resolving relative segments, | ||
| * canonicalizing separators, and stripping trailing separators. | ||
| * On Windows, also lowercases for case-insensitive comparison. | ||
| */ | ||
| export function normalizePathForCompare(p: string, isWindows = process.platform === "win32"): string { | ||
| let normalized = path.resolve(path.normalize(p.trim())) | ||
|
|
||
| const root = path.parse(normalized).root | ||
| if (normalized.length > root.length && normalized.endsWith(path.sep)) { | ||
| normalized = normalized.slice(0, -1) | ||
| } | ||
|
|
||
| if (isWindows) { | ||
| normalized = normalized.toLowerCase() | ||
| } | ||
|
|
||
| return normalized | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The codebase already has arePathsEqual() which handles path normalization, trailing separator stripping, and case-insensitive comparison on win32. Using it here would avoid the duplication and the cross-platform test issues described in the next comment. The only gap is .trim() for git config output, which can be applied to the worktree value before passing it to arePathsEqual:
| /** | |
| * Normalizes a file path for comparison by resolving relative segments, | |
| * canonicalizing separators, and stripping trailing separators. | |
| * On Windows, also lowercases for case-insensitive comparison. | |
| */ | |
| export function normalizePathForCompare(p: string, isWindows = process.platform === "win32"): string { | |
| let normalized = path.resolve(path.normalize(p.trim())) | |
| const root = path.parse(normalized).root | |
| if (normalized.length > root.length && normalized.endsWith(path.sep)) { | |
| normalized = normalized.slice(0, -1) | |
| } | |
| if (isWindows) { | |
| normalized = normalized.toLowerCase() | |
| } | |
| return normalized | |
| } | |
| import { arePathsEqual } from "../../utils/path" |
Then at the comparison site: if (!arePathsEqual(worktree?.trim(), this.workspaceDir)). This was also the approach suggested by the issue investigator in #11343 (comment).
Fix it with Roo Code or mention @roomote and request a fix.
| it("treats forward and backslash paths as equal on Windows", () => { | ||
| expect(normalizePathForCompare("C:\\Users\\Dennis\\Repo", true)).toBe( | ||
| normalizePathForCompare("C:/Users/Dennis/Repo", true), | ||
| ) | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test fails on non-Windows CI (confirmed locally: 1 failed | 6 passed). Node.js path.resolve/path.normalize use the host OS's separator conventions, so on Linux backslashes are treated as literal filename characters, not separators. The isWindows parameter only controls case-folding, not separator behavior. The result on Linux is:
Expected: ".../c:/users/dennis/repo"
Received: ".../c:\users\dennis\repo"
If normalizePathForCompare is kept, this test needs to either be skipped on non-Windows platforms (describe.skipIf(process.platform !== "win32")) or restructured to not depend on cross-platform path module behavior.
Fix it with Roo Code or mention @roomote and request a fix.
…ndows path mismatch failures Closes RooCodeInc#11343
c30f78a to
88c3654
Compare
|
Thanks, good catches. Updated the PR:
|
Closes #11343
Summary
initShadowGit()comparedcore.worktreetothis.workspaceDirusing raw string equality, which fails on Windows when git stores the path with forward slashes but VS Code resolves it with backslashes, or when drive-letter casing differsarePathsEqual()utility fromsrc/utils/path.tswhich already handles path normalization and case-insensitive comparison on Windows.trim()oncore.worktreeoutput to handle trailing whitespace/newlines from git config readscore.worktreenow throws a clear error instead of producing a misleading mismatch messageTest plan
core.worktreedoes not cause false mismatch (stub-based integration test)core.worktreethrows explicit error (integration test with config unset)