rust-lang/cargo · error · anyhow::Error
{} files in the working directory contain changes that were
Error message
{} files in the working directory contain changes that were not yet committed into git:
{}
to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag What it means
Before packaging, Cargo runs a git status check over the package source. If any tracked files (or files under the package root) are modified/uncommitted it bails, because the published crate would not match what is recorded in version control. The guard lives in cargo_package/vcs.rs and can be bypassed with --allow-dirty.
Source
Thrown at src/ops/cargo_package/vcs.rs:264
.chain(dirty_files_outside_pkg_root(ws, pkg, repo, src_files)?.iter())
.map(|path| {
pathdiff::diff_paths(path, cwd)
.as_ref()
.unwrap_or(path)
.display()
.to_string()
})
.collect();
let dirty = !dirty_src_files.is_empty();
if !dirty || opts.allow_dirty {
let maybe_head_id = repo.head()?.try_peel_to_id()?;
Ok(maybe_head_id.map(|id| GitVcsInfo {
sha1: id.to_string(),
dirty,
}))
} else {
dirty_src_files.sort_unstable();
anyhow::bail!(
"{} files in the working directory contain changes that were \
not yet committed into git:\n\n{}\n\n\
to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag",
dirty_src_files.len(),
dirty_src_files.join("\n")
)
}
}
/// Helper to collect dirty statuses for a single repo.
/// `relative_package_root` is `Some` if the root is a sub-directory of the workdir.
/// Writes dirty files outside `relative_package_root` into `dirty_files_outside_package_root`,
/// and all *everything else* into `dirty_files`.
#[must_use]
fn collect_statuses(
repo: &gix::Repository,
workdir: &Path,
relative_package_root: Option<&Path>,View on GitHub (pinned to 0e07a15537)
Solutions
- Commit or stash the uncommitted changes listed in the error, then re-run `cargo package`.
- If the changes are intentional and should ship in the crate, pass `--allow-dirty` (e.g. `cargo publish --allow-dirty`).
- Add generated/transient files to .gitignore so they no longer count as dirty.
Example fix
# before $ cargo publish error: 3 files in the working directory contain changes ... # after (commit first) $ git add -A && git commit -m "prep release" $ cargo publish # or, ship the dirty tree knowingly: $ cargo publish --allow-dirty
Defensive patterns
Strategy: validation
Validate before calling
# Fail fast if the worktree is dirty before packaging: if [ -n "$(git status --porcelain -- $PKG_ROOT)" ]; then echo "worktree dirty; commit or pass --allow-dirty" >&2 exit 1 fi cargo package
Prevention
- Always commit (or stash) before `cargo publish` so the crate matches HEAD.
- Use `cargo package --allow-dirty` only when you understand the published crate will diverge from git.
- CI: run `git diff --exit-code` (or stash) before publish.
When it happens
Trigger: Running `cargo package` or `cargo publish` while `git status` reports modified, staged-but-uncommitted, or untracked-in-source files for the package being packaged.
Common situations: Edited source after the last commit; generated files (e.g. from a codegen step) not added to git; switching branches with leftover changes; CI that builds from a dirty worktree.
Related errors
- cannot package a filename with a special character `{}`: {}
- Source directory was modified by build.rs during cargo publi
- found a virtual manifest at `{}` instead of a package manife
- all dependencies must have a version requirement specified w
- `{feature}` is unsupported when inferring the crate name, us
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/85f7c9fdb7f3d099.json.
Report an issue: GitHub.