{"record":{"id":"75751ddebe5a15ae","repo":"gitbutlerapp/gitbutler","slug":"failed-to-apply-changes-to-destination-commit-merge-conflict","errorCode":null,"errorMessage":"Failed to apply changes to destination commit - merge conflict","messagePattern":"Failed to apply changes to destination commit - merge conflict","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-workspace/src/commit/move_changes.rs","lineNumber":116,"sourceCode":"        if rebased_destination_commit.is_conflicted() {\n            bail!(\"Destination commit must not be conflicted\")\n        }\n        rebased_destination_commit.tree\n    };\n\n    let destination_tree_with_changes = {\n        let repo = editor.repo();\n        let (fail_fast_options, conflict_kind) = repo.merge_options_fail_fast()?;\n        let mut merge_result = repo.merge_trees(\n            source_tree_without_changes_id,\n            source_tree_id,\n            destination_tree_id,\n            Default::default(),\n            fail_fast_options,\n        )?;\n\n        if merge_result.has_unresolved_conflicts(conflict_kind) {\n            bail!(\"Failed to apply changes to destination commit - merge conflict\");\n        }\n\n        merge_result.tree.write()?.detach()\n    };\n\n    let new_destination_commit_id = {\n        let mut commit = rebased_destination_commit;\n        commit.tree = destination_tree_with_changes;\n        editor.new_commit(commit, DateMode::CommitterUpdateAuthorKeep)?\n    };\n\n    editor.replace(\n        destination_selector,\n        Step::new_pick(new_destination_commit_id),\n    )?;\n\n    let outcome = editor.rebase()?;\n","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-workspace/src/commit/move_changes.rs#L98-L134","documentation":"The three-way merge that applies the extracted changes onto the destination tree produced unresolved conflicts, so the move would corrupt the destination commit. The library bails instead of writing the conflicted tree.","triggerScenarios":"move_changes_between_commits calls tree merge with fail_fast options and merge_result.has_unresolved_conflicts() returns true — i.e. the moved hunks overlap conflicting content in the destination commit.","commonSituations":"Moving a hunk into a commit where the same lines were modified differently; moving changes across many commits so context has drifted; binary or tightly-coupled files.","solutions":["Manually apply the change to the destination commit (edit + restage) and only remove it from the source","Move the changes to an adjacent commit where merge context is closer","Reduce the size/scope of the moved hunks so they merge cleanly"],"exampleFix":"// before\neditor.move_changes_between_commits(src, dst, big_hunk, ctx)?; // merge conflict\n// after\nlet smaller = split_hunk(big_hunk);\neditor.move_changes_between_commits(src, dst, smaller, ctx)?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match editor.move_changes_between_commits(src, dst, changes, ctx) {\n    Err(e) if e.to_string().contains(\"merge conflict\") => {\n        // fall back to manual application: edit dst files, restage, then remove from src\n    }\n    other => other,\n}","preventionTips":["Move changes between adjacent commits to minimize merge drift","Split large hunks into smaller independent pieces","Avoid moving changes touching lines already modified in the destination"],"tags":["git","merge-conflict","move"],"backgroundTag":"merge-conflict","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"}