{"record":{"id":"45f5d19572246cda","repo":"GitoxideLabs/gitoxide","slug":"head-must-be-the-review-commit-or-one-of-its-succe","errorCode":null,"errorMessage":"HEAD must be the review commit or one of its successors before it can be finished","messagePattern":"HEAD must be the review commit or one of its successors before it can be finished","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/review.rs","lineNumber":237,"sourceCode":"    fallback: Option<ObjectId>,\n) -> Result<Finish> {\n    finish_with_progress(repo, graph, review, fallback, |_| {})\n}\n\npub(crate) fn finish_with_progress(\n    repo: gix::Repository,\n    graph: &history::HistoryGraph,\n    review: ObjectId,\n    fallback: Option<ObjectId>,\n    report: impl FnMut(super::rebase::Progress),\n) -> Result<Finish> {\n    let workdir = repo\n        .workdir()\n        .context(\"finishing review requires a worktree\")?\n        .to_owned();\n    let head = repo.head_id()?.detach();\n    if !graph.is_ancestor(review, head) {\n        anyhow::bail!(\"HEAD must be the review commit or one of its successors before it can be finished\");\n    }\n    ensure_clean(&workdir)?;\n    let commit = repo.find_commit(review)?.decode()?.into_owned()?;\n    let review_ref = reference(&commit)?.context(\"the selected commit is not an active review\")?;\n    let base = commit\n        .parents\n        .first()\n        .copied()\n        .context(\"a review commit must have a base\")?;\n    let mut reference = repo\n        .find_reference(review_ref.as_ref())\n        .context(\"the review reference is missing\")?;\n    let legacy_reattach = reference.target().try_name().map(ToOwned::to_owned);\n    let tip = reference\n        .peel_to_id()\n        .context(\"the review reference does not resolve\")?\n        .detach();\n    let delete_refs = resources(&repo, review_ref.clone())?;","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/review.rs#L219-L255","documentation":"finishing a review requires HEAD to already be on the review commit or one of its descendants; the library checks `graph.is_ancestor(review, head)` before proceeding. If HEAD points elsewhere, the review's changes are not what is being finished and the operation is refused. This guards against finalizing a review from the wrong position in history.","triggerScenarios":"Calling `finish`/`finish_with_progress` while HEAD is an unrelated commit, an ancestor of the review commit, or on a divergent branch that does not contain the review commit.","commonSituations":"The user switched branches or time-traveled away from the review before finishing; the review was rebased so the old commit is no longer an ancestor of HEAD; a different review is checked out than the one passed to finish.","solutions":["Check out the review commit (or a successor) before calling finish: `git checkout <review-commit>` or use tix's travel/review commands.","Verify you passed the correct review commit id to finish — HEAD may legitimately contain a different review.","If the review branch was rebased, locate the rebased successor of the review commit and pass/checkout that instead."],"exampleFix":"// before: finishing while HEAD sits on main\nlet finished = review::finish(repo, graph, review_id, None)?;\n// after: ensure HEAD descends from the review first\nlet head = repo.head_id()?.detach();\nassert!(graph.is_ancestor(review_id, head), \"checkout the review commit first\");\nlet finished = review::finish(repo, graph, review_id, None)?;","handlingStrategy":"validation","validationCode":"let head = repo.head_id()?.detach();\nif !graph.is_ancestor(review_id, head) {\n    return Err(anyhow::anyhow!(\"checkout the review commit (or a successor) before finishing\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always check out the review commit before finishing.","Re-resolve review ids from the review refs after any rebase or history rewrite.","Verify with `git merge-base --is-ancestor <review> HEAD` before invoking finish."],"tags":["git","review-workflow","invalid-state-transition"],"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"}