このセクションでは、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 <file>..." to unstage)

new file: tracked_file

Untracked files: (use "git add <file>..." to include in what will be committed) untracked_dir/ untracked_file

このサンプルでは、git_clean_test ディレクトリに新しい Git リポジトリを作成しています。その後、Git インデックスに追加される tracked_fileuntracked_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 <path>
-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

これは非常にシンプルであり、インタラクティブ セッションを終了します。

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 と併用して、リポジトリのあらゆる追加とコミットを元に戻せます。