{"record":{"id":"e4fd181e042be1e3","repo":"gitbutlerapp/gitbutler","slug":"failed-to-unapply-branch-due-to-conflicts-while-re","errorCode":null,"errorMessage":"Failed to unapply branch due to conflicts while rebuilding the workspace merge commit: {}","messagePattern":"Failed to unapply branch due to conflicts while rebuilding the workspace merge commit: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-workspace/src/branch/unapply.rs","lineNumber":626,"sourceCode":"    ) -> anyhow::Result<WorkspaceMergeAfterUnapply> {\n        let mut tips = future_workspace_tips.to_vec();\n        let report_workspace_merge = !tips.is_empty();\n        if tips.is_empty() {\n            tips.push(base_tip_after_unapply(ws, future_workspace_tips)?);\n        }\n        let outcome = WorkspaceCommit::from_new_merge_with_tips(tips, &ws.graph, repo, None)?;\n        ensure_workspace_merge_has_no_conflicts(&outcome)?;\n        let workspace_commit_id = outcome.workspace_commit_id;\n        Ok(WorkspaceMergeAfterUnapply {\n            workspace_commit_id,\n            workspace_merge: report_workspace_merge.then_some(outcome),\n        })\n    }\n\n    fn ensure_workspace_merge_has_no_conflicts(\n        outcome: &crate::commit::merge::Outcome,\n    ) -> anyhow::Result<()> {\n        ensure!(\n            !outcome.has_conflicts(),\n            \"Failed to unapply branch due to conflicts while rebuilding the workspace merge commit: {}\",\n            describe_conflicting_stacks(&outcome.conflicting_stacks)\n        );\n        Ok(())\n    }\n\n    fn describe_conflicting_stacks(\n        conflicting_stacks: &[crate::commit::merge::ConflictingStack],\n    ) -> String {\n        let ref_names = conflicting_stacks\n            .iter()\n            .filter_map(|stack| stack.ref_name.as_ref())\n            .map(|ref_name| ref_name.shorten().to_string())\n            .collect::<Vec<_>>();\n        if ref_names.is_empty() {\n            format!(\"{} stack(s)\", conflicting_stacks.len())\n        } else {","sourceCodeStart":608,"sourceCodeEnd":644,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-workspace/src/branch/unapply.rs#L608-L644","documentation":"After removing a branch from workspace metadata, unapply rebuilds the workspace merge commit from the remaining stack tips (WorkspaceCommit::from_new_merge_with_tips). If those remaining stacks now conflict with each other in the merged workspace commit, this ensure! aborts the unapply and lists the conflicting stacks by name.","triggerScenarios":"Unapplying branch A while branches B and C remain, where B and C only merged cleanly because A's changes reconciled them — the rebuild merge then reports conflicting_stacks and the whole unapply is refused (metadata rollback).","commonSituations":"Two branches touching the same lines that were both derived from a common reconciling branch; unapplying one of three interdependent stacked branches.","solutions":["Unapply the conflicting branches together (the error names the conflicting stacks) instead of one at a time","Resolve the conflict between the remaining branches first (edit one branch so it merges cleanly), then unapply","As a last resort, unapply the entire workspace or use the non-workspace-merge path that skips rebuilding the managed merge commit"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// preview the post-unapply merge before committing to it: compute tips of remaining stacks\n// and check for conflicts (dry-run the same merge the unapply will rebuild)\nlet preview = WorkspaceCommit::from_new_merge_with_tips(remaining_tips, &ws.graph, repo, None)?;\nif preview.has_conflicts() { /* warn user: unapply these stacks together or resolve first */ }","typeGuard":null,"tryCatchPattern":"match unapply_branch(...) {\n    Err(e) if e.to_string().contains(\"conflicts while rebuilding the workspace merge commit\") => {\n        // parse the named conflicting stacks and offer: unapply them all at once\n    }\n    r => r,\n}","preventionTips":["Unapply interdependent branches in one operation, not singly","Before unapplying, check whether remaining branches touch the same files","Keep branches that will survive an unapply independent of the removed branch's reconciliation"],"tags":["rust","git","merge-conflict","unapply","virtual-branches","but-workspace"],"backgroundTag":"merge-conflict-on-rebuild","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}