{"record":{"id":"8d24f9c5ab10eb07","repo":"GitoxideLabs/gitoxide","slug":"the-conflicted-head-attachment-does-not-directly-r","errorCode":null,"errorMessage":"the conflicted HEAD attachment does not directly reference {commit}","messagePattern":"the conflicted HEAD attachment does not directly reference (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/lib.rs","lineNumber":4380,"sourceCode":"    changes.clear();\n    result\n}\n\nfn conflict_head(repository_path: &Path, bare: bool, commit: gix::ObjectId) -> Result<ConflictHead> {\n    let repository = open_repository(repository_path, bare, false)\n        .context(\"could not reopen the repository after checking out a conflict\")?;\n    let head = repository.head().context(\"could not inspect the conflicted HEAD\")?;\n    let id = head\n        .id()\n        .map(gix::Id::detach)\n        .context(\"the conflicted HEAD is unborn\")?;\n    anyhow::ensure!(id == commit, \"the conflict checkout did not leave HEAD at {commit}\");\n    let reference = head.referent_name().map(ToOwned::to_owned);\n    drop(head);\n    let name = reference\n        .clone()\n        .unwrap_or_else(|| \"HEAD\".try_into().expect(\"valid reference name\"));\n    anyhow::ensure!(\n        edit::undo::state(&repository, name.as_ref())? == edit::undo::State::Object(commit),\n        \"the conflicted HEAD attachment does not directly reference {commit}\"\n    );\n    let parents = repository\n        .find_commit(commit)\n        .context(\"could not find the checked-out conflict commit\")?\n        .parent_ids()\n        .map(gix::Id::detach)\n        .collect();\n    Ok(ConflictHead { reference, parents })\n}\n\nfn reconcile_external_conflict(\n    repository_path: &Path,\n    bare: bool,\n    pending: &mut Option<PendingConflictResolution>,\n) -> Result<ExternalConflictResolution> {\n    let state = pending","sourceCodeStart":4362,"sourceCodeEnd":4398,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/lib.rs#L4362-L4398","documentation":"After confirming HEAD's id matches the conflict commit, the code checks the undo-state of HEAD's referent: it must directly reference (State::Object) the conflict commit, not be unborn, symbolic to something else, or resolving indirectly. The ensure fires when `edit::undo::state` reports anything other than `State::Object(commit)`.","triggerScenarios":"The HEAD referent's recorded undo state is not a direct object reference to `commit` — e.g. HEAD is unborn, attached to a branch pointing elsewhere, or the ref log/state was mutated after checkout.","commonSituations":"Undo bookkeeping interleaved with manual git commands that changed the branch HEAD points to; a detached-HEAD checkout where the expected attachment assumption breaks; stale undo state files.","solutions":["Re-attach HEAD to a reference that directly points at the conflict commit (e.g. `git checkout -B <branch> <commit>`).","Clear/rebuild the stale undo state (`edit::undo::state`) so it reflects the actual HEAD referent.","Repeat the conflict checkout so HEAD attachment and undo state are written together."],"exampleFix":"// before\nanyhow::ensure!(\n    edit::undo::state(&repository, name.as_ref())? == edit::undo::State::Object(commit),\n    \"the conflicted HEAD attachment does not directly reference {commit}\"\n);\n// after\nif edit::undo::state(&repository, name.as_ref())? != edit::undo::State::Object(commit) {\n    repository.reference(name.as_bstr(), commit, gix::refs::transaction::PreviousValue::Any)?;\n}","handlingStrategy":"validation","validationCode":"let state = edit::undo::state(&repo, referent.as_bstr())?;\nassert!(matches!(state, edit::undo::State::Object(id) if id == commit),\n    \"HEAD attachment must directly reference the conflict commit\");","typeGuard":"fn directly_references(state: &edit::undo::State, commit: gix::ObjectId) -> bool {\n    matches!(state, edit::undo::State::Object(id) if *id == commit)\n}","tryCatchPattern":"match edit::undo::state(&repo, name.as_bstr()) {\n    Ok(s) if s != edit::undo::State::Object(commit) => rebuild_undo_state(),\n    Ok(_) => proceed(),\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Always create/update undo state in the same transaction as the checkout.","Avoid manual `git checkout`/`git reset` on the same repo while undo state is live.","Rebuild undo state after any crash or external mutation."],"tags":["git","head","reference","undo-state"],"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"}