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
- Commit or revert the modified tracked files so the repository is clean (for IsClean mode)
- Add untracked files to the index if they should count towards dirtiness
- Note the check ignores untracked files — clean them with `git clean` equivalents or adjust expectations
- 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
- Remember this check ignores untracked files — handle them separately
- Commit or stash changes before asserting cleanliness in CI
- Use Mode::IsDirty when you want to assert the tree is actually dirty
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
- Only human format is supported right now
- Only the simplified format is currently implemented
- interrupted by user
- Cannot run without any task to perform on the repositories
- interrupted by user
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)