{"record":{"id":"729b11d5906fd589","repo":"GitoxideLabs/gitoxide","slug":"stashes-at-and-would-converge-on","errorCode":null,"errorMessage":"stashes at {} and {} would converge on {}","messagePattern":"stashes at (.+?) and (.+?) would converge on (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/stash.rs","lineNumber":81,"sourceCode":"            Ok(Some(id)) => id,\n            Ok(None) => continue,\n            Err(err) => {\n                tracing::warn!(name = %reference.name(), error = %err, \"ignored malformed tix stash reference\");\n                continue;\n            }\n        };\n        let Some(new) = rewritten.get(&old).copied() else {\n            continue;\n        };\n        if removed.contains(&old) {\n            anyhow::bail!(\"cannot drop stashed commit {}\", old.to_hex_with_len(7));\n        }\n        let new = new.context(\"a stashed commit cannot disappear during a rewrite\")?;\n        if new == old {\n            continue;\n        }\n        if let Some(other) = destinations.insert(new, old) {\n            anyhow::bail!(\n                \"stashes at {} and {} would converge on {}\",\n                other.to_hex_with_len(7),\n                old.to_hex_with_len(7),\n                new.to_hex_with_len(7)\n            );\n        }\n        moves.push((reference.name().to_owned(), reference.target().into_owned(), old, new));\n    }\n\n    let mut forward = Vec::with_capacity(moves.len() * 2);\n    let mut rollback = Vec::with_capacity(moves.len() * 2);\n    for (old_name, target, old, new) in moves {\n        let new_name = reference(new)?;\n        if repo.try_find_reference(new_name.as_ref())?.is_some() {\n            anyhow::bail!(\n                \"rewritten commit {} already has saved worktree state\",\n                new.to_hex_with_len(7)\n            );","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/stash.rs#L63-L99","documentation":"When rewriting history, tix re-points each stash reference from its old commit to the rewritten commit. This error fires when two different old stash references would both be re-pointed at the same new commit, which would make one reference clobber the other and lose saved worktree state. It reports the short hashes of both converging stash commits and the shared destination commit.","triggerScenarios":"Calling `stash::rewrite_edits` when the rewrite mapping `rewritten` sends two stash-owning commits to the same new commit ID (e.g. commits were squashed together), and both had stash references.","commonSituations":"Squashing or fixing-up commits during an interactive rebase when both squashed commits had saved tix worktree state; cherry-pick style rewrites collapsing distinct commits.","solutions":["Unstash the saved worktree state of one of the two stash commits before squashing them together","Drop or manually merge the contents of one of the stash references, then re-run the rewrite","Reorder the rewrite so the two commits are not collapsed into one destination"],"exampleFix":"// before squashing two stash-owning commits\nplan.squash(a_id, b_id);\n// after: rescue one stash first\nstash::restore_manual(path, bare, b_id)?;\nplan.squash(a_id, b_id);","handlingStrategy":"try-catch","validationCode":"let mut destinations = std::collections::HashSet::new();\nfor old in stash_owning_commits(&repo)? {\n    if let Some(new) = plan.rewritten().get(&old) {\n        if !destinations.insert(*new) {\n            anyhow::bail!(\"two stashes converge on {} after rewrite\", new);\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"match stash::rewrite_edits(&repo, plan) {\n    Err(e) if e.to_string().starts_with(\"stashes at \") => {\n        // two stash refs collapse; unstash one and retry\n    }\n    other => other?,\n}","preventionTips":["Avoid squashing commits that each have saved tix worktree state","Unstash before any interactive rebase that may squash or fix up stash-owning commits","Check the rewrite plan's mapping for duplicate destinations before executing"],"tags":["git","rewrite","stash","conflict"],"backgroundTag":"invalid-state-transition","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"}