Skip to content

fix(core): preserve line endings in patch tool - #58324

Open
rekram1-node wants to merge 1 commit into
devfrom
patch-line-endings
Open

rekram1-node wants to merge 1 commit into
devfrom
patch-line-endings

Conversation

@rekram1-node

@rekram1-node rekram1-node commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #45926
Closes #54605

Problem

The patch tool rewrote every line it touched with \n, so a CRLF file ended up with mixed endings after any update.

 file:   foo\r\n bar\r\n      patch: foo -> FOO
-before: FOO\n   bar\r\n
+after:  FOO\r\n bar\r\n

Change

line the patch didn't touch        -> kept byte for byte
line marked as context (" x")      -> kept byte for byte
changed or added line              -> file's first line ending (LF if none)
unterminated last line             -> gets the file's first line ending

Uniform files stay uniform, and mixed files stay mixed outside the edited lines.

To keep context lines verbatim, the parser now records which old/new lines are context (contextIndices on each chunk). The ACP preview, which reverses chunks, swaps those indices too.

Out of scope

  • A lone \r is still part of the line text, matching how Read shows the file.
  • New files from *** Add File are still written with LF.

Builds on #45931 and #56128, both authors are credited as co-authors.


Added by the opencode bot (AI-generated).

Public API: adds optional contextIndices to UpdateFileChunk in @opencode/util/patch (backwards compatible)

Co-authored-by: pengzh1 <[email protected]>
Co-authored-by: Parker Fawcett <[email protected]>

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I reproduced #54605 on the base with the simulated model: after patching a CRLF file, the whole hunk came back LF while the untouched line kept CRLF. With this change every line keeps \r\n, and the TUI diff shows only the line that actually changed. The patch tests in packages/core pass, and tsc is clean for packages/util and packages/cli.

Public API: UpdateFileChunk in @opencode/util/patch gets an optional contextIndices field. This is backwards compatible: chunks built without it behave as before, apart from the line-ending fix. No SDK, HTTP, plugin or config surface changes.

No blocking concerns.

Before

After

This branch has not been deployed

No deployments
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.

apply_patch turns CRLF files into mixed line endings Opencode v2: Tool Patch messes up line endings in Windows

1 participant