{"record":{"id":"dddbdc1ad9d08497","repo":"GitoxideLabs/gitoxide","slug":"cannot-restore-an-unborn-checkout-after-review-set","errorCode":null,"errorMessage":"cannot restore an unborn checkout after review setup failed","messagePattern":"cannot restore an unborn checkout after review setup failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/review.rs","lineNumber":377,"sourceCode":"fn remove_new_departure_pin(repository_path: &Path, bare: bool, pin: Option<&(history::Pin, bool)>) -> Result<()> {\n    let Some((pin, true)) = pin else { return Ok(()) };\n    let repo =\n        open_repository(repository_path, bare, false).context(\"could not reopen repository to remove review pin\")?;\n    super::time_travel::delete_pin(&repo, pin).context(\"could not remove review departure pin\")\n}\n\nfn restore_checkout(workdir: &Path, restore: &(Option<gix::refs::FullName>, Option<ObjectId>)) -> Result<()> {\n    let mut command = Command::new(\"git\");\n    command.arg(\"-C\").arg(workdir).args([\"checkout\", \"--quiet\", \"--force\"]);\n    match restore {\n        (Some(name), _) => {\n            let name = gix::path::from_bstr(name.as_bstr());\n            command.arg(name.as_ref());\n        }\n        (None, Some(id)) => {\n            command.args([\"--detach\", &id.to_string()]);\n        }\n        (None, None) => anyhow::bail!(\"cannot restore an unborn checkout after review setup failed\"),\n    }\n    let output = command\n        .output()\n        .context(\"could not restore checkout after review setup failed\")?;\n    if output.status.success() {\n        Ok(())\n    } else {\n        anyhow::bail!(\"{}\", String::from_utf8_lossy(&output.stderr).trim())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    fn run(path: &Path, args: &[&str]) -> gix_testtools::Result<Vec<u8>> {\n        let output = Command::new(\"git\")\n            .arg(\"-C\")","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/review.rs#L359-L395","documentation":"If review setup fails midway, `restore_checkout` attempts to return the worktree to its previous position. When the repository had an unborn HEAD (a fresh repo with no commits — no branch target and no commit id recorded), there is nowhere to check out, so the restore is impossible and this error is raised during rollback.","triggerScenarios":"Review `start` failing on a repository with zero commits (HEAD points to a not-yet-created branch), triggering the rollback path in `restore_checkout` with `(None, None)`.","commonSituations":"Running `tix review` in a freshly `git init`ed repository before the first commit; a repo where all branches were deleted.","solutions":["Create an initial commit first (`git commit --allow-empty -m init`) so HEAD is born, then retry the review.","Manually restore the unborn-HEAD state: delete the branch HEAD was moved to (`git update-ref -d <branch>`) if setup partially completed.","Re-initialize the repository from scratch if it is disposable."],"exampleFix":"// before: review in an empty repo fails and cannot roll back\n// shell: git commit --allow-empty -m \"initial\"\n// after: retry the review command","handlingStrategy":"validation","validationCode":"let has_commits = repo.head_id().is_ok() || repo.head().ok().and_then(|h| h.try_into_referenced().ok()).is_some();\nif !has_commits {\n    return Err(anyhow::anyhow!(\"create an initial commit before starting a review\"));\n}","typeGuard":null,"tryCatchPattern":"match review::start(repo, params) {\n    Err(e) if e.to_string().contains(\"unborn checkout\") => {\n        eprintln!(\"repository has no commits; run: git commit --allow-empty -m init\");\n    }\n    other => other?,\n}","preventionTips":["Never run review workflows in freshly `git init`ed, commit-less repositories.","Check `git rev-parse HEAD` succeeds before review operations.","Require at least one commit in setup scripts or CI guards."],"tags":["git","unborn-head","rollback-failed"],"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"}