{"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/58e5313667b857ef39a730e380af31816a7b1768/crates/but-workspace/src/commit/mod.rs#L236-L272","documentation":"tips_from_metadata in crates/but-workspace/src/commit/mod.rs panics with a todo!() when it encounters a workspace commit whose relation to the workspace is WorkspaceCommitRelation::MergeFrom (an unmerged tree / merge source). Merged and Outside relations are handled; MergeFrom explicitly has no handling yet, so reaching it is an unconditional panic.","triggerScenarios":"Calling but_workspace::commit::tips_from_metadata on workspace metadata that contains at least one top-segment commit classified as WorkspaceCommitRelation::MergeFrom{..} (a merge commit brought into the workspace but not merged into the workspace tree).","commonSituations":"A user pulled/merged external commits into a workspace branch so the workspace contains unmerged merge-commit trees; the app then derives commit tips from metadata and hits the placeholder.","solutions":["Upgrade/normalize the workspace metadata so affected commits are classified Merged (retry them via the documented path of passing them as Merged) or Outside before calling tips_from_metadata.","Fix at the source: ensure merge-from commits are added to parents lists without being merged, as the code comment suggests, then implement the MergeFrom arm.","Short-term, filter out MergeFrom relations in a pre-pass and handle them separately instead of feeding them to tips_from_metadata."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// pre-check metadata for MergeFrom relations before calling tips_from_metadata\nif segments.iter().any(|s| matches!(s.relation, WorkspaceCommitRelation::MergeFrom{..})) {\n    // handle separately\n}","typeGuard":"// Rust: match on the relation before passing through\nmatch relation {\n    WorkspaceCommitRelation::MergeFrom{..} => None, // handled elsewhere\n    _ => Some((top_segment, relation)),\n}","tryCatchPattern":null,"preventionTips":["Inspect workspace relations before deriving tips; never assume all commits are Merged.","Add a test with a merge-from commit to catch this early.","Normalize workspace metadata (re-classify MergeFrom commits) after pull/merge operations."],"tags":["rust","panic","workspace","merge","unimplemented"],"backgroundTag":"unsupported-operation","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}