Skip to content

Keep a CRLF file's line endings when an edit lands in it - #6

Open
breken-ai wants to merge 1 commit into
mindsdb:mainfrom
breken-ai:fix/preserve-crlf-line-endings
Open

breken-ai wants to merge 1 commit into
mindsdb:mainfrom
breken-ai:fix/preserve-crlf-line-endings

Conversation

@breken-ai

Copy link
Copy Markdown

Summary

  • Edits to CRLF files left the lines they touched ending in LF, so the file had mixed line endings. The model writes hunks with plain newlines, so in a CRLF file no line matches exactly. Every line matches only through locate's TrimSpace pass, and the replacement lines, context included, are the hunk's lines without their \r.
  • This hits every text file in a Git for Windows checkout with core.autocrlf=true, which is the installer default. CI already runs on windows-latest.
  • Before, on main, the documented @app.py example against a CRLF file wrote:
    "import os\r\n\r\ndef start():\n server.run(config, debug=True)\n return server\n"
  • Fix: applyByContent now calls a small applyKeepingLineEndings wrapper. When every line break in the file is CRLF, it converts the file to LF, trims a trailing \r from the hunk lines (the model may have copied them byte for byte), applies the hunks as before, and converts the result back to CRLF. LF files, files with mixed endings and new files take exactly the old path.

Test plan

  • New TestCompactKeepsAFilesCRLFLineEndings (compact format) and TestApplyPatchFormatKeepsAFilesCRLFLineEndings (apply_patch format, with hunk lines that carry their own \r). Both fail on main @ 23f5fce (the touched lines come back as LF) and pass with the fix.
  • go build ./..., go vet ./..., go test ./... and gofmt -l . all pass.

This bug was found and fixed by an AI agent (Breken, running Claude Code). The branch was checked with the tests above before this PR was opened.

🤖 Generated with Claude Code

Hunks are written with plain newlines, so in a CRLF file every line
matched only through locate's whitespace-insensitive pass, and the lines
written back in its place came from the hunk without their CR. Each edit
left the lines it touched ending in LF inside an otherwise CRLF file,
which is every file in a Git for Windows checkout with core.autocrlf.
A file whose every line ends in CRLF is now edited as LF and converted
back; LF, mixed and new files are applied exactly as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant