{"record":{"id":"ffbd613416751d5c","repo":"GitoxideLabs/gitoxide","slug":"parent-match-assures-this","errorCode":null,"errorMessage":"parent-match assures this","messagePattern":"parent-match assures this","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-merge/src/tree/function/resolve.rs","lineNumber":1070,"sourceCode":"                                    ];\n                                    match resolve_tree_conflicts {\n                                        None => {\n                                            editor.upsert(toc(location), entry_mode.kind(), *id)?;\n                                        }\n                                        Some(ResolveWith::Ours) => {\n                                            let ours = match outer_side {\n                                                Original => ours,\n                                                Swapped => theirs,\n                                            };\n\n                                            match ours {\n                                                Change::Modification { .. } => {\n                                                    editor.upsert(toc(location), entry_mode.kind(), *id)?;\n                                                }\n                                                Change::Deletion { .. } => {\n                                                    editor.remove(toc(location))?;\n                                                }\n                                                _ => unreachable!(\"parent-match assures this\"),\n                                            }\n                                        }\n                                        Some(ResolveWith::Ancestor) => {}\n                                    }\n                                    should_fail_on_conflict(Conflict::without_resolution(\n                                        ResolutionFailure::OursModifiedTheirsDeleted,\n                                        (ours, theirs, side, outer_side),\n                                        entries,\n                                    ))\n                                };\n                                let deletion_was_applied = match resolve_tree_conflicts {\n                                    None => deletion_replaced_by_directory,\n                                    Some(ResolveWith::Ours) => side.to_global(outer_side).is_swapped(),\n                                    Some(ResolveWith::Ancestor) => false,\n                                };\n                                if deletion_was_applied {\n                                    match side {\n                                        Original => theirs_disposition = ChangeDisposition::Applied,","sourceCodeStart":1052,"sourceCodeEnd":1088,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-merge/src/tree/function/resolve.rs#L1052-L1088","documentation":"This `unreachable!()` in `gix-merge`'s three-way tree merge fires when a conflict-side change is neither a Modification nor a Deletion while applying an ours-changed/theirs-deleted resolution. The enclosing code assumes the parent matching logic guarantees only those two `Change` shapes can occur here.","triggerScenarios":"Calling `gix_merge::tree(...)` (merge) with an index or tree state where a change entry for the current location is `Addition` instead of Modification/Deletion — i.e. a broken parent-child correspondence between merged trees.","commonSituations":"Practically unreachable; would indicate a bug in the change enumeration during a merge involving deeply nested paths where one side deleted a directory.","solutions":["Report the panic upstream with the two trees and ancestor that reproduce the merge.","Update `gix-merge` to the latest patch version in case the parent-matching invariant was fixed.","If you maintain the code, replace the wildcard arm with an explicit error or handle `Change::Addition` deliberately."],"exampleFix":"// before\n_ => unreachable!(\"parent-match assures this\"),\n// after\nother => return Err(message!(\"unexpected change {other:?} during ours-modified/theirs-deleted resolution\"))","handlingStrategy":"try-catch","validationCode":"// Validate inputs are complete trees before merging\n// gix_merge::tree(...) requires ancestor, ours, theirs tree objects resolvable in the object store","typeGuard":null,"tryCatchPattern":"// Panics propagate; run merges behind catch_unwind or in a worker process.\nlet result = std::panic::catch_unwind(|| gix_merge::tree(...));","preventionTips":["Use the same version for all gix-* crates","Test merges with tricky directory-add/delete pairs before deploying","Report upstream panics with reproducing trees"],"tags":["rust","panic","internal-invariant","tree-merge"],"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"}