{"record":{"id":"020a1677ef4d1989","repo":"gitbutlerapp/gitbutler","slug":"this-is-a-placeholder-for-where-we-will-have-to-st","errorCode":null,"errorMessage":"this is a placeholder for where we will have to start handling this UnmergedTree","messagePattern":"this is a placeholder for where we will have to start handling this UnmergedTree","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-workspace/src/commit/mod.rs","lineNumber":254,"sourceCode":"        /// the workspace projection, used to preserve anonymous parents not represented in metadata.\n        ///\n        /// `graph` resolves metadata branch names to commit and segment ids.\n        pub fn tips_from_metadata<'a>(\n            stacks: impl IntoIterator<Item = &'a but_core::ref_metadata::WorkspaceStack>,\n            anon_stacks: impl IntoIterator<Item = (usize, Tip)>,\n            graph: &but_graph::Graph,\n        ) -> ResolvedTips {\n            let mut missing_stacks = Vec::new();\n            let mut tips_with_metadata_slots: Vec<_> = stacks\n                .into_iter()\n                .filter_map(|s| s.branches.first().map(|b| (b, s.workspacecommit_relation)))\n                .map(|(top_segment, relation)| {\n                    match relation {\n                        WorkspaceCommitRelation::Merged => {}\n                        WorkspaceCommitRelation::MergeFrom { .. } => {\n                            // These need to be part of the parents list, but shouldn't be merged.\n                            // If the caller wants to retry them, they can be passed here as \"Merged\".\n                            todo!(\n                                \"this is a placeholder for where we will have to start handling this UnmergedTree\"\n                            )\n                        }\n                        WorkspaceCommitRelation::Outside => return None,\n                    }\n                    let stack_tip_name = top_segment.ref_name.as_ref();\n                    match graph.segment_and_commit_by_ref_name(stack_tip_name) {\n                        None => {\n                            missing_stacks.push(top_segment.ref_name.to_owned());\n                            None\n                        }\n                        Some((segment, commit)) => Some(Tip {\n                            name: Some(stack_tip_name.to_owned()),\n                            commit_id: commit.id,\n                            segment_idx: segment.id,\n                        }),\n                    }\n                })","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-workspace/src/commit/mod.rs#L236-L272","documentation":"When but_workspace::commit builds ResolvedTips from stacks, stacks whose `workspacecommit_relation` is `MergeFrom` hit a `todo!`: these stacks must become parents of the workspace commit without being merged, and that UnmergedTree handling is not implemented yet. The comment notes callers may pass them as `Merged` on retry (crates/but-workspace/src/commit/mod.rs:254).","triggerScenarios":"Committing the workspace when at least one stack relates to the workspace commit via `WorkspaceCommitRelation::MergeFrom` - e.g. merge-shaped workspace topologies or imported stacks that arrive as merge parents.","commonSituations":"Repos with merge commits inside the workspace topology; import/sync flows that produce MergeFrom relations; newer workspace-import features exercising this relation for the first time.","solutions":["Retry with the offending stacks passed as `Merged` (the documented workaround in the source comment) if the calling API allows re-passing relations","Restructure the workspace so no stack is in MergeFrom relation (unstack/absorb the merge) before committing","Upgrade but-workspace once UnmergedTree handling is implemented; watch upstream for the todo removal"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Filter or convert MergeFrom stacks before building tips\nlet retryable: Vec<_> = stacks.into_iter().map(|s| {\n    if s.workspacecommit_relation == WorkspaceCommitRelation::MergeFrom {\n        // documented workaround: pass as Merged on retry if the caller permits\n        s.with_relation(WorkspaceCommitRelation::Merged)\n    } else { s }\n}).collect();","typeGuard":"fn has_mergefrom(stacks: &[Stack]) -> bool {\n    stacks.iter().any(|s| matches!(s.workspacecommit_relation, WorkspaceCommitRelation::MergeFrom))\n}","tryCatchPattern":null,"preventionTips":["Check workspacecommit_relation of every stack before calling the tips/commit API","Keep merge-parent-shaped stacks out of the workspace until UnmergedTree handling ships","Wrap workspace commits in a pre-validation step that rejects MergeFrom with a clear upstream error"],"tags":["rust","but-workspace","todo","unimplemented","workspace-commit","panic"],"backgroundTag":"unimplemented-todo-panic","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}