Skip to content

apply_patch rewrites CRLF and mixed line endings to LF on every update #47

Description

@code-yeongyu

Summary

Any *** Update File rewrites the whole file with LF line endings. In a CRLF repository, a one-line patch turns into a whole-file change: every line shows as modified in git and in the tool's own diff preview. Files with mixed endings get flattened too.

Reproduction

// lines.txt = "one\r\ntwo\r\nthree\r\n"
await applyPatchDetailed(cwd, "*** Begin Patch\n*** Update File: lines.txt\n@@\n-one\n+ONE\n two\n+between\n three\n*** End Patch\n")
// lines.txt is now "ONE\ntwo\nbetween\nthree\n"

Codex's portable conformance scenarios 023_preserves_crlf_line_endings and 024_preserves_mixed_line_endings (codex-rs/apply-patch/tests/fixtures/scenarios/) fail on this package.

Expected

Only the lines the patch changes are rewritten:

  • Unchanged lines, including the chunk's context lines, keep their exact text and ending.
  • Inserted lines take the file's first line ending (LF when the file has none).
  • The file still ends with a line ending, as today.

This is what Codex implements in codex-rs/apply-patch/src/text_file.rs and file_update.rs (compute_replacements, PreserveLineEndings) at b741e48. In Codex it currently ships behind the apply_patch_preserve_line_endings feature (under development, off by default), and its conformance scenarios run with it on. oh-my-pi restores the file's detected ending after an edit (packages/coding-agent/src/edit/normalize.ts).

Actual

Every line is rewritten with LF.

Acceptance

  • Scenarios 023 and 024 pass.
  • An LF-only file behaves exactly as before.
  • A failed hunk on a CRLF file leaves its bytes untouched.
  • The diff preview of a one-line change on a CRLF file counts one line.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions