Skip to content
masterclass Buddy

Git · Command

git clean

git clean deletes untracked files from your working tree. It can also delete untracked directories and files that Git ignores, so you can get back to a pristine checkout.

Last updated

How it works

Starting from the current directory, git clean works through the working tree and finds paths that are not tracked. By default it only picks unknown files that are not ignored, and it does not go into untracked directories. Flags change what it targets: -d includes untracked directories, -x includes ignored files, -X targets only ignored files, and pathspecs limit the paths it touches. Because deletions can't be undone, it refuses to run without -f unless clean.requireForce is false. You can also use -n to preview or -i to choose items interactively.

Syntax

git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] [<pathspec>…]

Parameters

NameTypeDescription
-dflagGo into untracked directories and remove them too when no pathspec is given.
-f, --forceflagRequired to delete anything unless clean.requireForce is false. Give it twice to also remove untracked nested Git repositories.
-i, --interactiveflagList the candidates and let you choose what to delete in an interactive menu.
-n, --dry-runflagOnly report what would be removed, without deleting anything.
-q, --quietflagPrint errors only, not the files that were removed.
-e <pattern>, --exclude=<pattern>stringAdd an exclude pattern on top of the standard ignore rules, so matching files are kept.
-xflagIgnore the standard ignore rules so that ignored files are removed as well. Patterns given with -e still apply.
-XflagRemove only the files that Git ignores.
<pathspec>…pathspecRestrict the cleanup to paths that match these patterns.

Key points

  • The cleanup starts at your current directory and works down from there, not from the repository root, so running it in a subfolder only affects that subtree.
  • Without a pathspec, untracked directories are left alone on purpose. You have to add -d to remove them as well.
  • -X is the opposite of the default: it removes only ignored files, such as build output, and keeps untracked files you created by hand.
  • -e adds your own patterns to protect files from deletion, and those patterns still apply when -x turns off the standard ignore rules.
  • The clean.requireForce setting is true by default, which is why a plain git clean with no flags refuses to delete anything.
  • Interactive mode doesn't need -f because it asks for confirmation itself. Its menu lets you filter by pattern, select items by number or range, or confirm each item one at a time.
  • Use -q in scripts to hide the list of removed files so that only errors are printed.

Common mistakes

  • Once you give a pathspec, every matching untracked file goes, including files inside untracked directories, whether or not you passed -d.
  • Even with -f, untracked directories that contain their own .git (for example, nested clones) are kept. You need -ff to delete them, and that also deletes their history.
  • -x also deletes ignored local files such as .env files or editor settings, not just build artifacts. Preview with -n first, or protect those files with -e.

Example: Preview, then reset the working tree to a pristine state

#!/usr/bin/env bash
set -euo pipefail

# 1. See what would be deleted (untracked dirs + ignored files), keeping .env
git clean -n -d -x -e .env

# 2. Discard changes to tracked files
git restore --staged --worktree .

# 3. Actually delete untracked and ignored files/dirs, still keeping .env
git clean -f -d -x -e .env

# Alternative: wipe only ignored build output, keep hand-made files
# git clean -f -d -X

The script previews the cleanup with -n, resets tracked files with git restore, then deletes untracked and ignored files and directories while -e keeps .env.

When to use it

Clean build verification

Before a release build, combine git restore with git clean -fdx so the build starts from exactly what is committed, with no leftover artifacts.

Clearing merge leftovers

After a messy merge or rebase, remove stray .orig files and scratch files with git clean -i, picking only the ones you no longer need.

Rebuild from scratch, keep notes

Run git clean -fX to delete ignored outputs such as compiled objects while keeping untracked notes or drafts you haven't committed yet.

Interview questions

QWhy does running plain git clean often do nothing except print an error?

The clean.requireForce setting defaults to true, so git clean refuses to delete files unless you pass -f. This guards against accidental data loss, because the files it removes are untracked and Git cannot recover them. The -n and -i modes don't need -f, since one deletes nothing and the other asks before deleting.

Follow-up: Does git clean -f remove an untracked directory that contains a cloned repo? No. Untracked nested repositories, meaning directories with a .git subdirectory, are only removed if you give -f twice.

QWhat is the difference between -x and -X?

-x stops applying the standard ignore rules, so it removes both ignored files and ordinary untracked files. -X removes only files Git ignores and keeps untracked files you created yourself. Use -x when you want everything gone, and -X when you only want to rebuild artifacts.

Follow-up: Can you protect a file while using -x? Yes. Patterns passed with -e still apply when -x is used, so git clean -fdx -e .env keeps .env.

QHow does -d interact with a pathspec?

Without a pathspec, git clean skips untracked directories unless you pass -d. Once you give a pathspec, -d makes no difference: every untracked file that matches is removed, except for nested Git repositories.

Follow-up: Where does git clean start when you run it from a subdirectory? It starts in the current directory and works downward, so files above or beside it are left alone.

  • git restore
  • git reset
  • git stash
  • git status
  • gitignore
  • git config

Source: Git - git-clean Documentation. Checked 2026-11-02.