{"record":{"id":"2b6b6a7f15487743","repo":"GitoxideLabs/gitoxide","slug":"the-reword-target-or-one-of-its-descendants-must-b","errorCode":null,"errorMessage":"the reword target or one of its descendants must be pinned","messagePattern":"the reword target or one of its descendants must be pinned","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/command/reword.rs","lineNumber":114,"sourceCode":"    let head = repository.head().context(\"could not read HEAD after editing commit\")?;\n    let attached_head = !head.is_detached() && head.id().map(gix::Id::detach) == Some(target);\n    drop(head);\n    ensure_retained_target(&graph, target, &pins, attached_head)?;\n    let output_repository = repository.clone();\n    finish_editor(\n        &output_repository,\n        crate::edit::reword::apply(repository, &graph, target, &edited)?,\n    )\n}\n\nfn ensure_retained_target(\n    graph: &crate::history::HistoryGraph,\n    target: gix::ObjectId,\n    pins: &[crate::history::Pin],\n    attached_head: bool,\n) -> Result<()> {\n    if !attached_head && !pins.iter().any(|pin| graph.is_ancestor(target, pin.id)) {\n        anyhow::bail!(\"the reword target or one of its descendants must be pinned\");\n    }\n    Ok(())\n}\n\npub(super) fn explicit_message(args: &MessageArgs, mut stdin: impl Read) -> Result<Option<Vec<u8>>> {\n    if !args.message.is_empty() {\n        let mut out = Vec::new();\n        for (index, message) in args.message.iter().enumerate() {\n            if index > 0 {\n                out.extend_from_slice(b\"\\n\\n\");\n            }\n            out.extend_from_slice(\n                gix::path::os_str_into_bstr(message)\n                    .with_context(|| format!(\"message {} is not valid UTF-8\", index + 1))?,\n            );\n        }\n        return Ok(Some(out));\n    }","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/command/reword.rs#L96-L132","documentation":"Rewording a commit that is not reachable from HEAD and not covered by any pin would leave the old commit garbage-collectable with no way back. ensure_retained_target requires that the reword target (or a pinned descendant of it) is retained — pinned — unless HEAD itself is attached to the history containing it. This protects against rewriting commits that nothing references.","triggerScenarios":"Calling `tix reword` for a target OID while in detached HEAD state and no pin in `tix history` pins covers the target via is_ancestor.","commonSituations":"Rewording an old commit on a detached HEAD; pins expired or never created; editing a commit from a branch that was since deleted or rewritten.","solutions":["Pin the target (or a descendant) with `tix pin` before rewording","Re-attach HEAD to the branch containing the target, then reword","Verify pins with `tix history` / pin listing to see why retention check fails"],"exampleFix":"// before\ntix reword <oid> -m \"new message\"   # detached HEAD, no pins\n// after\ntix pin <oid>\ntix reword <oid> -m \"new message\"","handlingStrategy":"validation","validationCode":"// Before rewording, ensure the target is retained\nlet pins = crate::history::all_pins(&repo)?;\nlet attached = repo.head_detached() == Ok(false);\nif !attached && !pins.iter().any(|p| graph.is_ancestor(target, p.id)) {\n    // create a pin first\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = tix_reword(target, msg) {\n    if e.to_string().contains(\"must be pinned\") {\n        tix_pin(target)?;\n        tix_reword(target, msg)?;\n    } else { return Err(e); }\n}","preventionTips":["Pin targets before rewriting them when detached","Avoid rewording commits on deleted/rewritten branches","Regularly review and refresh pins"],"tags":["cli","reword","pin","git-history"],"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"}