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

  1. Fix the metadata section so `before` and `after` differ; delete the no-op section if the ref truly did not change.
  2. Regenerate the undo metadata from the original operation instead of editing it by hand.
  3. Check the tool that wrote the metadata for recording no-op ref updates.
  4. 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

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


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(&section, &["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)