extract_paths_from_patch splits unquoted Git paths containing spaces

Open 💬 0 comments Opened Jul 18, 2026 by Kevinjohn

extract_paths_from_patch returns incorrect paths when Git emits an unquoted diff --git header for a filename containing spaces.

What issue are you seeing?

  • Observable sequence: Git emits diff --git a/hello world.txt b/hello world.txt.
  • Expected: extract_paths_from_patch returns ["hello world.txt"].
  • Actual: it returns ["hello", "world.txt"].
  • Tested revision: 312caf176a8fd3a5897a3d1fd3ed0a283bd1b5ac (main).
  • Environment: macOS 26.5.2, Git 2.55.0, Rust 1.95.0.

The first command in the screenshot shows that Git itself emits the path unquoted. The focused reproduction then shows the parser result.

Actual screenshot

!Terminal reproduction showing an unquoted Git path with spaces being split into two parsed paths

What steps can reproduce the bug?

Create a file whose name contains a space and inspect Git's header:

git diff --no-index -- /dev/null '/private/tmp/hello world.txt' | head -1

Git emits:

diff --git a/private/tmp/hello world.txt b/private/tmp/hello world.txt

The parser can be reproduced directly with:

use codex_git_utils::extract_paths_from_patch;

fn main() {
    let patch = "diff --git a/hello world.txt b/hello world.txt\n";
    assert_eq!(
        extract_paths_from_patch(patch),
        vec!["hello world.txt".to_string()]
    );
}

The assertion fails because the current result is ["hello", "world.txt"].

What is the expected behavior?

The parser should preserve the complete filename and never return partial whitespace-delimited fragments from an unquoted Git header.

Additional information

read_diff_git_token currently ends every unquoted token at the first whitespace. That works for quoted headers, but Git does not necessarily quote a path merely because it contains a space.

This remaining case was also noted and acknowledged during the review of merged PR #8824.

A focused fix could:

  1. Prefer the single-path ---, +++, rename from/to, and copy from/to metadata lines, preserving spaces and the existing C-style unescaping.
  2. Retain a safe diff --git fallback for mirrored a/<path> b/<path> headers, including binary diffs.
  3. Avoid returning partial tokens when an unquoted header is ambiguous.
  4. Add regression coverage for unquoted spaces while retaining the existing quoted-path, escape, and /dev/null cases.

---

I have a PR made, if this metadata-first approach is consistent with the intended parser behavior?

View original on GitHub ↗