W3docs

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.

gitclean

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 clean deletes 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 clean is irreversible. It deletes files straight from the file system, not into a recoverable area like the stash. There is no git clean undo. 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_file

After 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 clean

Because 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_file

The 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_file

test_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_file

With -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 -xdf

Quick reference

CommandEffect
git clean -nPreview removable untracked files
git clean -fDelete untracked files
git clean -dfDelete untracked files and directories
git clean -xfDelete untracked and ignored files
git clean -xdfDelete everything not committed (files, dirs, ignored)
git clean -iStep 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 selection

1 — clean. Deletes the items currently listed, then exits:

What now> 1
#Removing test_untracked_dir/
#Removing test_untracked_file

2 — 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]? N

5 — 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 files

After those two commands the working directory exactly matches the last commit, with no leftover files of any kind.

Practice

Practice
What are the functionalities and options of the 'git clean' command?
What are the functionalities and options of the 'git clean' command?
Was this page helpful?