Skip to content

git add <tab> truncates filenames containing spaces #271

Description

@nickeddy

Summary

In the Warp client, git add <tab> returns broken suggestions for any working-tree file whose name contains a space. The completion popup shows the filename truncated at the first space (often with a stray leading " from git's C-style quoting), and selecting the suggestion inserts the truncated string into the buffer. The user cannot stage files with spaces in their names via tab completion.

Reproduction

mkdir /tmp/repro && cd /tmp/repro
git init -q
touch "new file test.csv"

In Warp, type git add in /tmp/repro and press Tab.

Actual behavior

The popup shows a single suggestion that displays as "new (leading double-quote, content up to the first space, trailing space). Pressing Enter inserts that broken string into the buffer.

Expected behavior

The popup shows new file test.csv as a suggestion. Pressing Enter inserts a properly escaped form (new\ file\ test.csv for POSIX shells, or any equivalent that the shell will parse as the single token new file test.csv).

Environment

  • Warp version: v0.2026.05.13.09.15.stable_01
  • OS: Linux Mint 22.2 x86_64
  • Shell: zsh

Root cause

command-signatures/src/generators/git.rs:437-453 (in warpdotdev/command-signatures, pinned in warp's Cargo.toml at rev 00a032b8):

fn post_process_tracked_files(output: &str) -> GeneratorResults {
    let output = filter_messages(output);
    if output.starts_with("fatal:") {
        return GeneratorResults::default();
    }

    output
        .lines()
        // The first non-whitespace string is just a character indicating the type of indexed file.
        .filter_map(|file| file.split_whitespace().nth(1))   // <-- bug
        .map(|file| {
            Suggestion::with_description(file, "Changed file")
                .with_priority(Priority::Global(Importance::More(Order(100))))
                .with_icon(IconType::File)
        })
        .collect_unordered_results()
}

This post-processor consumes the output of git --no-optional-locks status --short (registered as the files_for_staging generator at line 770-775 and referenced from command-signatures/json/git.json for the git add argument).

git status --short formats lines as XY <pathname>. By default (core.quotepath=true) git C-style-quotes pathnames with special characters, so an untracked file new file test.csv produces ?? "new file test.csv". file.split_whitespace().nth(1) returns only the second whitespace-delimited token ("new), discarding the rest of the path. That truncated string flows through unchanged as both the suggestion's display value and its insertion replacement.

The existing test test_post_process_tracked_files (same file, line 968) only covers paths without spaces, which is why the regression slipped through.

Suggested fix

Switch the command to -z mode and rewrite the parser to handle the binary-safe NUL-separated format:

  • Change the command to git --no-optional-locks status --short -z. NUL terminators replace newlines and disable C-style quoting entirely.
  • In the post-processor, split the output on '\0', take everything from byte 3 of each record (skipping the fixed-width XY prefix), and skip the source-path record that follows any rename or copy entry (status starting with R or C).

NUL bytes survive the warp runtime end-to-end:

  • Local subprocess executor: raw Vec<u8> from child.output().await.
  • In-band executor: hex-encoded by the bootstrap shell wrapper (od -An -v -tx1) and hex::decoded on the warp side, so each 0x00 byte round-trips cleanly.
  • TMUX executor: same event.output: Vec<u8> pipeline as in-band.

Notes

  • The fix lives in warpdotdev/command-signatures, not warpdotdev/warp. After the command-signatures PR merges, warp's Cargo.toml pin needs to be bumped in a follow-up PR.
  • A latent gap exists at crates/warp_completer/src/completer/engine/argument/v2.rs:685-751 (warp side): script-output suggestions go through From<signatures::Suggestion> for Suggestion with no shell-escaping of the replacement. Once the generator is fixed, plain filenames with spaces will still need escaping at insertion time. That's a separate fix in warp and probably warrants its own issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-to-implementThis issue is scoped out and ready to be worked on.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions