{"record":{"id":"977f4da89aade5bd","repo":"GitoxideLabs/gitoxide","slug":"an-undo-ref-does-not-change","errorCode":null,"errorMessage":"an undo ref does not change","messagePattern":"an undo ref does not change","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/undo.rs","lineNumber":634,"sourceCode":"        let subsection = section\n            .header()\n            .subsection_name()\n            .context(\"an undo ref section has no reference name\")?;\n        let name = FullName::try_from(subsection).context(\"an undo entry contains an invalid reference name\")?;\n        ensure!(!is_queue_ref(name.as_bstr()), \"the undo queue records itself\");\n        if let Some(previous) = &previous_name {\n            ensure!(\n                previous < &name,\n                \"undo reference sections are duplicated or out of order\"\n            );\n        }\n        previous_name = Some(name.clone());\n        ensure_exact_keys(&section, &[\"before\", \"after\"])?;\n        let before = section.value(\"before\").context(\"an undo ref has no before-state\")?;\n        let before = parse_state(repo, before.as_bstr())?;\n        let after = section.value(\"after\").context(\"an undo ref has no after-state\")?;\n        let after = parse_state(repo, after.as_bstr())?;\n        ensure!(before != after, \"an undo ref does not change\");\n        changes.push(RefChange { name, before, after });\n    }\n    Ok(changes)\n}\n\nfn ensure_exact_keys(section: &gix::config::file::SectionRef<'_>, expected: &[&str]) -> Result<()> {\n    let actual: Vec<_> = section.value_names().collect();\n    ensure!(\n        actual == expected,\n        \"undo metadata has missing, repeated, or unknown keys\"\n    );\n    Ok(())\n}\n\nfn parse_state(repo: &gix::Repository, value: &BStr) -> Result<State> {\n    if value == b\"missing\" {\n        return Ok(State::Missing);\n    }","sourceCodeStart":616,"sourceCodeEnd":652,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/undo.rs#L616-L652","documentation":"When parsing undo metadata, each `[undo-ref ...]`-style section must carry distinct `before` and `after` states. `parse_config` raises this error when both parsed states are equal, because such a section records no actual change and would corrupt the undo plan.","triggerScenarios":"`parse_config` (called from `parse_commit`, undo.rs:634) reads a section whose `before` and `after` values parse to identical `State`s — e.g. both `missing`, both `object:<same-oid>`, or both `symbolic:<same-name>`.","commonSituations":"A hand-edited or tool-generated undo metadata file that duplicated the same OID in before/after; a snapshot taken after no-op ref update; a merge/rebase that resolved to identical values on both sides.","solutions":["Fix the metadata section so `before` and `after` differ; delete the no-op section if the ref truly did not change.","Regenerate the undo metadata from the original operation instead of editing it by hand.","Check the tool that wrote the metadata for recording no-op ref updates.","If intentional no-op sections should be tolerated, change `ensure!` to `continue` for equal states."],"exampleFix":"// before\n[undo-ref \"refs/heads/main\"]\n\tbefore = object:1a2b3c...\n\tafter = object:1a2b3c...\n// after\n[undo-ref \"refs/heads/main\"]\n\tbefore = object:1a2b3c...\n\tafter = object:9f8e7d...","handlingStrategy":"validation","validationCode":"fn undo_section_changes(before: &State, after: &State) -> bool {\n    before != after\n}","typeGuard":null,"tryCatchPattern":"match parse_undo_metadata(&repo, &text) {\n    Err(e) if e.to_string().contains(\"an undo ref does not change\") => {\n        eprintln!(\"A section has identical before/after; remove the no-op section\");\n    }\n    res => res?,\n}","preventionTips":["Never hand-edit undo metadata; regenerate it from the operation","Filter out no-op ref updates when the metadata is generated","Diff before/after values when reviewing metadata files","Validate each section's states differ before writing them"],"tags":["validation","config-parse","undo","no-op"],"backgroundTag":"invalid-config-value","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"}