{"record":{"id":"3b4ef31dc84dbfe2","repo":"GitoxideLabs/gitoxide","slug":"the-stack-is-already-directly-above-the-move-targe","errorCode":null,"errorMessage":"the stack is already directly above the move target","messagePattern":"the stack is already directly above the move target","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gix-tix/src/edit/rebase.rs","lineNumber":680,"sourceCode":"        let id = *stack.last().expect(\"a stack always contains HEAD\");\n        let parents = graph.parents_of(id).context(\"a moved stack commit is incomplete\")?;\n        let [parent] = parents.as_slice() else {\n            anyhow::bail!(\"moving a stack requires every commit to have exactly one parent\");\n        };\n        stack_parent.insert(id, *parent);\n        if id == base {\n            break;\n        }\n        stack.push(*parent);\n    }\n    stack.reverse();\n    let stack_set: HashSet<_> = stack.iter().copied().collect();\n    if stack_set.contains(&target) {\n        anyhow::bail!(\"the move target must not be part of the moved stack\");\n    }\n    let base_parent = stack_parent[&base];\n    if base_parent == target {\n        anyhow::bail!(\"the stack is already directly above the move target\");\n    }\n\n    let target_rewritten = graph.is_ancestor(base, target);\n    let mut scope = Vec::new();\n    let mut scope_set = HashSet::new();\n    for id in graph\n        .descendants_in_parent_order(base)\n        .context(\"the stack base is not in the loaded history\")?\n        .into_iter()\n        .chain(\n            graph\n                .descendants_in_parent_order(target)\n                .context(\"the move target is not in the loaded history\")?,\n        )\n    {\n        if (id != target || target_rewritten) && scope_set.insert(id) {\n            scope.push(id);\n        }","sourceCodeStart":662,"sourceCodeEnd":698,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/rebase.rs#L662-L698","documentation":"The stack is moved to sit directly on top of `target`. If `base`'s current parent is already `target`, the stack already occupies exactly that position and the move is a no-op; the plan builder bails instead of producing an empty rewrite.","triggerScenarios":"Calling `move_insert_plan`/`stack_insert_plan(repo, graph, base, head, target)` where the parent of `base` equals `target` — i.e. repeating an already-applied move, or passing the natural current parent as target.","commonSituations":"Re-running the same move command twice (e.g. after a retried script); user selecting the commit the stack already sits on; automation replaying recorded operations.","solutions":["Skip the operation if the stack is already in the requested position.","Choose a different target commit.","Make the operation idempotent in caller code by checking `parent_of(base) == target` before invoking."],"exampleFix":"// before\nstack_insert_plan(&repo, &graph, base, head, target)?\n\n// after\nif graph.parents_of(base)?[0] != target {\n    stack_insert_plan(&repo, &graph, base, head, target)?;\n}","handlingStrategy":"validation","validationCode":"if graph.parents_of(base)?[0] == target {\n    eprintln!(\"stack is already directly above target; nothing to do\");\n    return Ok(());\n}","typeGuard":"fn move_changes_position(graph: &HistoryGraph, base: ObjectId, target: ObjectId) -> bool {\n    graph.parents_of(base).map(|p| p.first() != Some(&target)).unwrap_or(false)\n}","tryCatchPattern":"match stack_insert_plan(&repo, &graph, base, head, target) {\n    Err(e) if e.to_string().contains(\"already directly above\") => { /* treat as success/no-op */ }\n    other => other?,\n}","preventionTips":["Make repeated operations idempotent by checking current position first","Track already-applied moves in scripts to avoid replaying them","Default the destination picker away from the stack's current parent"],"tags":["git","rebase","no-op","idempotency"],"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-16T04:17:20.429Z"}