apply_patch reports success for no-op update hunks
Summary
apply_patch currently reports success for a no-op update hunk: the CLI exits 0 and prints M <file> even when the target file bytes are unchanged.
This is not about normal hunk mismatch failures. If the old lines do not match the file, apply_patch correctly returns Failed to find expected lines. The problematic case is when the old lines do match, but the replacement computes to identical file contents, causing a no-op update to be reported as a successful modification.
Reproduction
Create modify.txt:
line1
line2
Run this patch:
*** Begin Patch
*** Update File: modify.txt
@@
-line2
+line2
*** End Patch
Current behavior on main
I reproduced this against a clean main worktree at commit a7dcd20d38:
exit:0
stdout:
Success. Updated the following files:
M modify.txt
stderr:
file content:
line1
line2
sha256 before:2751a3a2f303ad21752038085e2b8c5f98ecff61a2e4ebbd43506a941725be80
sha256 after:2751a3a2f303ad21752038085e2b8c5f98ecff61a2e4ebbd43506a941725be80
changed: no
The file content and hash are unchanged, but the command reports a successful modification.
Expected behavior
A patch that produces no actual file changes should not report success as a modification. A clearer behavior is a non-zero exit with:
No files were modified.
Root-cause hypothesis
In codex-rs/apply-patch/src/lib.rs, apply_hunks_to_files derives new_contents for update hunks and records the path as modified after writing it. It does not check whether new_contents == original_contents, so a same-text replacement can be counted as a modification even though the bytes are unchanged.
Local fix branch
I have a focused local fix and regression tests here:
https://github.com/myersguo/codex/tree/codex/reject-noop-apply-patch
Commit:
477d5ba751 Reject no-op apply_patch updates
The fix skips non-rename update hunks whose computed new_contents equals original_contents; if all hunks are no-ops, the CLI returns No files were modified..
Fixed behavior from local branch
exit:1
stdout:
stderr:
No files were modified.
file content:
line1
line2
sha256 before:2751a3a2f303ad21752038085e2b8c5f98ecff61a2e4ebbd43506a941725be80
sha256 after:2751a3a2f303ad21752038085e2b8c5f98ecff61a2e4ebbd43506a941725be80
changed: no
Validation
On the local fix branch:
just fmt
just test -p codex-apply-patch
just fix -p codex-apply-patch
git diff --check
Latest targeted test result:
Summary [2.442s]88 tests run:88 passed,0 skipped
I am opening this issue first per the contribution guidelines, since external code PRs are by invitation only.