Skip to content

fix(core): preserve trailing blank lines when applying patches - #51803

Closed
icearia0219 wants to merge 2 commits into
anomalyco:devfrom
icearia0219:patch-blank-lines
Closed

icearia0219 wants to merge 2 commits into
anomalyco:devfrom
icearia0219:patch-blank-lines

Conversation

@icearia0219

@icearia0219 icearia0219 commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Issue for this PR

Closes #42081

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Preserve trailing blank lines when apply_patch changes another part of a file. Both patch implementations now remember whether they removed the trailing split sentinel and restore it, rather than confusing a blank content line with that sentinel.

This revisits #42084 by @codeAnqiang-ma, which was closed by automated cleanup. Credit to that issue/PR for the diagnosis and approach. The bug still reproduces on current dev; this submission adds repeated-edit coverage and checks the reported diff counts. Explicit blank-line removal still works.

Following review, pure additions in the legacy implementation now append after all content lines, including genuine blank lines; the split sentinel has already been removed before insertion.

Authored and locally verified by Codex with the account owner's authorization; no manual user or full CLI/LLM end-to-end validation.

How did you verify your code works?

On Windows with Bun 1.3.14:

  • Before the fix: four new regression cases fail across the two implementations.
  • The review follow-up adds six pure-addition cases per implementation; three legacy cases fail before the insertion fix.
  • packages/core: bun test test/patch.test.ts test/tool-apply-patch.test.ts — 26 pass.
  • packages/opencode: bun test test/patch/patch.test.ts test/tool/apply_patch.test.ts --timeout 30000 — 55 pass.
  • bun typecheck passes in both packages.
  • Formatting and git diff --check pass. Oxlint reports zero errors and the same 16 warnings as the unchanged base for these files.

Tests use real temporary files, including repeated updates through tool settlement and the legacy patch API. The full repository suite was not run.

Screenshots / recordings

N/A — no UI changes.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Fixes anomalyco#42081
Revisits the approach in anomalyco#42084 by codeAnqiang-ma, closed by automated cleanup.

Signed-off-by: icearia0219 <[email protected]>
Copilot AI lite review requested due to automatic review settings September 28, 2026 08:12
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

The legacy implementation mishandles pure additions when genuine trailing blank lines remain.

Review effort: Lite
Findings: None

What changed in this PR

Fixes apply_patch trailing blank-line preservation in both patch implementations.

Changes:

  • Preserve trailing newline sentinels during patch application.
  • Add regression tests for repeated edits, BOMs, explicit removal, and diff counts.
File Description
packages/​opencode/​test/​patch/​patch.test.ts Tests repeated legacy updates.
packages/​opencode/​src/​patch/​index.ts Applies the legacy patch fix.
packages/​core/​test/​tool-apply-patch.test.ts Tests repeated tool updates and diff counts.
packages/​core/​test/​patch.test.ts Tests newline and BOM behavior.
packages/​core/​src/​patch.ts Preserves trailing newline state.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@icearia0219

Copy link
Copy Markdown
Contributor Author

Reproduced and fixed in 5026e30.

The legacy pure-addition branch subtracted one from the insertion index when the last line was empty, even though deriveNewContentsFromChunks had already removed the split sentinel. For before\n\n plus an insertion-only +added hunk, it produced before\nadded\n\n instead of before\n\nadded\n. It now appends at originalLines.length, matching core.

Added six cases per implementation covering empty files, blank-only files, unterminated text, and one or more trailing newlines. Three legacy cases fail without this follow-up. After the fix, the selected core suites pass 26 tests and the legacy suites pass 55 tests; both package typechecks pass. The PR description includes the updated verification results.

@thdxr

thdxr commented Oct 10, 2026

Copy link
Copy Markdown
Member

This branch has been upgraded to V2. We're no longer taking PRs for V1. If you think this is still relevant, please port it over and open it for V2.

— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

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 deletes the final blank line of files that end with one

3 participants