gitbutlerapp/gitbutler · error · anyhow::Error
commit prefix '{spec}' is ambiguous
Error message
commit prefix '{spec}' is ambiguous What it means
Raised by `resolve_commit` when a commit spec is a prefix that matches two or more commits in the allowed divergence set (string prefix match against full hex ObjectIds). The parser refuses to guess which commit was meant.
Source
Thrown at crates/but-workspace/src/branch/integrate_branch_upstream/parsing.rs:161
commit.target_relation,
IntegrationDivergenceTargetRelation::NotIntegrated
)
})
.map(|commit| commit.id)
.chain(divergence.upstream_only.iter().map(|commit| commit.id))
.collect()
}
fn resolve_commit(spec: &str, allowed_commits: &HashSet<gix::ObjectId>) -> Result<gix::ObjectId> {
let matches = allowed_commits
.iter()
.copied()
.filter(|commit_id| commit_id.to_string().starts_with(spec))
.collect::<Vec<_>>();
match matches.as_slice() {
[] => bail!("commit '{spec}' is not part of the editable divergence"),
[commit_id] => Ok(*commit_id),
_ => bail!("commit prefix '{spec}' is ambiguous"),
}
}
fn split_message_clause(line: &str) -> Result<(&str, Option<&str>)> {
let Some((command_part, message_part)) = line.split_once('|') else {
return Ok((line, None));
};
Ok((command_part.trim_end(), Some(message_part.trim_start())))
}
fn parse_message_clause(clause: &str) -> Result<String> {
let value = clause
.strip_prefix("message=")
.context("expected `message=` after `|`")?;
parse_quoted_string(value)
}
fn parse_quoted_string(input: &str) -> Result<String> {View on GitHub (pinned to caf1f223d3)
Solutions
- Lengthen the prefix until it is unique (7+ hex chars is usually enough; full 40-char SHA always works).
- Copy the exact prefixes emitted by `render_integration_steps_script`, which uses `short_id` and is what the UI displays.
Example fix
# before squash 4f 991b # after squash 4f2a9c1 991b3aa
Defensive patterns
Strategy: validation
Validate before calling
// Enforce unique prefixes up front:
fn unique_prefix_len(ids: &HashSet<gix::ObjectId>, spec: &str) -> bool {
ids.iter().filter(|id| id.to_string().starts_with(spec)).count() == 1
} Try / catch
if let Err(err) = parse_integration_steps_script(&script, &divergence) {
if err.to_string().contains("ambiguous") {
// ask user to lengthen the prefix on the reported line
}
} Prevention
- Emit scripts via render_integration_steps_script (uses short_id) rather than hand-shortening SHAs.
- Prefer 7+ hex characters; full SHAs never conflict.
When it happens
Trigger: Using a very short prefix like `4f` when two divergence commits both start with `4f`; prefixes shorter than the unique-prefix length of the current divergence.
Common situations: Users shorten SHAs to 1-4 chars as on CLI git; automated editors that truncate SHAs for readability.
Related errors
- commit '{spec}' is not part of the editable divergence
- line {line_number}: pick does not accept a message clause
- line {line_number}: pick requires exactly one commit
- line {line_number}: merge does not accept a message clause
- line {line_number}: merge requires exactly one commit
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/e7c53bc0f648c92b.
Report an issue: GitHub.