affaan-m/ECC · error

git rev-parse failed

Error message

git rev-parse failed: {stderr}

What it means

After a successful commit, commit_staged resolves the new HEAD with `git rev-parse --short HEAD` to return the short hash. If that command exits non-zero the library throws this error; the commit likely succeeded but the hash could not be resolved, which points to a repository-state problem.

Solutions

  1. Re-run git status / rev-parse manually to inspect repository state; the commit may still exist (check `git log -1`).
  2. Retry commit_staged if the race was transient and no commit was created — but first verify with `git log` to avoid duplicate commits.
  3. Investigate repository integrity with `git fsck` if errors persist.
  4. Avoid running concurrent git-mutating operations (IDE + this library) on the same worktree.

Example fix

// caller-side: handle partial success
match commit_staged(&worktree, msg) {
    Ok(hash) => println!("committed {hash}"),
    Err(e) if e.to_string().contains("rev-parse") => {
        // commit may exist; check before retrying
        let head = current_head(&worktree)?;
        println!("recoverable, HEAD={head}");
    }
    Err(e) => return Err(e),
}
Defensive patterns

Strategy: retry

Validate before calling

fn head_resolvable(worktree: &WorktreeInfo) -> bool {
    Command::new("git").arg("-C").arg(&worktree.path)
        .args(["rev-parse", "--verify", "HEAD"])
        .output().map(|o| o.status.success()).unwrap_or(false)
}

Type guard

None

Try / catch

match commit_staged(&worktree, &msg) {
    Ok(hash) => Ok(hash),
    Err(e) if e.to_string().contains("rev-parse") => {
        // commit likely succeeded; resolve HEAD once before retrying
        std::thread::sleep(std::time::Duration::from_millis(50));
        resolve_head(&worktree)
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Calling commit_staged when the follow-up rev-parse fails: another process detached HEAD or ran `git update-ref -d HEAD` between commit and rev-parse, repository corruption, or the commit actually failed silently in an edge case leaving HEAD unborn.

Common situations: Concurrent tooling mutating the repo mid-operation; corrupted .git/refs; running in an environment where git is a different version/shim misbehaving; very rare race with a parallel commit/checkout.

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/b22ef6d221b5da20. Report an issue: GitHub.

Appendix: source

Thrown at ecc2/src/worktree/mod.rs:483

        .arg("-C")
        .arg(&worktree.path)
        .args(["commit", "-m", message])
        .output()
        .context("Failed to create commit")?;
    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        anyhow::bail!("git commit failed: {stderr}");
    }

    let rev_parse = Command::new("git")
        .arg("-C")
        .arg(&worktree.path)
        .args(["rev-parse", "--short", "HEAD"])
        .output()
        .context("Failed to resolve commit hash")?;
    if !rev_parse.status.success() {
        let stderr = String::from_utf8_lossy(&rev_parse.stderr);
        anyhow::bail!("git rev-parse failed: {stderr}");
    }

    Ok(String::from_utf8_lossy(&rev_parse.stdout)
        .trim()
        .to_string())
}

pub fn latest_commit_subject(worktree: &WorktreeInfo) -> Result<String> {
    let output = Command::new("git")
        .arg("-C")
        .arg(&worktree.path)
        .args(["log", "-1", "--pretty=%s"])
        .output()
        .context("Failed to read latest commit subject")?;
    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        anyhow::bail!("git log failed: {stderr}");
    }

View on GitHub (pinned to 8321021c54)