affaan-m/ECC · error · anyhow::Error

git log failed: {stderr}

Error message

git log failed: {stderr}

What it means

latest_commit_subject runs `git log -1 --pretty=%s`. Non-zero exit is re-thrown. The function is used to display the most recent commit; failure means HEAD has no commit to describe.

Source

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

        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}");
    }

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

pub fn create_draft_pr(worktree: &WorktreeInfo, title: &str, body: &str) -> Result<String> {
    create_draft_pr_with_options(worktree, title, body, &DraftPrOptions::default())
}

pub fn create_draft_pr_with_options(
    worktree: &WorktreeInfo,
    title: &str,
    body: &str,
    options: &DraftPrOptions,
) -> Result<String> {
    create_draft_pr_with_gh(worktree, title, body, options, Path::new("gh"))
}

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Pre-check `git rev-parse --verify HEAD^{commit}` and only call latest_commit_subject when it resolves.
  2. Render an 'empty branch' placeholder when there is no HEAD commit.
  3. Run `git fsck` if HEAD should resolve but does not.

Example fix

// before
let subject = latest_commit_subject(&worktree)?;

// after
let has_head = Command::new("git")
    .arg("-C").arg(&worktree.path)
    .args(["rev-parse", "--verify", "HEAD^{commit}"])
    .output()?.status.success();
let subject = if has_head {
    Some(latest_commit_subject(&worktree)?)
} else { None };
Defensive patterns

Strategy: validation

Validate before calling

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

let subject = if head_has_commit(&worktree) {
    Some(latest_commit_subject(&worktree)?)
} else {
    None
};

Type guard

fn has_commits(worktree: &WorktreeInfo) -> bool {
    head_has_commit(worktree)
}

Try / catch

match latest_commit_subject(&worktree) {
    Ok(s) => Some(s),
    Err(e) if format!("{e:#}").contains("does not have any commits") => None,
    Err(e) if format!("{e:#}").contains("unknown revision") => None,
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling latest_commit_subject on a brand-new worktree whose branch has no commits yet (unborn HEAD); corrupted HEAD ref; the branch was reset to a state with zero commits.

Common situations: UI renders a 'last commit' field on a freshly created worktree before any commit; rebase left HEAD pointing at nothing during an interrupted operation; reflog corruption.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/640e91e6c6413d68. Report an issue: GitHub.