GitoxideLabs/gitoxide · error · anyhow::Error

{msg} {suffix}

Error message

{msg} {suffix}

What it means

The dirty check concludes with a message about untracked files: the repository-local `is_dirty()` does not consider untracked files, so success/failure is reported with the suffix "(not counting untracked files)". When the result is the failure branch (repo dirty when checking IsClean, or clean when checking IsDirty), this message is raised as an error.

Solutions

  1. Commit or revert the modified tracked files so the repository is clean (for IsClean mode)
  2. Add untracked files to the index if they should count towards dirtiness
  3. Note the check ignores untracked files — clean them with `git clean` equivalents or adjust expectations
  4. Use the opposite Mode if you intended the other assertion

Example fix

// before
dirty::check(repo, Mode::IsClean, out, format)?; // fails when tracked changes exist
// after
// commit or stash changes first, then:
dirty::check(repo, Mode::IsClean, out, format)?;
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check tracked-file dirtiness before asserting IsClean
let is_dirty = repo.is_dirty()?;
if is_dirty {
    eprintln!("working tree has tracked changes; commit or stash first");
}

Try / catch

match dirty::check(repo, Mode::IsClean, &mut out, format) {
    Ok(()) => println!("clean (excluding untracked files)"),
    Err(e) => {
        eprintln!("not clean: {e}");
        std::process::exit(1);
    }
}

Prevention

When it happens

Trigger: Running `gix status dirty` (check in gitoxide-core/src/repository/dirty.rs): it errors when mode is IsClean but the repository has changes, or mode is IsDirty but the repository is clean — always appending the untracked-files caveat.

Common situations: CI pipelines asserting a clean working tree fail because tracked files were modified (untracked-only changes are ignored by this check); developers expecting untracked files to count as dirty get a confusing result.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at gitoxide-core/src/repository/dirty.rs:30

    mode: Mode,
    out: &mut dyn std::io::Write,
    format: OutputFormat,
) -> anyhow::Result<()> {
    if format != OutputFormat::Human {
        bail!("JSON output isn't implemented yet");
    }
    let is_dirty = repo.is_dirty()?;
    let res = match (is_dirty, mode) {
        (false, Mode::IsClean) => Ok("The repository is clean"),
        (true, Mode::IsClean) => Err("The repository has changes"),
        (false, Mode::IsDirty) => Err("The repository is clean"),
        (true, Mode::IsDirty) => Ok("The repository has changes"),
    };

    let suffix = "(not counting untracked files)";
    match res {
        Ok(msg) => writeln!(out, "{msg} {suffix}")?,
        Err(msg) => bail!("{msg} {suffix}"),
    }
    Ok(())
}

View on GitHub (pinned to e73179060b)