gitbutlerapp/gitbutler · error
Cannot push branch '{}': the push would include {} conflicte
Error message
Cannot push branch '{}': the push would include {} conflicted commit{}.
Conflicted commits: {}
Please resolve conflicts before pushing using 'but resolve <commit>'. What it means
Before pushing, the CLI checks the branch and its stack ancestors for conflicted commits; any hit aborts the push with the count (pluralized) and a short-id list (change ids where the IdMap knows them, otherwise shortened oids). The message directs to `but resolve <commit>` because publishing conflict markers to a remote is never wanted.
Source
Thrown at crates/but/src/command/legacy/push.rs:1264
.map(|c| c.id)
.collect();
// Only pay for the map when the error actually prints.
let id_map = (!conflicted.is_empty())
.then(|| crate::IdMap::legacy_new_from_context(ctx).ok())
.flatten();
let conflicted_commits: Vec<String> = conflicted
.iter()
.map(|id| {
id_map
.as_ref()
.and_then(|id_map| id_map.change_id_ref(*id))
.map(|change_id| change_id.padded_short_id())
.unwrap_or_else(|| shorten_object_id(&repo, *id))
})
.collect();
if !conflicted_commits.is_empty() {
return Err(anyhow::anyhow!(
"Cannot push branch '{}': the push would include {} conflicted commit{}.\n\
Conflicted commits: {}\n\
Please resolve conflicts before pushing using 'but resolve <commit>'.",
branch_name,
conflicted_commits.len(),
if conflicted_commits.len() == 1 {
""
} else {
"s"
},
conflicted_commits.join(", ")
));
}
return Ok(());
}
}
View on GitHub (pinned to caf1f223d3)
Solutions
- Run `but resolve <commit>` for each commit listed in the error and complete conflict resolution
- Verify the stack is clean with `but status` and `but push --dry-run`
- Push again once no conflicted commits remain
Example fix
# before but push feature-x # error: Cannot push branch 'feature-x': the push would include 2 conflicted commits... # after but resolve <short-id-from-error> # repeat for each listed commit but push feature-x
Defensive patterns
Strategy: validation
Validate before calling
# Preview before pushing — dry-run surfaces conflicts without touching the remote
but push --dry-run || { echo 'resolve conflicts first: but resolve <commit>' >&2; exit 1; } Try / catch
# Extract the conflicted-commit list and drive resolution out=$(but push 2>&1); rc=$? if [ $rc -ne 0 ] && [[ "$out" == *"conflicted commit"* ]]; then # ids follow 'Conflicted commits:' in the message — feed each to `but resolve` echo "$out" | sed -n 's/.*Conflicted commits: //p' fi
Prevention
- Always dry-run after a conflict-heavy pull
- Finish `but resolve` sessions before switching tasks or pushing
- Treat the conflicted-commit list in the error as your worklist
When it happens
Trigger: Pushing a branch whose stack contains commits still marked conflicted — typically after `but pull` integrated upstream changes and the conflicts were left unresolved.
Common situations: Pull brought conflicting upstream changes and the user pushed without finishing resolution; long-lived stacks integrated onto a moved target; CI attempting to push mid-conflict.
Related errors
- Could not find stack containing commit {commit_ref}
- No stack selected!
- push failed
- push failed after {MAX_RETRIES} attempts
- Could not restore all review targets after the push failed:
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/9da6ab1663eed68d.
Report an issue: GitHub.