{"record":{"id":"9b9f248139408a04","repo":"GitoxideLabs/gitoxide","slug":"an-edit-unexpectedly-produced-a-merge-conflict","errorCode":null,"errorMessage":"an edit unexpectedly produced a merge conflict","messagePattern":"an edit unexpectedly produced a merge conflict","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/rebase.rs","lineNumber":294,"sourceCode":"    pub new: ObjectId,\n}\n\nimpl Outcome {\n    pub(crate) fn map(&self, id: ObjectId) -> Option<ObjectId> {\n        self.rewritten.get(&id).copied().unwrap_or(Some(id))\n    }\n}\n\npub(crate) enum Perform {\n    Complete(Outcome),\n    Conflict(Conflict),\n}\n\nimpl Perform {\n    pub(crate) fn complete(self) -> Result<Outcome> {\n        match self {\n            Perform::Complete(outcome) => Ok(outcome),\n            Perform::Conflict(_) => anyhow::bail!(\"an edit unexpectedly produced a merge conflict\"),\n        }\n    }\n}\n\npub(crate) struct Conflict {\n    prepared: Prepared,\n    conflicts: Vec<gix::merge::tree::Conflict>,\n    merged_tree: ObjectId,\n    commit: ObjectId,\n    original: ObjectId,\n}\n\nimpl Conflict {\n    pub(crate) fn original(&self) -> ObjectId {\n        self.original\n    }\n\n    pub(crate) fn persist(mut self) -> Result<PersistedConflict> {","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/rebase.rs#L276-L312","documentation":"`Perform::complete` converts an internal rebase result into an `Outcome`. A conflict result is normally handled and resolved interactively during the rebase; if a `Perform::Conflict` still exists when the edit is declared complete, the rebase machinery reached an unexpected state. This is an internal invariant check — the conflict should never have survived to this point.","triggerScenarios":"Finishing a tix edit/rebase whose `Perform` state is `Perform::Conflict(_)` at `complete()` time, i.e. the rebase stopped on a merge conflict that the caller of `complete()` did not surface or resolve beforehand.","commonSituations":"Rebasing edits across a history that touches the same paths in diverging branches and produces a conflict mid-rebase while the driver assumes conflict-free edits; a bug or unhandled conflict path in the edit workflow.","solutions":["Inspect the repository state (`git status`) for leftover conflict markers and resolve or abort the in-progress rebase before retrying.","Retry the edit after resolving conflicting changes manually, or split the edit into smaller steps that avoid conflicts.","If reproducible without a real conflict, report it as a bug in tix's rebase conflict handling (invariant violation)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Rust: only call complete() when no conflict remains\nif matches!(performed, Perform::Conflict(_)) {\n    handle_conflict_interactively(performed)?;\n} else {\n    let outcome = performed.complete()?;\n}","typeGuard":"fn is_ready(performed: &Perform) -> bool {\n    matches!(performed, Perform::Complete(_))\n}","tryCatchPattern":"// Rust\nlet outcome = performed.complete().map_err(|e| {\n    eprintln!(\"conflict left after edit; resolve manually with git status\");\n    e\n})?;","preventionTips":["Ensure edits operate on conflict-free ranges of history.","Resolve any in-progress conflicts before declaring an edit complete.","Reproduce persistently with a minimal repo and report as a tix bug."],"tags":["rebase","merge-conflict","internal-state","git"],"backgroundTag":"internal-invariant-violation","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}