gitbutlerapp/gitbutler · error · anyhow::Error
Branch name '{}' collides with existing branch '{}'
Error message
Branch name '{}' collides with existing branch '{}' What it means
Git refused to create the ref because its name conflicts with an existing ref in the same namespace: you cannot have both refs/heads/foo and refs/heads/foo/bar in a files-based ref store (a ref is both a file path and a directory). gix reports this as a not-a-directory edit error; the code remaps it to a friendly message naming the colliding existing ref.
Source
Thrown at crates/but-workspace/src/branch/create_reference.rs:504
belongs to another branch in the workspace. Each commit can only \
belong to one branch at a time.",
ref_name.shorten(),
ref_target_id,
)
}
// Actually apply the changes
repo.reference(
ref_name,
ref_target_id,
PreviousValue::ExistingMustMatch(gix::refs::Target::Object(ref_target_id)),
"Dependent branch by GitButler",
)
.map_err(|err| {
if is_not_a_directory_ref_edit_error(&err)
&& let Ok(Some(colliding_ref)) = find_colliding_ref_ancestor(repo, ref_name)
{
return anyhow::anyhow!(
"Branch name '{}' collides with existing branch '{}'",
ref_name.shorten(),
colliding_ref.shorten()
);
}
let code = match err {
gix::reference::edit::Error::FileTransactionCommit(
gix::refs::file::transaction::commit::Error::CreateOrUpdateRefLog(
gix::refs::file::log::create_or_update::Error::MissingCommitter,
),
) => Some(but_error::Code::AuthorMissing),
_ => None,
};
let err = anyhow::Error::from(err);
if let Some(code) = code {
err.context(code)
} else {
errView on GitHub (pinned to caf1f223d3)
Solutions
- Rename the new branch so neither name is a path-prefix of the other (e.g. feature-x instead of feature/x)
- Delete or rename the colliding existing branch named in the error if it is obsolete
- When generating names programmatically, check the existing ref set for both prefix and extension collisions first
Example fix
# before git branch feature # exists # creating feature/x → "Branch name 'feature/x' collides with existing branch 'feature'" # after — use a non-hierarchical name git branch feature-x # no collision
Defensive patterns
Strategy: validation
Validate before calling
// before creating refs, check both collision directions against existing refs
fn collides(repo: &gix::Repository, name: &gix::refs::FullName) -> Option<gix::refs::FullName> {
let names: Vec<_> = repo.references().ok()?.map_while(Result::ok)
.map(|r| r.name().to_owned()).collect();
names.into_iter().find(|existing|
existing.as_bstr() == name.as_bstr()
|| existing.as_bstr().starts_with(format!("{}/", name.as_bstr()).as_bytes())
|| name.as_bstr().starts_with(format!("{}/", existing.as_bstr()).as_bytes()))
} Type guard
fn is_safe_branch_name(existing: &[String], candidate: &str) -> bool {
existing.iter().all(|e| e != candidate && !e.starts_with(&format!("{candidate}/")) && !candidate.starts_with(&format!("{e}/")))
} Try / catch
match create_reference(...) {
Err(e) if e.to_string().contains("collides with existing branch") => { /* extract colliding name, suggest alternative like replacing '/' with '-' */ }
r => r,
} Prevention
- Avoid hierarchical names (a/b) for generated branches, or normalize separators
- Validate candidate names against the full ref list (both prefix directions) before creating
- Clean up obsolete stacked branches whose names block a namespace
When it happens
Trigger: Creating dependent branch 'feature/x' when branch 'feature' already exists (or vice versa) via create_reference; any generated branch name whose path prefix equals an existing ref, or that extends an existing ref with a slash component.
Common situations: Automatic branch-name generation (e.g. stacking schemes that insert slashes) colliding with user-created branches; importing branches from another remote with hierarchical naming.
Related errors
- When using Anthropic in a bring your own key configuration,
- HTTP Error ${response.statusText}: ${text}
- Integration steps cannot be empty
- line {line_number}: pick does not accept a message clause
- line {line_number}: pick requires exactly one commit
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/7a807956c855ba4b.
Report an issue: GitHub.