Add a line-ending preservation mode to apply_patch (#37757)

## Why

Updating a file with `apply_patch` historically normalized its contents to LF,
which can rewrite line endings outside the requested change.

## What changed

- Add an opt-in `PreserveLineEndings` update mode and thread it through patch
  verification, application, and the standalone executable. Existing APIs keep
  the LF-normalizing mode by default.
- Retain the original endings of untouched and context lines, including in
  mixed-ending files, and use the file's first line ending for inserted or
  replaced lines.
- Track patch context separately from identical changed lines so preservation
  does not alter replacement ordering or matching.

## Testing

Add coverage for CRLF, CR, mixed endings, trailing blank lines, repeated lines,
EOF overlap rejection, and legacy LF normalization.

GitOrigin-RevId: 085f0cbc57e0965aa62c6a2d0e80870424e762f5
This commit is contained in:
Charlie Marsh
2026-08-10 01:39:55 +00:00
committed by copyberry
parent f344a80a3b
commit 21aa552e87
19 changed files with 1174 additions and 520 deletions
@@ -67,8 +67,10 @@ pub fn run_main() -> i32 {
};
// TODO(anp): Discover the standalone executable cwd as PathUri directly.
let cwd = codex_utils_path_uri::PathUri::from_abs_path(&cwd);
match runtime.block_on(crate::apply_patch(
let update_file_mode = crate::apply_patch_file_update_mode_from_env();
match runtime.block_on(crate::apply_patch_with_mode(
&patch_arg,
update_file_mode,
&cwd,
&mut stdout,
&mut stderr,