{"record":{"id":"5023aa7821ba777d","repo":"GitoxideLabs/gitoxide","slug":"the-undo-sentinel-contains-reference-changes","errorCode":null,"errorMessage":"the undo sentinel contains reference changes","messagePattern":"the undo sentinel contains reference changes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/undo.rs","lineNumber":856,"sourceCode":"        .context(\"could not own an undo queue commit\")?;\n    ensure!(\n        commit.tree == ObjectId::empty_tree(repo.object_hash()),\n        \"an undo queue commit does not use the empty tree\"\n    );\n    let message = gix::objs::commit::MessageRef::from_bytes(&commit.message);\n    let title = message\n        .title\n        .to_str()\n        .context(\"an undo operation title is not UTF-8\")?\n        .to_owned();\n    validate_title(&title)?;\n    let body = message.body.context(\"an undo queue commit has no metadata body\")?;\n    let changes = parse_config(repo, body)?;\n    let parent = commit.parents.first().copied();\n    match parent {\n        None => {\n            ensure!(title == START_TITLE, \"the undo sentinel has the wrong title\");\n            ensure!(changes.is_empty(), \"the undo sentinel contains reference changes\");\n        }\n        Some(parent) => {\n            ensure!(!changes.is_empty(), \"an undo operation contains no reference changes\");\n            let expected = retention_parents(repo, parent, &changes)?;\n            ensure!(\n                commit.parents.as_slice() == expected,\n                \"an undo commit has invalid retention parents\"\n            );\n        }\n    }\n    Ok(ParsedCommit { parent, title, changes })\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    fn repo() -> gix_testtools::Result<(gix_testtools::tempfile::TempDir, gix::Repository)> {","sourceCodeStart":838,"sourceCodeEnd":874,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/undo.rs#L838-L874","documentation":"The sentinel commit marks the start of the undo queue and must contain no reference changes — its body is empty configuration. `parse_commit` throws this when a parentless queue commit carries reference changes, which would make undo bookkeeping ambiguous.","triggerScenarios":"Calling `parse_commit` (via `is_queue_commit` or `load`) on a parentless undo queue commit whose parsed config body contains entries.","commonSituations":"Manually editing a sentinel commit's message to embed changes, or a tool rewriting the queue history and merging changes into the root commit.","solutions":["Regenerate the sentinel with an empty body by re-initializing the undo queue via the library","Move any reference changes into a proper child undo operation commit created by `record`","Avoid editing undo queue commit messages by hand"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match undo.load(repo) {\n    Err(e) if e.to_string().contains(\"sentinel\") => {\n        // rebuild the undo queue via the library\n    }\n    other => other?,\n}","preventionTips":["Never edit undo queue commit messages manually","Keep sentinel commits bodyless"],"tags":["git","undo","corruption"],"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"}