.gitignoreが効かない時にgitで追跡を外す方法

公開日:
目次

gitを使っていて、すでにコミット済みのファイルを「追跡から外す」方法を忘れがちなので、手順をまとめておきます。

TL;DR

  • ローカルのファイルは残したまま追跡だけ外す → git rm --cached <ファイル>
  • ディレクトリごとなら git rm -r --cached <ディレクトリ>
  • .gitignore に書き足すのは「これから無視する」設定で、すでに追跡済みのファイルには効かない

.gitignoreに足したのに消えない理由

.gitignore が効くのは未追跡(untracked)のファイルだけです。一度 git add / commit したファイルは追跡済み(tracked)の状態になっていて、.gitignore はもう手を出しません。

門番に例えると、.gitignore は「これから入ってくる人」を止める門番で、すでに部屋の中にいる人は管轄外、という立ち位置です。だからレビューで指摘される「もう commit してしまったファイル」は、門番を増やしても出ていきません。

別途「外に出す」操作が必要で、それが git rm --cached です。

gitで追跡を外す手順

例として、今回はビルド生成物の dist/ と環境変数を入れた .env をコミットしてしまったとします。

まず .gitignore に対象を書きます。

.gitignore
+ dist/
+ .env

次に追跡を外します。--cached を付けると、インデックス(追跡対象の一覧)からは外れますが、作業ツリーのファイルはそのまま残ります。

git rm -r --cached dist .env

あとは .gitignore と一緒にコミットします。

git add .gitignore
git commit -m "stop tracking dist and .env"

効いているか確認するなら、追跡一覧と無視状態をそれぞれ見ます。

git ls-files | grep dist   # 何も出なければ追跡から外れている
git check-ignore -v .env   # .gitignore のどの行で無視されたか表示される

--cachedを付け忘れると手元から消える

ここが一番引っかかるところですが、--cached を付けない素の git rm は、追跡を外すと同時に作業ツリーからもファイルを物理削除します。設定ファイルやまだ使うソースでこれをやると、手元から本当に消えます。

たとえば環境変数を入れた .envgit rm .env--cached なし)で外すと、追跡が外れるのと同時に .env 自体が消えてローカルの環境が動かなくなります。追跡だけ外したいときは必ず --cached を付けましょう。

自分はこの4コマンドをスニペットにして、誤って追加してしまった際にコピペしています。毎回コマンドを思い出そうとして手を止めるくらいなら、貼って終わらせた方が早いです。