GitoxideLabs/gitoxide · error
an undo ref does not change
Error message
an undo ref does not change
What it means
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.
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.
Example fix
// before [undo-ref "refs/heads/main"] before = object:1a2b3c... after = object:1a2b3c... // after [undo-ref "refs/heads/main"] before = object:1a2b3c... after = object:9f8e7d...
Defensive patterns
Strategy: validation
Validate before calling
fn undo_section_changes(before: &State, after: &State) -> bool {
before != after
} Try / catch
match parse_undo_metadata(&repo, &text) {
Err(e) if e.to_string().contains("an undo ref does not change") => {
eprintln!("A section has identical before/after; remove the no-op section");
}
res => res?,
} Prevention
- 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
When it happens
Trigger: `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>`.
Common situations: 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.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- undo metadata contains an unknown section
- the undo queue records itself
- undo reference sections are duplicated or out of order
- the undo queue is not a selectable revision
- undo metadata has missing, repeated, or unknown keys
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/977f4da89aade5bd.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/undo.rs:634
let subsection = section
.header()
.subsection_name()
.context("an undo ref section has no reference name")?;
let name = FullName::try_from(subsection).context("an undo entry contains an invalid reference name")?;
ensure!(!is_queue_ref(name.as_bstr()), "the undo queue records itself");
if let Some(previous) = &previous_name {
ensure!(
previous < &name,
"undo reference sections are duplicated or out of order"
);
}
previous_name = Some(name.clone());
ensure_exact_keys(§ion, &["before", "after"])?;
let before = section.value("before").context("an undo ref has no before-state")?;
let before = parse_state(repo, before.as_bstr())?;
let after = section.value("after").context("an undo ref has no after-state")?;
let after = parse_state(repo, after.as_bstr())?;
ensure!(before != after, "an undo ref does not change");
changes.push(RefChange { name, before, after });
}
Ok(changes)
}
fn ensure_exact_keys(section: &gix::config::file::SectionRef<'_>, expected: &[&str]) -> Result<()> {
let actual: Vec<_> = section.value_names().collect();
ensure!(
actual == expected,
"undo metadata has missing, repeated, or unknown keys"
);
Ok(())
}
fn parse_state(repo: &gix::Repository, value: &BStr) -> Result<State> {
if value == b"missing" {
return Ok(State::Missing);
}View on GitHub (pinned to e73179060b)