Git Clean

git clean removes untracked files and directories, which is how build output and leftovers get out of your way.

git clean deletes files Git does not track. It is the counterpart to git restore, which fixes tracked files: restore puts your source back, clean removes the things you never committed.

That makes it genuinely useful and genuinely dangerous. A file Git has never seen is a file it cannot restore, because it was never in a commit.

There is no undo:

Nothing git clean deletes can be recovered with git checkout or the reflog, because none of it was ever tracked. Always run it with -n first.

Dry run, always

git clean -n

-n lists what would be deleted without deleting it. This is the habit worth building, and it costs nothing.

What it deletes and what it leaves

git clean -n          # untracked files
git clean -nd         # and untracked directories
git clean -ndx        # and ignored files too

By default git clean removes untracked files but leaves directories alone, and never touches anything matched by .gitignore. That last part is why it is usually the wrong command for cleaning node_modules — those files are ignored, so you need -x.

The full form

git clean -ndx        # show everything that would go
git clean -fdx        # do it

-f is required for directories and for ignored files, so it is a deliberate speed bump. -i prompts for each one instead.

What people actually use it for

git clean -fd         # throw away scratch files and merged-away branches' leftovers
git clean -fdx        # a full reset of node_modules, dist, .env.local

A common pair with a checkout, when switching branches has left build output from a branch that no longer exists:

git clean -fdx && git switch other-branch

Safer alternatives

If the file is build output, delete it through the tool that made it rather than through Git — rm -rf node_modules is the same result, and npm ci or bun install is what puts it back. Git is a reasonable place to clean up build artefacts, but it is not the only one, and reaching for it out of habit means running a command that can eat a file you forgot about.

Before deleting something you did not expect to be untracked

git status --ignored

Files that Git considers ignored still exist and may hold work. git clean -x removes those too, which is occasionally what you want and occasionally surprising. See .gitignore for what belongs in it.