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.
Git · Command
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
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.
git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] [<pathspec>…]| Name | Type | Description |
|---|---|---|
-d | flag | Go into untracked directories and remove them too when no pathspec is given. |
-f, --force | flag | Required to delete anything unless clean.requireForce is false. Give it twice to also remove untracked nested Git repositories. |
-i, --interactive | flag | List the candidates and let you choose what to delete in an interactive menu. |
-n, --dry-run | flag | Only report what would be removed, without deleting anything. |
-q, --quiet | flag | Print errors only, not the files that were removed. |
-e <pattern>, --exclude=<pattern> | string | Add an exclude pattern on top of the standard ignore rules, so matching files are kept. |
-x | flag | Ignore the standard ignore rules so that ignored files are removed as well. Patterns given with -e still apply. |
-X | flag | Remove only the files that Git ignores. |
<pathspec>… | pathspec | Restrict the cleanup to paths that match these patterns. |
git clean with no flags refuses to delete anything.#!/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 -XThe script previews the cleanup with -n, resets tracked files with git restore, then deletes untracked and ignored files and directories while -e keeps .env.
Before a release build, combine git restore with git clean -fdx so the build starts from exactly what is committed, with no leftover artifacts.
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.
Run git clean -fX to delete ignored outputs such as compiled objects while keeping untracked notes or drafts you haven't committed yet.
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.
-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.
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 restoregit resetgit stashgit statusgitignoregit config