{"record":{"id":"3a87fb5764e447b7","repo":"GitoxideLabs/gitoxide","slug":"the-copy-source-and-target-must-differ","errorCode":null,"errorMessage":"the copy source and target must differ","messagePattern":"the copy source and target must differ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/rebase.rs","lineNumber":565,"sourceCode":") -> Result<Plan> {\n    let source_parents = graph\n        .parents_of(source)\n        .context(\"the copy source is not in the loaded history\")?;\n    let [_source_parent] = source_parents.as_slice() else {\n        anyhow::bail!(\"copying a commit requires it to have exactly one parent\");\n    };\n    let source_commit = repo\n        .find_commit(source)\n        .context(\"could not find the copy source\")?\n        .decode()\n        .context(\"could not decode the copy source\")?\n        .into_owned()\n        .context(\"could not own the copy source\")?;\n    if super::review::reference(&source_commit)?.is_some() {\n        anyhow::bail!(\"review commits cannot be copied\");\n    }\n    if source == target {\n        anyhow::bail!(\"the copy source and target must differ\");\n    }\n\n    let mut scope = graph\n        .descendants_in_parent_order(target)\n        .context(\"the copy target is not in the loaded history\")?;\n    scope.retain(|id| *id != target);\n    let mut steps = vec![PlanStep {\n        parent: PlanParent::Existing(target),\n        commit: PlanCommit::Copy(source),\n        squash: Vec::new(),\n    }];\n    let mut step_by_id = HashMap::with_capacity(scope.len());\n    for id in &scope {\n        let parents = graph.parents_of(*id).context(\"an affected copy commit is incomplete\")?;\n        let [parent] = parents.as_slice() else {\n            anyhow::bail!(\"copying a commit cannot rewrite root or merge commits\");\n        };\n        let parent = if *parent == target {","sourceCodeStart":547,"sourceCodeEnd":583,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/rebase.rs#L547-L583","documentation":"A copy operation requires the source commit and the target insertion point to be different commits. Inserting a commit 'after itself' is a no-op that would corrupt the plan's parent bookkeeping, so the plan builder rejects `source == target` up front.","triggerScenarios":"Calling `copy_insert_plan(repo, graph, source, target)` with the same `ObjectId` for both `source` and `target`, e.g. a UI or script that passes the selected commit for both fields.","commonSituations":"Interactive tooling where the user selects one commit and both 'copy this' and 'paste here' resolve to it; scripts with a defaulted/empty target argument falling back to the source.","solutions":["Pass a different target commit than the source.","If the intent is a no-op, skip calling the copy operation entirely when the IDs match.","Fix argument ordering in scripts so target is not accidentally bound to the source value."],"exampleFix":"// before\ncopy_insert_plan(repo, graph, id, id)\n\n// after\nif source != target {\n    copy_insert_plan(repo, graph, source, target)?;\n}","handlingStrategy":"validation","validationCode":"if source == target {\n    eprintln!(\"copy source and target must differ\");\n    return Ok(());\n}","typeGuard":"fn copy_args_valid(source: ObjectId, target: ObjectId) -> bool {\n    source != target\n}","tryCatchPattern":"match copy_insert_plan(&repo, &graph, source, target) {\n    Err(e) if e.to_string().contains(\"must differ\") => eprintln!(\"nothing to do: source equals target\"),\n    other => other?,\n}","preventionTips":["Guard at the command/UI layer before constructing a plan","Disable the 'copy here' action when the selected target equals the source","Validate distinctness of all id arguments in a single preflight function"],"tags":["git","rebase","invalid-argument","argument-validation"],"backgroundTag":"invalid-argument-value","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"}