Skip to content
LatchkeyLatchkey home

git clean -fdx vs -fdX: Removing Untracked Files

git clean -fd removes untracked files and directories; adding -x also removes ignored files (build output), while -X removes only the ignored ones, leaving new source untouched.

Resetting a runner workspace means deleting untracked junk, but the difference between lowercase -x and uppercase -X decides whether you wipe build caches or only them. Always dry-run with -n first.

What it does

git clean deletes untracked files. -f is required to actually delete (force). -d also recurses into untracked directories. -x removes files that .gitignore would normally protect (node_modules, dist), giving a pristine tree. -X removes only ignored files and keeps untracked, not-yet-added source. -n shows what would be deleted without deleting.

Common usage

Terminal
git clean -n -d                 # dry run: list what would go
git clean -fd                   # remove untracked files + dirs
git clean -fdx                  # also remove ignored (full reset)
git clean -fdX                  # remove ONLY ignored files
# combine with hard reset for a pristine workspace
git reset --hard && git clean -fdx

Options

FlagWhat it does
-f / --forceActually delete (required unless clean.requireForce=false)
-dRecurse into untracked directories
-xAlso remove ignored files (use the full ignore set)
-XRemove ONLY ignored files, keep other untracked files
-n / --dry-runList what would be removed without removing
-e <pattern>Add an exclude pattern on top of .gitignore

In CI

On persistent or self-hosted runners, git clean -fdx between jobs prevents stale artifacts from leaking into a build, but it also blows away caches, so weigh -fdx (full reset) against -fdX (drop only ignored build output). git reset --hard does not touch untracked files; pair it with git clean to truly reset. Dry-run with -n in a new pipeline before trusting -f.

Common errors in CI

"fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given" means you forgot -f. "Cowardly refusing to clean the current working directory" can appear in edge cases; run from the repo root. Surprise deletion of needed files usually means -x was used where -X (ignored only) was intended.

Using this in CI

CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.

.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git rev-parse --abbrev-ref HEAD          # prints HEAD when detached

Frequently asked questions

git clean -fdx vs -fdX: Removing Untracked Files?
Resetting a runner workspace means deleting untracked junk, but the difference between lowercase -x and uppercase -X decides whether you wipe build caches or only them. Always dry-run with -n first.
What it does?
git clean deletes untracked files. -f is required to actually delete (force). -d also recurses into untracked directories. -x removes files that .gitignore would normally protect (node_modules, dist), giving a pristine tree. -X removes only ignored files and keeps untracked, not-yet-added source.
In CI?
On persistent or self-hosted runners, git clean -fdx between jobs prevents stale artifacts from leaking into a build, but it also blows away caches, so weigh -fdx (full reset) against -fdX (drop only ignored build output). git reset --hard does not touch untracked files; pair it with git clean to truly reset.
Common errors in CI?
"fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given" means you forgot -f. "Cowardly refusing to clean the current working directory" can appear in edge cases; run from the repo root. Surprise deletion of needed files usually means -x was used where -X (ignored only) was intended.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card