このセクションでは git clean コマンドについて詳しく取り上げます。git clean はある程度「元に戻す」コマンドと似ています。git cleangit resetgit checkout などのコマンドに足りない部分を補完するものだと考えることができます。これらその他のコマンドでは、以前 Git トラッキングインデックスに追加されたファイルを操作しますが、git clean コマンドでは追跡対象外ファイルを操作します。追跡対象外ファイルとは、リポジトリの作業ディレクトリ内で作成されたものの、git add コマンドを使ってリポジトリのトラッキングインデックスにまだ追加されていないファイルのことです。追跡対象ファイルと追跡対象外ファイルをより分かりやすく説明するために、以下のコマンドラインサンプルを見てみてください。

 $ mkdir git_clean_test $ cd git_clean_test/ $ git init . Initialized empty Git repository in /Users/kev/code/git_clean_test/.git/ $ echo "tracked" > ./tracked_file $ git add ./tracked_file $ echo "untracked" > ./untracked_file $ mkdir ./untracked_dir && touch ./untracked_dir/file $ git status On branch master Initial commit Changes to be committed: (use "git rm --cached ..." to unstage) new file: tracked_file Untracked files: (use "git add ..." to include in what will be committed) untracked_dir/ untracked_file

このサンプルでは git_clean_test ディレクトリに新しい Git リポジトリを作成しています。その後、Git インデックスに追加される tracked_file が作成され、さらに untracked_fileuntracked_dir が作成されます。次に、git status を呼び出して追跡対象の変更と追跡対象外の変更の Git の内部状態を示す出力を表示しています。この状態のリポジトリで git clean コマンドを実行すると、このコマンドの本来の目的を実際に確認することができます。

 $ git clean fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given; refusing to clean

この時点でデフォルトの git clean コマンドを実行すると致命的なエラーが発生することがあります。上のサンプルはそのエラーがどのように表示されるかを示しています。Git は「force」オプションを渡さないと git clean を開始できないようデフォルトでグローバルに設定されています。これは重要な安全策です。最終的に git clean を実行すると、元の状態に戻すことはできません。エラーが発生せずに git clean が実行されると、ファイルシステムの削除が確定します。つまり、コマンドラインの rm ユーティリティを実行したときと同じような結果になります。コマンドを実行する前に、追跡対象外ファイルを削除しても本当に問題ないか確認してください。

一般的なオプションとその使用方法

git clean のデフォルトの動作と注意事項はさきほど説明したとおりですが、ここからは git clean のさまざまなユースケースと、それらのユースケースに必要なコマンドラインオプションを説明していきます。

-n

-n オプションでは git clean の「ドライラン」を実行します。このオプションを付けることで、実際に削除する前に削除対象のファイルを確認することができます。ファイルを削除するときは常に git clean のドライランを実行するようにしましょう。さきほど作成したデモ用リポジトリでこのオプションの実際の動作を確認することができます。

 $ git clean -n Would remove untracked_file

出力を見ると、git clean 実行時に untracked_file が削除されることがわかります。この出力では untracked_dir が報告されていないことに注目してください。デフォルトでは git clean はディレクトリで再帰的な操作を実行しません。これも誤って完全に削除してしまうのを防止する安全策の 1 つです。

 -f or --force

force オプションを付けると現在のディレクトリの追跡対象外ファイルの削除が実際に始まります。clean.requireForce 設定オプションを false に設定していない限り、force オプションを付ける必要があります。.gitignore で指定した、追跡対象外のフォルダーまたはファイルは削除されません。では実際にサンプルリポジトリで git clean を実行してみましょう。

 $ git clean -f Removing untracked_file

削除したファイルが出力されます。出力を見ると untracked_file が削除されていることがわかります。この時点で git status を実行するか、ls を実行すると、untracked_file が削除されていてどこにもないことがわかります。デフォルトでは現在のディレクトリのすべての追跡対象外ファイルが git clean -f の対象になります。また、 値を -f オプションとともに渡して特定のファイルを削除することもできます。

 git clean -f  -d include directories

-d オプションを git clean に付けるとすべての追跡対象外ディレクトリも削除します。デフォルトではディレクトリは無視されます。前のサンプルに -d オプションを付けてみましょう。

 $ git clean -dn Would remove untracked_dir/ $ git clean -df Removing untracked_dir/

ここでは -dn の組み合わせを使って「ドライラン」を実行し、untracked_dir が削除対象になるという結果が出力されました。この後強制クリーンを実行すると untracked_dir が削除されるという出力を得られます。

 -x force removal of ignored files

一般的なソフトウェアリリースのパターンには、リポジトリのトラッキングインデックスにコミットされないビルドディレクトリまたは配布ディレクトリがあります。ビルドディレクトリにはコミットされたソースコードから生成された一時的なビルドの中間生成物が格納されます。このビルドディレクトリは通常リポジトリの .gitignore ファイルに追加されます。追跡対象外の他のファイルがあるこのディレクトリを整理しておくと便利です。-x オプションを git clean に付けても無視されているファイルを指定することができます。前回の git clean の呼び出しのように、最終的に削除する前にまずは「ドライラン」を実行しておきましょう。-x オプションはプロジェクトビルドの特定のファイルだけでなく、無視されているすべてのファイルを対象にします。これは ./.idea IDE 構成ファイルのように想定外の結果を生む場合があります。

 git clean -xf 

-d オプション同様、-x を渡して他のオプションと組み合わせることができます。このサンプルでは -f と組み合わせて、現在のディレクトリの追跡対象外ファイルだけでなく、Git では通常無視されるすべてのファイルも削除します。

インタラクティブモードまたは git clean のインタラクティブ操作

ここまでにお見せしたアドホックなコマンドラインの実行だけでなく、git clean には「インタラクティブ」モードがあり、-i オプションを渡すとこのモードを開始できます。このドキュメントの最初で紹介したサンプルリポジトリに戻りましょう。初期状態のリポジトリでインタラクティブなクリーンセッションを開始します。

 $ git clean -di Would remove the following items: untracked_dir/ untracked_file *** Commands *** 1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit 6: help What now>

-d オプションを付けてインタラクティブセッションを開始したため、untracked_dir も操作対象になっています。インタラクティブモードには What now> というプロンプトが表示され、これに続けて追跡対象外ファイルに適用するコマンドを入力します。コマンド自体はその名前を見ればどのような動作をするかがわかるものになっています。ではランダムにコマンドを選んで少しだけ見ていきましょう。まずは 6: help です。コマンド 6 を選択すると他のコマンドの詳細が表示されます。

 What now> 6 clean - start cleaning 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
 5: quit

Is はシンプルなコマンドで、これを実行するとインタラクティブセッションを終了します。

 1: clean

指定した項目が削除されます。もしこの時点で 1: clean を実行したら、untracked_dir/ untracked_file が削除されます。

 4: ask each

追跡対象外の各ファイルで処理を繰り返して、削除するかを確認する Y/N ファイルごとに表示されます。実際に実行すると次のようになります。

 *** Commands *** 1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit 6: help What now> 4 Remove untracked_dir/ [y/N]? N Remove untracked_file [y/N]? N
 2: filter by pattern

追跡対象外ファイルのリストのフィルタリングに使う入力を取る別のプロンプトが表示されます。

 Would remove the following items: untracked_dir/ untracked_file *** Commands *** 1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit 6: help What now> 2 untracked_dir/ untracked_file Input ignore patterns>> *_file untracked_dir/

ここでは *_file のワイルドカードパターンを入力として指定したため、追跡対象外ファイルのリストは untracked_dir だけに制限されます。

 3: select by numbers

コマンド 2 同様、コマンド 3 も追跡対象外のファイル名のリストを見やすくしてくれます。インタラクティブセッションでは追跡対象外ファイル名に対応する数字が表示されます。

 Would remove the following items: untracked_dir/ untracked_file *** Commands *** 1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit 6: help What now> 3 1: untracked_dir/ 2: untracked_file Select items to delete>> 2 1: untracked_dir/ * 2: untracked_file Select items to delete>> Would remove the following item: untracked_file *** Commands *** 1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit 6: help

要約

git clean はリポジトリの作業ディレクトリの追跡対象外ファイルの削除に便利な方法です。追跡対象外ファイルとはリポジトリのディレクトリにあるものの、git add を実行してリポジトリのインデックスにまだ追加されていないファイルのことです。全体的に見ると、git clean の代わりに git status とオペレーティングシステムに元々ある削除ツールを使っても同じ結果が得られます。git cleangit reset と一緒に使ってリポジトリのあらゆる追加とコミットを元に戻すことができます。