zed-industries/zed · error

unexpected git-show output for {commit:?}: {output:?}

Error message

unexpected git-show output for {commit:?}: {output:?}

What it means

Commit details are parsed from `git show --no-patch --format=%H%x00%B%x00%at%x00%ae%x00%an%x00 <commit>`; the code splits stdout on NUL and requires exactly 6 fields (sha, body, timestamp, email, name, trailing empty). Any other field count bails with the whole output in Debug form. Since the format always emits five NULs, a count != 6 means the output itself was perturbed — most plausibly NUL bytes inside the commit message body.

Source

Thrown at crates/git/src/repository.rs:1376

            cx.update(|cx| {
                cx.path_for_auxiliary_executable("git")
                    .context("could not find git binary path")
                    .log_err()
            })
        } else {
            None
        };

    let git = GitBinary::new(
        git_binary_path.unwrap_or(PathBuf::from("git")),
        paths::home_dir().clone(),
        paths::home_dir().join(".git"),
        cx.background_executor().clone(),
        true,
    );

    cx.background_spawn(async move {
        let name = git
            .run(&["config", "--global", "user.name"])
            .await
            .log_err();
        let email = git
            .run(&["config", "--global", "user.email"])
            .await
            .log_err();
        GitCommitter { name, email }
    })
    .await
}

fn parse_remote_urls(stdout: &str) -> HashMap<String, String> {
    let mut urls = HashMap::default();
    for line in stdout.lines() {
        if let Some((line, suffix)) = line.rsplit_once(" (fetch)")
            && (suffix.is_empty() || suffix.starts_with(" [") && suffix.ends_with(']'))
            && let Some((name, url)) = line.split_once(char::is_whitespace)

View on GitHub (pinned to 5a9b9558db)

Solutions

  1. Reproduce: git show --no-patch --format='%H%x00%B%x00%at%x00%ae%x00%an%x00' <commit> | tr '\0' '\n' and count the fields
  2. Inspect the commit with `git cat-file commit <sha>` for NUL bytes or odd header content
  3. Check `git replace -l` and info/grafts and remove any perturbing refs
  4. If the commit is genuinely malformed, rewrite/redact it (filter-repo) or skip details for it
Defensive patterns

Strategy: validation

Validate before calling

let fields = output.split('\0').collect::<Vec<_>>();
if fields.len() != 6 {
    // dump the raw stdout for diagnosis instead of bubbling the bail
    log::warn!("unexpected git-show fields: {fields:?}");
}

Type guard

fn is_parseable_show_output(output: &str) -> bool {
    output.split('\0').count() == 6
}

Try / catch

match details(commit).await {
    Ok(d) => Ok(d),
    Err(e) if e.to_string().contains("unexpected git-show output") => { /* fall back to log --format=1 parsing */ }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Loading commit details for a commit whose message body contains NUL bytes (created via plumbing or forged objects), output polluted by replace refs/grafts, or a git wrapper emitting extra content to stdout.

Common situations: Repositories containing pathological hand-crafted commits, `git replace` refs in play, or tools wrapping git that prepend banners to stdout.

Related errors


AI-assisted analysis of zed-industries/zed@5a9b9558db (2026-08-20). Data as JSON: /api/errors/2b5a15654fe022aa. Report an issue: GitHub.