{"record":{"id":"d8b0762fd5bed87b","repo":"GitoxideLabs/gitoxide","slug":"an-undo-operation-contains-no-reference-changes","errorCode":null,"errorMessage":"an undo operation contains no reference changes","messagePattern":"an undo operation contains no reference changes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/undo.rs","lineNumber":859,"sourceCode":"        \"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)> {\n        let fixture = gix_testtools::scripted_fixture_writable(\"create_commit.sh\")?;\n        let repository = crate::test_repository::open(fixture.path())?;\n        Ok((fixture, repository))","sourceCodeStart":841,"sourceCodeEnd":877,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/undo.rs#L841-L877","documentation":"Each non-sentinel undo operation must record at least one reference change; an operation that changes nothing is meaningless. `parse_commit` throws this when a queue commit with a parent has an empty parsed changes set in its body.","triggerScenarios":"Calling `parse_commit` (via `is_queue_commit` or `load`) on a non-root undo queue commit whose message body parses to an empty set of reference changes.","commonSituations":"Recording an undo when no references actually changed (e.g. a no-op operation), or a commit whose body was truncated/edited so changes were lost.","solutions":["Skip recording undo operations when no reference changes were detected","Rebuild the queue entry with a body containing the actual reference changes via the library's `record` path","If the body was edited, restore the original commit message with the change entries"],"exampleFix":"// before\nif changes.is_empty() { undo.record(repo, title)?; }\n// after\nif !changes.is_empty() {\n    undo.record(repo, title)?;\n}","handlingStrategy":"validation","validationCode":"if changes.is_empty() {\n    // skip recording an undo operation entirely\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only call record when reference changes actually occurred","Re-verify queue commit bodies after any external history rewrite"],"tags":["git","undo","validation"],"backgroundTag":"empty-required-field","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"}