TL;DR: gitでuntrackedファイルを消すには git clean -fd ——ただし必ず先に git clean -nd で確認を。cleanはゴミ箱を通さず、消したものは二度と戻りません。 -f がファイル、-fd がファイルとディレクトリ、gitignoreされたビルド成果物までまとめてなら -fdx です。最多の苦情「git cleanを実行してもuntrackedファイルが消えない」は、ほぼ必ずファイルがuntrackedなディレクトリの中にあるか(-d を足す)、無視ファイルであるか(-x を足す)のどちらかです。untrackedな散らかりは、実験とビルドとクローン周りのスクリプトが生む正常な副産物。このガイドでは、全削除を事前プレビューする方法、1ディレクトリだけ掃除する方法、そして大事なリポジトリで決して実行してはいけない組み合わせを示します。
git status の「untracked」は何を意味している?
untrackedとは、gitがそのファイルの存在はディスク上で認識しているが、追跡を一度も指示されていない状態——インデックスになく、コミット履歴もない——を指します。git status は全ファイルを3つのバケツに分けます:
$ git status --short
M src/app.ts # 変更済み: 追跡済みで、差分あり
?? notes.txt # untracked: gitの知らない新規ファイル
?? build/ # untrackedディレクトリ: gitには完全に新規 この区別が重要なのは、バケツごとに必要な除去ツールが違うからです。追跡済みだが変更されたファイルは git restore で戻すかコミットして片付けます——git clean は触りません。?? の行だけが git clean の領域です。そして無視ファイル(.gitignore に一致するもの)は隠れた第4のバケツです。?? としてすら表示されず、-x で明示的にオプトインしない限り git clean はスキップします。
本当の問題が「そもそもコミットされるべきでなかった追跡済みファイル」なら、掃除は誤った道具です。それは git rm --cached の仕事であり、直前のコミットのリセットなら git undo last commit: keep the changes で扱っています。
gitでuntrackedファイルを削除するには?
中心となるコマンドは git clean -f です。-f なしではgitは何も削除せず警告を表示するだけ——意図的な安全装置です。全体の流れはこうなります:
# 1. 何が消えるのか正確に確認する(dry run —— 何も削除しない)
git clean -nd
# 次のように表示されるはず:
# notes.txt
# build/
# scratch/
# 2. リストに大事なものがないことを確認し、本当に消す
git clean -fd フラグを1つずつ:
-f/--force— 必須。untrackedファイルを実際に削除する。-d— untrackedなディレクトリへ再帰的に入る。-fだけではトップレベルのuntrackedファイルしか消えず、断ったディレクトリが報告されるだけ。-n/--dry-run— 消えるはずのものを表示。必ず最初に実行。-x— 無視ファイルも削除する(node_modules、ビルド成果物、.env)。-X— 無視ファイルだけを削除し、untrackedだが無視されていないファイルは残す。-i— 対話モード。dry-runのリストが長いときに便利。
真似する価値のある習慣: git clean -nd を git diff と同じ扱いにする。コミット前にdiffを見るように、掃除の前に -nd を見る。
git cleanを実行してもuntrackedファイルが消えないのはなぜ?
実際に咬みつく頻度順に、原因は3つです:
1. ファイルがuntrackedなディレクトリの中にある。 -f だけでは、gitはバラのuntrackedファイルを消すもののディレクトリの前で止まり、実際の実行では Would remove build/ と報告しながら削除はしません。-d を足します:
git clean -fd 2. ファイルがgitignoreされている。 node_modules/、dist/、.venv/ —— 無視されたパスは素のcleanからは見えません。dry runにも載らず、cleanも消しません。明示的にオプトインします:
git clean -fdx # untracked + 無視ファイル・ディレクトリをまとめて 3. ネストしたgitリポジトリかサブモジュールが邪魔をしている。 gitは外側から別リポジトリの中身を絶対に削除しません。サブモジュールを正しく外すか、--force を2回渡します(git clean -ffd)。前者を推奨します。
dry runが何も表示しないのに git status がまだ ?? を出すなら、別のワーキングツリーにいる可能性が高い——git rev-parse --show-toplevel を実行して、掃除のつもりのリポジトリの中にいるか確認しましょう。
特定のディレクトリだけuntrackedファイルを削除するには?
パスを渡して掃除範囲を限定します——それ以外は一切触られません:
git clean -fd build/ # build/ の中だけ
git clean -fd src/generated # 特定の1ツリーだけ 「build/ のuntrackedファイルとフォルダは消したいが、リポジトリルートの作業メモは残したい」への答えがこれです。パスは現在ディレクトリ相対なので、リポジトリルートから実行すればリポジトリ全体、サブディレクトリから実行すればそのサブツリーに限定されます。
ファイルを消さずにuntrackedを片付けるには?
dry runに「後で欲しくなるかもしれない」ファイルが映ったら、賭けはしないこと。まず保存、それから掃除です:
# untrackedファイルを消さずにstashへ(-a なら無視ファイルも)
git stash push --include-untracked
git clean -fd # ツリーがきれいになる
git stash pop # 必要になったら戻す git stash -u はuntrackedファイルをツリーの外へ動かしつつ復元可能なまま保ちます——これこそ人々が本当に求めている「削除せずに除去する」のセマンティクスです。残しておけるプレビューなら、git clean -nd > clean-plan.txt が何も確定する前に正確なリストをくれます。git clean -f の後にはundoが存在しません: 削除は消滅です。
git clean vs git rm vs git restore:いつどれを使う?
| コマンド | 触れる対象 | ディスクから削除 | 使う場面 |
|---|---|---|---|
git clean -fd | untrackedファイル/ディレクトリ | はい | gitが追跡したことのないファイルを消したい |
git clean -fdx | untracked + 無視 | はい | node_modules、ビルド成果物込みのフルリセット |
git rm <file> | 追跡済みファイル | はい(ステージ) | ファイルを消し、その削除をgitに記録したい |
git rm --cached <file> | 追跡済みファイル | いいえ | 追跡をやめるがディスクには残したい |
git restore <file> | 追跡済みファイル | いいえ | ローカル編集を捨てて、ファイルは残したい |
一行でまとめると: cleanはgitが知らないものを管理し、rmとrestoreはgitが知っているものを管理する。 この取り違えが作業消失の定番です——git restore のつもりで git clean -fdx を実行する、という具合に。
git cleanを絶対に実行してはいけない場面は?
避けるべき習慣が2つあります:
- モノレポやワークスペースで
git clean -fdxを無思考に実行しない。 すべての無視ディレクトリを消します——ツリー内の全node_modules、全 virtualenv、全ローカル.env。取り戻すのに1時間の再インストールが発生し、削除された.envはそもそも復元不能な場合があります。 - force込みのエイリアスを作らない。
git config alias.wipe "clean -fd"は、パスをタイプミスするまで効率的に感じられます。dry runを1キー先に置き(git clean -nd)、プレビュー→削除の2コマンドの儀式にしましょう。
もう1つ知っておくと得: untrackedファイルの掃除を [sync a fork with upstream] のpull直前に済ませると、マージの接触面が小さくなります——整ったツリーは最も安上がりのコンフリクト保険です: sync a fork with upstream, step by step。
安全なgit cleanワークフロー、要点だけ
git status --short # ツリーに何がある?
git clean -nd # プレビュー: 何が消える予定か?
git clean -fd # untrackedファイル + ディレクトリを削除
git clean -fdX # (任意)無視されたビルド成果物だけ掃除
git status --short # 確認: ワーキングツリーがきれい プレビュー、削除、確認——30秒、後悔ゼロ。そして git status がようやく「きれい」を返してくれます。
— mrsaynothing
Get the next one by email
One email per post. No spam, no algorithms.
what is this?rsync vs scp:Linuxのコピーはどちらのコマンドを使うべきか
記事を楽しんでいただけましたか?私の本業はこのような構築です。 採用のご相談