fix: Windows E2E failures — MSYS path normalization and test fixes#835
Open
fix: Windows E2E failures — MSYS path normalization and test fixes#835
Conversation
…est race Fix two E2E test failures from CI run #23889606598: 1. filterToUncommittedFiles compares working tree content with HEAD blob content using raw bytes. On Windows with core.autocrlf=true, the working tree has CRLF while git blobs store LF, causing the comparison to fail and committed files to be incorrectly treated as uncommitted. This created spurious shadow branches after subagent commits. Fix: normalize CRLF to LF before comparing. 2. TestInteractiveMultiStep reads the checkpoint branch immediately after WaitForCheckpoint, but the turn-end hook's finalize step writes a second commit to the same branch concurrently. Reading mid-update can see a broken ref. Fix: add WaitForSessionIdle before checkpoint assertions. Entire-Checkpoint: 8141fe489b5a
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes two Windows-/timing-related issues that were causing flaky or incorrect behavior in checkpoint/session handling.
Changes:
- Normalizes CRLF → LF when comparing working-tree content to HEAD in
filterToUncommittedFilesto avoid false “modified” detection on Windows withcore.autocrlf. - Adds an explicit “session idle” wait in an E2E interactive test to avoid reading checkpoint refs mid-finalize.
- Adds unit regression tests covering CRLF normalization and “real modification” behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| e2e/tests/interactive_test.go | Adds a wait to avoid a race between checkpoint finalize writes and checkpoint branch reads. |
| cmd/entire/cli/state.go | Updates working-tree vs HEAD comparison to normalize CRLF line endings on Windows. |
| cmd/entire/cli/state_test.go | Adds unit tests to validate CRLF normalization behavior and ensure true content changes are still detected. |
…erToUncommittedFiles Entire-Checkpoint: 9a6f73c4cfe0
Entire-Checkpoint: ee1c6a0cbbed
Entire-Checkpoint: 1e6a888663be
…ompt - Revert CRLF normalization in filterToUncommittedFiles since it didn't fix the Windows failure. Add diagnostic logging instead to identify the actual root cause on the next CI run. - Fix TestMidTurnCommit prompt: replace "Do not include any trailers or metadata" with "Do not add Co-authored-by or Signed-off-by trailers" to prevent cursor-cli from stripping Entire's hook-added trailers. Entire-Checkpoint: 0e96c87393c4
Replace go-git content comparison with git status --porcelain in filterToUncommittedFiles. go-git's raw byte comparison doesn't handle line-ending normalization (core.autocrlf) on Windows, causing committed files to appear as modified. This created spurious shadow branches after subagent commits, failing TestSingleSessionSubagentCommitInTurn in 6/6 consecutive Windows CI runs. Uses git CLI which handles all normalization correctly, matching the existing pattern for go-git workarounds (HardResetWithProtection, HasUncommittedChanges). Also strengthen resume test prompts with "or approval" to prevent Claude Code from asking for file write permissions on Windows. Entire-Checkpoint: 3b132e6ccfdf
git status needs to run from the repo root since the file paths are repo-root-relative. Without this, running the stop hook from a subdirectory causes path mismatch and skips the checkpoint. Entire-Checkpoint: c0ebbbd30d28
Ensure test repos exercise CRLF line-ending normalization by setting core.autocrlf=true in both E2E (SetupRepo) and integration (InitRepo) test setup. go-git v6 supports autocrlf in worktree operations, and this makes the test environment consistent with Windows CI where autocrlf is typically enabled globally. Entire-Checkpoint: b5d9ef5ea680
…ttedFiles The git CLI replacement wasn't necessary. go-git v6 supports core.autocrlf — the real fix is setting core.autocrlf=true in the test repos (previous commit), which makes go-git handle line-ending normalization correctly. Entire-Checkpoint: 17f8316a512d
Add DEBUG-level logging to each decision point in filterToUncommittedFiles to diagnose why committed files are not filtered on Windows. Logs include: fail-open errors, tree lookup failures, content comparison results with lengths and first 20 bytes of each side (quoted). No behavior change. Entire-Checkpoint: d6d5c61790f9
Claude Code on Windows outputs MSYS-style paths (/c/Users/...) in its transcript. Go's filepath.IsAbs doesn't recognize these as absolute on Windows, so ToRelativePath returned them unchanged. This caused filterToUncommittedFiles to pass the full MSYS path to headTree.File(), which failed with "file not found" since the git tree only has repo-relative paths like docs/red.md. Fix: normalize MSYS paths (/c/Users/... -> C:/Users/...) before processing in ToRelativePath. Confirmed via diagnostic logging that this was the root cause of TestSingleSessionSubagentCommitInTurn failing in 7/7 consecutive Windows CI runs. Entire-Checkpoint: abf133710085
MSYS/Git Bash on Windows sometimes omits the drive letter, producing paths like /Users/runneradmin/... instead of /c/Users/.... When this happens, prepend the drive letter from cwd (e.g. C:) so filepath.IsAbs and filepath.Rel can process them correctly. Previous fix only handled /c/... style paths. This covers both variants seen in CI: /c/Users/... and /Users/.... Entire-Checkpoint: 1b475aaf607d
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Fixes Windows E2E test failures that have been failing consistently (7/7 runs on main).
Root cause: MSYS path normalization — Claude Code on Windows outputs MSYS/Git Bash-style paths (
/c/Users/...) in its transcript. Go'sfilepath.IsAbsdoesn't recognize these as absolute on Windows, soToRelativePathreturned them unchanged. This causedfilterToUncommittedFilesto pass the full MSYS path toheadTree.File(), which failed with "file not found" since the git tree only has repo-relative paths likedocs/red.md. The function then kept the file (fail-open), creating a spurious shadow branch.Changes
cmd/entire/cli/paths/paths.go— AddnormalizeMSYSPathto convert/c/Users/...toC:/Users/...on Windows beforefilepath.IsAbs/filepath.Relprocessingcmd/entire/cli/state.go— Add diagnostic DEBUG logging tofilterToUncommittedFiles(how we found the root cause)cmd/entire/cli/testutil/testutil.go+e2e/testutil/repo.go— Setcore.autocrlf=truein test repos for consistent Windows behaviore2e/tests/interactive_test.go— AddWaitForSessionIdlebefore checkpoint assertions to fix race condition (TestInteractiveMultiStep opencode failure)e2e/tests/mid_turn_commit_test.go— Replace "Do not include any trailers or metadata" with specific trailer names to prevent cursor-cli from stripping hook-added trailerse2e/tests/resume_test.go— Add "or approval" to anti-confirmation prompts for Windows agent behaviorTest plan
TestNormalizeMSYSPath,TestFilterToUncommittedFiles_ReallyModified)