GitoxideLabs/gitoxide · error · anyhow::Error

(re-raised revision-spec parse error via bail!(err))

Error message

{err} (re-raised revision-spec parse error via bail!(err))

What it means

`explain` runs a revision-spec parse while collecting explanation callbacks; if the parser recorded an error via the `Explain` visitor, that error is re-raised with `bail!(err)`. The message text shown to users is the underlying gix revision-spec parse error (e.g. 'unknown revision or path not in the working tree'-style diagnostics), surfaced through anyhow. The comment placeholder `{err}` stands for the actual spec error text.

Solutions

  1. Fix the revision expression; verify the ref/commit exists with `git rev-parse <spec>`
  2. Check for typos and ambiguity in short object IDs
  3. Ensure the needed objects are present (unshallow shallow clones)
  4. Use `gix revision parse` or run the same spec against git to compare diagnostics

Example fix

// before
gix explain HEAD~^@
// after
gix explain HEAD~1
Defensive patterns

Strategy: validation

Validate before calling

# resolve the spec with git first to validate
if git rev-parse --verify --quiet "$spec"^{commit} >/dev/null; then
  gix explain "$spec"
fi

Try / catch

match gix_explain_result {
    Err(e) if e.to_string().contains("did not match") => eprintln!("invalid revision spec: {spec}"),
    Err(e) => return Err(e),
    Ok(_) => {}
}

Prevention

When it happens

Trigger: Calling `gix explain <spec>` (gitoxide-core/src/repository/revision/explain.rs::explain) with a revision expression that gix's `gix::revision::plumbing::spec::parse` cannot resolve: bad `~`/`^` selectors, nonexistent ref names, invalid `@{...}` expressions, or malformed range syntax.

Common situations: Typos in branch/tag names, using ranges or `^N` parent selectors on objects that don't support them, ambiguous short hashes, or specs referencing objects missing from a shallow/partial clone.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/e7a16ce0d705c720. Report an issue: GitHub.

Appendix: source

Thrown at gitoxide-core/src/repository/revision/explain.rs:19

use anyhow::bail;
use gix::{
    Exn,
    bstr::{BStr, BString},
    revision::plumbing::{
        spec,
        spec::parse::{
            Delegate, delegate,
            delegate::{PeelTo, ReflogLookup, SiblingBranch, Traversal},
        },
    },
};

pub fn explain(spec: std::ffi::OsString, mut out: impl std::io::Write) -> anyhow::Result<()> {
    let mut explain = Explain::new(&mut out);
    let spec = gix::path::os_str_into_bstr(&spec)?;
    gix::revision::plumbing::spec::parse(spec, &mut explain).map_err(gix::Error::from)?;
    if let Some(err) = explain.err {
        bail!(err);
    }
    Ok(())
}

struct Explain<'a> {
    out: &'a mut dyn std::io::Write,
    call: usize,
    ref_name: Option<BString>,
    oid_prefix: Option<gix::hash::Prefix>,
    has_implicit_anchor: bool,
    err: Option<String>,
}

impl<'a> Explain<'a> {
    fn new(out: &'a mut impl std::io::Write) -> Self {
        Explain {
            out,
            call: 0,

View on GitHub (pinned to e73179060b)