gitbutlerapp/gitbutler · error
Commit ID '{}' is ambiguous. Found {} matches
Error message
Commit ID '{}' is ambiguous. Found {} matches What it means
`but show` (crates/but/src/command/legacy/show.rs:67) resolves its argument through the IdMap of short CLI IDs; when the argument prefix matches more than one entity (cli_ids.len() > 1) it refuses to guess and reports the match count. Short IDs (often 2-character prefixes) are only usable when unique within the current workspace snapshot.
Source
Thrown at crates/but/src/command/legacy/show.rs:67
}
}
// 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) => {
// This is a branch identified by CLI ID, show the branch
return show_branch(ctx, out, &branch.name, verbose, &id_map);
}
_ => {
bail!(
"Target must be a commit ID or branch, not {}",
cli_ids[0].kind_for_humans()View on GitHub (pinned to caf1f223d3)
Solutions
- Lengthen the prefix until unique, or pass the full 40-character object ID.
- Re-run `but status` to see the current short-ID assignments and pick an unambiguous one.
- Remember the fallback path: any string not in the IdMap is parsed with rev_parse_single, so full SHAs and ref names always bypass ambiguity.
Example fix
# before but show ab # Commit ID 'ab' is ambiguous. Found 2 matches # after but show ab9f31c04d8e2f7a1b3c5d6e7f8a9b0c1d2e3f4a
Defensive patterns
Strategy: validation
Validate before calling
let matches = id_map.lookup(prefix);
match matches.len() {
0 => /* fall back to rev_parse_single */,
1 => /* safe */,
_ => return Err(anyhow::anyhow!("prefix '{}' matches {} entities; extend it", prefix, matches.len())),
} Try / catch
if let Err(err) = show_command(&ctx, &out, id) {
if err.to_string().contains("ambiguous") {
// retry with the full 40-char SHA captured from the original entity
}
} Prevention
- Store full object IDs in scripts; shorten only at display time.
- Refresh short IDs with `but status` right before using them.
- Treat ambiguity as expected in small workspaces and auto-extend prefixes.
When it happens
Trigger: Passing a short ID prefix that collides across entities, e.g. `but show ab` where two commits or branches share that prefix; the workspace changed between displaying the ID and running the command, introducing a new collision.
Common situations: Copy-pasting a truncated ID from stale TUI/status output; small workspaces where 1-2 hex characters collide frequently; scripts that cut SHAs to fixed short lengths.
Related errors
- Stack name '{stack}' is ambiguous in the current workspace
- No branch found for ID: {branch_id}
- Could not find branch: {branch_id}
- Ambiguous branch '{branch_id}', matches multiple items
- Expected a branch ID, got {}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/b57ec69c2a24c6c9.
Report an issue: GitHub.