From 377af757308dd9a3324bf5207519a658049bf321 Mon Sep 17 00:00:00 2001 From: Jeremy Rose <172423086+nornagon-openai@users.noreply.github.com> Date: Thu, 11 Sep 2025 09:07:03 -0700 Subject: [PATCH] apply-patch: sort replacements and add regression tests (#3425) - Ensure replacements are applied in index order for determinism. - Add tests for addition chunk followed by removal and worktree-aware helper. This fixes a panic I observed. Co-authored-by: Codex <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com> --- codex-rs/apply-patch/src/lib.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/codex-rs/apply-patch/src/lib.rs b/codex-rs/apply-patch/src/lib.rs index 1fdd6928e..de22173c2 100644 --- a/codex-rs/apply-patch/src/lib.rs +++ b/codex-rs/apply-patch/src/lib.rs @@ -733,6 +733,8 @@ fn compute_replacements( } } + replacements.sort_by(|(lhs_idx, _, _), (rhs_idx, _, _)| lhs_idx.cmp(rhs_idx)); + Ok(replacements) } @@ -1216,6 +1218,33 @@ PATCH"#, assert_eq!(contents, "a\nB\nc\nd\nE\nf\ng\n"); } + #[test] + fn test_pure_addition_chunk_followed_by_removal() { + let dir = tempdir().unwrap(); + let path = dir.path().join("panic.txt"); + fs::write(&path, "line1\nline2\nline3\n").unwrap(); + let patch = wrap_patch(&format!( + r#"*** Update File: {} +@@ ++after-context ++second-line +@@ + line1 +-line2 +-line3 ++line2-replacement"#, + path.display() + )); + let mut stdout = Vec::new(); + let mut stderr = Vec::new(); + apply_patch(&patch, &mut stdout, &mut stderr).unwrap(); + let contents = fs::read_to_string(path).unwrap(); + assert_eq!( + contents, + "line1\nline2-replacement\nafter-context\nsecond-line\n" + ); + } + /// Ensure that patches authored with ASCII characters can update lines that /// contain typographic Unicode punctuation (e.g. EN DASH, NON-BREAKING /// HYPHEN). Historically `git apply` succeeds in such scenarios but our