git clean
On this page, you will learn about the git clean command, find out the difference between git clean and git reset, see the common options and usage.

What git clean does
The git clean command removes untracked files from your working directory. An untracked file is one that exists on disk but Git is not following it yet, that is, it has never been git add-ed and is not in the index.
This makes git clean different from its neighbours among the undo commands:
- git reset moves the branch tip and can unstage tracked changes.
- git checkout restores tracked files to a previous state.
git cleandeletes the files Git is not tracking at all.
Together they cover the whole working tree: reset/checkout handle tracked and staged content, clean handles the rest. A typical use is wiping build artifacts, generated files, or experiment leftovers so you start from a pristine copy of the committed tree.
git cleanis irreversible. It deletes files straight from the file system, not into a recoverable area like the stash. There is nogit cleanundo. Always preview with a dry run (-n) first.
The example below sets up a repository with one tracked and several untracked items so you can see the distinction:
Set up a sample repository
mkdir test_directory
cd test_directory/
git init .
#Initialized empty Git repository in /Users/kev/code/test_directory/.git/
echo "tracked file" > ./test_tracked_file
git add ./test_tracked_file
echo "untracked" > ./test_untracked_file
mkdir ./test_untracked_dir && touch ./test_untracked_dir/file
git status
#On branch master
#No commits yet
#Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
# new file: test_tracked_file
#Untracked files:
# (use "git add <file>..." to include in what will be committed)
# test_untracked_dir/
# test_untracked_fileAfter running this you have a fresh repository with one staged file, test_tracked_file, plus an untracked file (test_untracked_file) and an untracked directory (test_untracked_dir). git status reports them in separate sections, exactly the split that git clean cares about. Everything that follows operates on this repository.
Why force is required
Run the bare command and Git refuses:
git clean
#fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given; refusing to cleanBecause the deletion is permanent, Git will not run unless you opt in with -f (force), -n (dry run), or -i (interactive). You can flip the default with the git config setting clean.requireForce, but leaving it on is the safe choice.
Common options and usage
The behaviour of git clean is controlled almost entirely by a handful of short flags, which combine freely.
-n: dry run (preview)
The -n (or --dry-run) flag lists what would be removed without deleting anything. Make this your default first step.
git clean -n
#Would remove test_untracked_fileThe output names test_untracked_file. Notice the untracked directory is not listed, because by default git clean ignores directories (see -d below).
-f: force the deletion
The -f (or --force) flag actually performs the deletion. It is required unless clean.requireForce is set to false.
git clean -f
#Removing test_untracked_filetest_untracked_file is now gone; a follow-up git status no longer lists it. By default git clean -f acts on every untracked file in the current directory. Files matched by .gitignore are left alone unless you add -x (below).
To limit the operation to a specific location, pass a path:
git clean -f path/to/dir-d: include untracked directories
By default git clean skips untracked directories. Add -d to remove them too. Combine it with -n for a preview, then -f to commit:
git clean -dn
#Would remove test_untracked_dir/
#Would remove test_untracked_file
git clean -df
#Removing test_untracked_dir/
#Removing test_untracked_fileWith -d the dry run now lists the directory as well as the untracked file, and the forced run removes both, deleting the directory and everything inside it.
-x: include ignored files
Normally git clean respects .gitignore. The -x flag tells it to also delete ignored files, things like node_modules/, build output, or editor folders such as .idea/. This is powerful and easy to regret, so always dry-run it first.
git clean -xn
#Would remove .idea/
#Would remove build/-x composes with the other flags. The combination below wipes untracked files, untracked directories, and ignored files in one go, the equivalent of "reset this checkout to exactly what is committed":
git clean -xdfQuick reference
| Command | Effect |
|---|---|
git clean -n | Preview removable untracked files |
git clean -f | Delete untracked files |
git clean -df | Delete untracked files and directories |
git clean -xf | Delete untracked and ignored files |
git clean -xdf | Delete everything not committed (files, dirs, ignored) |
git clean -i | Step through removals interactively |
Interactive mode
If you are unsure exactly what should go, run git clean in interactive mode with the -i flag. It is the safest way to clean a messy working tree, because nothing is deleted until you confirm. The example below adds -d as well so directories are included. Git prints the candidate items and then a What now> prompt offering six commands:
git clean -di
#Would remove the following items:
# test_untracked_dir/ test_untracked_file
#*** Commands ***
# 1: clean 2: filter by pattern 3: select by numbers
# 4: ask each 5: quit 6: help
#What now>Here is what each command does.
6 — help. Type 6 to print a description of every command:
What now> 6
#clean - start cleaning files and directories
#filter by pattern - exclude items from deletion
#select by numbers - select items to be deleted by numbers
#ask each - confirm each deletion (like "rm -i")
#quit - stop cleaning
#help - this screen
#? - help for prompt selection1 — clean. Deletes the items currently listed, then exits:
What now> 1
#Removing test_untracked_dir/
#Removing test_untracked_file2 — filter by pattern. Lets you exclude items by glob. Here the *_file pattern removes test_untracked_file from the deletion list, leaving only the directory queued:
What now> 2
#test_untracked_dir/ test_untracked_file
#Input ignore patterns>> *_file
#test_untracked_dir/3 — select by numbers. Refines the list by item number rather than pattern. Git numbers each candidate and you type the ones to keep:
What now> 3
# 1: test_untracked_dir/ 2: test_untracked_file
#Select items to delete>>4 — ask each. Walks through every candidate with a y/N prompt, like rm -i. Answer N to keep an item:
What now> 4
#Remove test_untracked_dir/ [y/N]? N
#Remove test_untracked_file [y/N]? N5 — quit. Leaves interactive mode without deleting anything:
What now> 5
#Bye.git clean vs. stashing and resetting
git clean only touches untracked files, so reach for it when you want to throw work away rather than save it. If you might want the changes back later, prefer one of these instead:
- git stash — shelves tracked modifications (and, with
-u, untracked files) so you can restore them later. Reversible. - git reset — moves the branch tip and unstages or discards tracked changes.
- git checkout — restores tracked files to their committed state.
A common full reset of a working tree is to combine reset for tracked content with clean for untracked content:
git reset --hard # discard tracked changes
git clean -xdf # remove untracked and ignored filesAfter those two commands the working directory exactly matches the last commit, with no leftover files of any kind.