fix: respect Git line-ending normalization in working-tree diffs - #835
fix: respect Git line-ending normalization in working-tree diffs#835mvanhorn wants to merge 1 commit into
Conversation
|
@mvanhorn is attempting to deploy a commit to the Modem Team on Vercel. A member of the Team first needs to authorize it. |
|
PR author is not in the allowed authors list. |
|
Blocking: This change adds A concrete example is an HTTP protocol fixture, where CRLF is meaningful: git init crlf-repro
cd crlf-repro
git config user.email test@example.com
git config user.name Test
mkdir fixtures
printf 'fixtures/*.http -text\n' > .gitattributes
printf 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n' > fixtures/request.http
git add .
git commit -m "add HTTP fixture"
# Simulate an editor incorrectly converting CRLF to LF.
printf 'GET / HTTP/1.1\nHost: example.com\n\n' > fixtures/request.httpGit correctly reports that the file changed: $ git status --short
M fixtures/request.http
$ git diff --numstat
3 3 fixtures/request.httpBut the command introduced by this PR suppresses the change completely: $ git diff --ignore-cr-at-eol --numstat
# no output
$ git diff --ignore-cr-at-eol
# no outputTherefore, after this PR,
The current regression test only covers: *.ts text eol=crlfThat is the positive normalization case. On Please add the inverse test using This comment was generated by Pi using gpt-5.6-sol |
Git can keep canonical LF content in its index while materializing CRLF in the working tree according to
.gitattributes, buthunk diffcurrently presents a one-line edit as a whole-file replacement. The same Git-produced patch renders correctly throughhunk patch -, isolating the defect to the bundled Git working-tree acquisition path rather than the shared patch parser or terminal renderer. The reported reproduction is concrete and applies to the defaultworking-tree-diffoperation, including a single-revision comparison whose new endpoint is still the live worktree. Staged and commit-to-commit reviews must retain their existing byte-sensitive comparison behavior.Summary
Use the Git endpoint resolution already owned by the bundled adapter to identify operations whose new side is the worktree, and make the patch, numstat, and watch-signature argument builders apply Git's CR-at-EOL comparison tolerance only for those operations. Keep the decision at the adapter/command boundary so patch parsing and renderer logic remain provider-neutral, and ensure the stats query and reload signature use the same comparison policy as the visible patch. Add focused builder coverage proving the flag is present only for worktree-backed inputs, plus a real-Git adapter regression that commits
.gitattributeswith*.ts text eol=crlf, edits one line in a CRLF checkout, and asserts the loaded patch/stats describe only that line.Validation
*.ts text eol=crlfand a CRLF worktree file changes one line; the adapter patch contains one deletion and one addition rather than every line, and its reported stats agree.hunk diffandhunk diff <single-ref>apply the worktree line-ending policy because their resolved new endpoint is the live worktree.hunk diff --stagedand explicit commit-to-commit ranges do not receive worktree-only CR-at-EOL tolerance, preserving exact stored-content comparisons.Fixes #818