gitbutlerapp/gitbutler · error

this is a placeholder for where we will have to start handli

Error message

this is a placeholder for where we will have to start handling this UnmergedTree

What it means

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).

Source

Thrown at crates/but-workspace/src/commit/mod.rs:254

        /// the workspace projection, used to preserve anonymous parents not represented in metadata.
        ///
        /// `graph` resolves metadata branch names to commit and segment ids.
        pub fn tips_from_metadata<'a>(
            stacks: impl IntoIterator<Item = &'a but_core::ref_metadata::WorkspaceStack>,
            anon_stacks: impl IntoIterator<Item = (usize, Tip)>,
            graph: &but_graph::Graph,
        ) -> ResolvedTips {
            let mut missing_stacks = Vec::new();
            let mut tips_with_metadata_slots: Vec<_> = stacks
                .into_iter()
                .filter_map(|s| s.branches.first().map(|b| (b, s.workspacecommit_relation)))
                .map(|(top_segment, relation)| {
                    match relation {
                        WorkspaceCommitRelation::Merged => {}
                        WorkspaceCommitRelation::MergeFrom { .. } => {
                            // These need to be part of the parents list, but shouldn't be merged.
                            // If the caller wants to retry them, they can be passed here as "Merged".
                            todo!(
                                "this is a placeholder for where we will have to start handling this UnmergedTree"
                            )
                        }
                        WorkspaceCommitRelation::Outside => return None,
                    }
                    let stack_tip_name = top_segment.ref_name.as_ref();
                    match graph.segment_and_commit_by_ref_name(stack_tip_name) {
                        None => {
                            missing_stacks.push(top_segment.ref_name.to_owned());
                            None
                        }
                        Some((segment, commit)) => Some(Tip {
                            name: Some(stack_tip_name.to_owned()),
                            commit_id: commit.id,
                            segment_idx: segment.id,
                        }),
                    }
                })

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Retry with the offending stacks passed as `Merged` (the documented workaround in the source comment) if the calling API allows re-passing relations
  2. Restructure the workspace so no stack is in MergeFrom relation (unstack/absorb the merge) before committing
  3. Upgrade but-workspace once UnmergedTree handling is implemented; watch upstream for the todo removal
Defensive patterns

Strategy: validation

Validate before calling

// Filter or convert MergeFrom stacks before building tips
let retryable: Vec<_> = stacks.into_iter().map(|s| {
    if s.workspacecommit_relation == WorkspaceCommitRelation::MergeFrom {
        // documented workaround: pass as Merged on retry if the caller permits
        s.with_relation(WorkspaceCommitRelation::Merged)
    } else { s }
}).collect();

Type guard

fn has_mergefrom(stacks: &[Stack]) -> bool {
    stacks.iter().any(|s| matches!(s.workspacecommit_relation, WorkspaceCommitRelation::MergeFrom))
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/020a1677ef4d1989. Report an issue: GitHub.