gitbutlerapp/gitbutler · error · anyhow::Error

Commit '{commit_id_str}' not found

Error message

Commit '{commit_id_str}' not found

What it means

Thrown by `but show <id>` resolution: the IdMap lookup returned no CLI ids, so the string is fall back to `repo.rev_parse_single(commit_id_str)`. If gix cannot resolve the revision at all, this error is raised — the input is neither a known CLI short id, nor any ref/oid expression git understands.

Source

Thrown at crates/but/src/command/legacy/show.rs:60

            let head_name = branch.name.clone();
            if head_name == commit_id_str
                || head_name.to_lowercase() == commit_id_str.to_lowercase()
            {
                // Found the branch in a stack
                return show_branch(ctx, out, &head_name, verbose, &id_map);
            }
        }
    }

    // Not a branch, resolve the commit ID through the IdMap
    let cli_ids = id_map.parse_using_context(commit_id_str, ctx)?;

    let commit_id = if cli_ids.is_empty() {
        // If not found in IdMap, try to parse as a git commit ID directly
        let repo = ctx.repo.get()?;
        let obj = repo
            .rev_parse_single(commit_id_str)
            .map_err(|_| anyhow::anyhow!("Commit '{commit_id_str}' not found"))?;
        let commit = obj
            .object()?
            .try_into_commit()
            .map_err(|_| anyhow::anyhow!("'{commit_id_str}' is not a commit"))?;
        commit.id
    } else if cli_ids.len() > 1 {
        bail!(
            "Commit ID '{}' is ambiguous. Found {} matches",
            commit_id_str,
            cli_ids.len()
        );
    } else {
        match &cli_ids[0] {
            CliId::Commit {
                commit: CommitId { commit_id, .. },
                id: _,
            } => *commit_id,
            CliId::Branch(branch) => {

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Verify the id resolves in the same repo: `git rev-parse <id>` — if git also fails, the id is stale or wrong
  2. Use the short id printed by current `but status` / `but log` output so IdMap resolution succeeds first
  3. If the commit should exist but is missing (shallow/pruned), fetch it: `git fetch origin <sha>` (needs uploadpack.allowAnySHA1InWant on the server) and retry
  4. Reference a branch name instead of a raw sha when possible

Example fix

# before: stale/mistyped sha
but show 4f2ac91

# after: confirm it exists, else take a fresh id
 git rev-parse 4f2ac91   # fails -> copy a current id instead
but status               # lists fresh CLI ids
but show c3
Defensive patterns

Strategy: validation

Validate before calling

let repo = ctx.repo.get()?;
if repo.rev_parse_single(id.as_bytes()).is_err() {
    anyhow::bail!("id {id} does not resolve; run 'but status' for current ids or 'git rev-parse {id}' to check");
}

Try / catch

match resolve_commit(id_map, ctx, id) {
    Ok(commit_id) => { /* show */ }
    Err(err) if err.to_string().contains("not found") => {
        // suggest fresh 'but status' ids and 'git rev-parse' verification
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Passing a mistyped hex sha, a too-short prefix gix refuses to guess, an object id that no longer exists (pruned by gc, beyond a shallow-clone boundary), or a ref name typo — and none of these resolve via rev-parse.

Common situations: Copying a truncated or edited sha from logs/chat; referencing commits after `git gc --prune` or in shallow CI clones; reusing CLI short ids from a different workspace whose IdMap doesn't know them; old ids after history rewrite.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/5fe147350b925be0. Report an issue: GitHub.