{"record":{"id":"66cddb83ceb5cbdf","repo":"gitbutlerapp/gitbutler","slug":"no-changes-to-move","errorCode":null,"errorMessage":"No changes to move","messagePattern":"No changes to move","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-workspace/src/worktrees.rs","lineNumber":212,"sourceCode":"                selection,\n                context_lines,\n            )?;\n            let rejected: Vec<_> = outcome\n                .rejected_specs\n                .iter()\n                .map(|(reason, spec)| format!(\"{reason:?}: {}\", spec.path))\n                .collect();\n            if !rejected.is_empty() {\n                bail!(\n                    \"Some selected changes no longer match the worktree's uncommitted changes: {}\",\n                    rejected.join(\", \")\n                );\n            }\n            outcome.destination_tree.context(\"No changes to move\")?\n        }\n    };\n    if moved_tree == worktree_head_tree {\n        bail!(\"No changes to move\");\n    }\n\n    let destination_outcome = but_core::worktree::safe_checkout_from_head(\n        moved_tree,\n        main_repo,\n        but_core::worktree::checkout::Options {\n            merge_base_override: Some(worktree_head_tree),\n            allow_uncommitted_changes_to_conflict_with_new_head: true,\n            ..Default::default()\n        },\n    )?;\n\n    but_core::worktree::safe_checkout_from_head(\n        worktree_head_tree,\n        worktree_repo,\n        but_core::worktree::checkout::Options {\n            merge_base_override: Some(moved_tree),\n            allow_uncommitted_changes_to_conflict_with_new_head: true,","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-workspace/src/worktrees.rs#L194-L230","documentation":"After constructing the tree of changes to move, if that tree equals the worktree's head tree, the move would relocate nothing (the selection covers everything but resolves to the same content, or the constructed destination tree has no delta). The library bails instead of performing a meaningless checkout.","triggerScenarios":"move_uncommitted_changes where moved_tree == worktree_head_tree — the moved content is identical to the current worktree head, e.g. the selection math produced a tree with no actual differences, or a preceding context(\"No changes to move\") on the destination tree was bypassed with identical trees.","commonSituations":"Selecting changes that only revert each other (edit + re-edit netting zero); moving with a selection whose resulting tree matches head because the destination already contains that content; automation passing a full-copy selection with no delta.","solutions":["Verify the selection actually captures a non-empty delta against the worktree head before moving","Recompute the diff of the worktree; if it is empty, treat 'nothing to move' as a success no-op in the caller","Adjust the selection so it represents real changes to relocate"],"exampleFix":"// before: assuming a move always changes something\nmove_uncommitted_changes(ctx, &wt, Some(selection), None)?;\n// after: short-circuit no-op moves\nlet diff = worktree_repo.diff_tree_to_workdir_with_index(...)?;\nif diff.is_empty() { return Ok(MoveOutcome::Noop); }\nmove_uncommitted_changes(ctx, &wt, Some(selection), None)?;","handlingStrategy":"validation","validationCode":"let workdir_diff = worktree_repo.diff_tree_to_workdir_with_index(Some(&worktree_head_tree), None)?;\nanyhow::ensure!(!workdir_diff.is_empty(), \"worktree has no delta against head; nothing to move\");","typeGuard":null,"tryCatchPattern":"match move_uncommitted_changes(ctx, &wt, Some(selection), None) {\n    Err(e) if e.to_string().contains(\"No changes to move\") => Ok(MoveOutcome::Noop),\n    r => r,\n}","preventionTips":["Verify the selection yields a real content delta before moving","Handle edit/re-edit netting to zero as an explicit no-op","Check the worktree diff emptiness early and skip the call","Don't select 'everything' when the destination already matches"],"tags":["git","worktree","selection","no-op"],"backgroundTag":"empty-result-set","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"}