はじめに
Gitでプロジェクトなどの管理を行うとき、対象外にしたいファイルやディレクトリは.gitignoreに記載するかと思います。
ただ(一度コミットした等で)すでにGitでの管理対象になっているファイルは、その後.gitignoreに記載されても管理の対象から外れません。そのため「.gitignoreに書かれているけどGitで管理されている」という状況が起こり得ます。
これを解消する方法を書き残しておきます。
環境
この記事を書いている時の動作環境は下記の通りです
macOS Sonoma 14.6
git version 2.48.1
コマンド
もったいぶらずに書くと、↓のコマンドでほぼ終わります。
コマンドの意味は後で解説します。
git ls-files -ci --exclude-standard | xargs git rm --cached
いきなり管理対象から外すのがためらわれる場合、↓の通り前半だけ実行すれば対象外になるファイルの一覧が確認できます。
git ls-files -ci --exclude-standard
「ほぼ終わる」と書いたのは、上記のコマンドを実行しただけだと管理対象から外した状態がコミットされていないためです。
git statusを実行して状態を確認すると、deleted:と付いた状態で、対象外になったファイルたちが表示されるはずです。
deletedと見るとファイルそのものが消えたようで驚くかもしれませんが、ファイル自体は消えていません。心配ならlsなどのコマンドで確認してみてください。
問題なければ、その状態でコミットすれば完了です。
git ls-files
git ls-filesは、ざっくり言うとgitの管理対象となっているファイルを表示するコマンドです。各種オプションを使った絞り込みなどもできます。
-cオプション
-cオプションは--cachedを短縮したものです。
Gitにキャッシュされているファイル、つまりすべての追跡済みファイル(管理対象ファイル)を表示します。
-iオプション
-iオプションは--ignoredを短縮したものです。
無視されるファイルのみを表示するもので、-cまたは-oと組み合わせて使う必要があります。
今回の-cとの組み合わせでは、「無視されるパターンに合致しているが、管理対象になっているファイル」を出力します。
ここでいう「無視されるパターン」については自分で指定する必要があります。「標準の設定がデフォルトで反映される」という仕様ではありません。そのため、何かしら除外に関するオプションを指定する必要があります。これについては次で触れます。
--exclude-standardオプション
-iオプションで触れた「除外に関するオプション」の1つが--exclude-standardオプションです。
Gitが標準で参照する除外ルール(つまり、リポジトリ内の.gitignoreファイルなど)での除外設定を使いたい場合、このオプションを指定します。
この他にも任意の除外ルールを追加することもできますが、今回は.gitignoreを使いたいので--exclude-standardだけで問題ありません。
git ls-filesやそのオプションについて、より詳しくはこちらのページを確認してください。
Git - git-ls-files Documentation
https://git-scm.com/docs/git-ls-files
パイプ( | ) と xargs
2つのgitコマンドを繋いでいるパイプ(|)とxargsについても説明しておきます。
ちなみにこれらは別にgit用のコマンドではなく汎用的なものです。
パイプ(|)は前のコマンド(今回だとgit ls-files -ci --exclude-standard)の出力を、次のコマンドの入力として渡します。
xargsコマンドは、入力を1行ずつ、後に続くコマンド(今回だとgit rm --cached)の引数として渡します。
つまり、次のコマンドで行われる「Git管理からの除外」を、git ls-filesでリストアップした各ファイルに対して適用している、ということです。
git rm
git rmはGitで管理しているファイルを削除するためのコマンドです。
通常は↓のように引数で削除対象のファイルを渡しますが、今回のコマンドでは|とxargsで引数が渡されてくるので不要です。
git rm fileA
ここで注意すべきが、このコマンドはファイル自体を削除するということです。
そこで必要になるのが次のオプションです。
--cachedオプション
Gitにキャッシュされたファイルのみを削除し、ファイルそのものは削除しない時に使うコマンドです。
つまりGitでの管理から外すだけで、ファイル自体には何も変化を及ぼしません。
git rmやそのオプションについて、より詳しくはこちらのページを確認してください。
Git - git-rm Documentation
https://git-scm.com/docs/git-rm