やりたかったこと

git status を実行したら node_modules/ 以下のファイルが何千件も表示されて真っ赤になった。git add . するたびに重くなるし、pushしたらリポジトリが数百MBになってしまった。.gitignore で管理対象から外す方法を調べた。


環境

  • OS: macOS 13.5 / Ubuntu 22.04
  • Git: 2.42.0
  • Node.js: 20.11.0

試したこと・うまくいかなかったこと

.gitignore を新しく作って node_modules/ と書いた。git status を確認したら、まだ node_modules の中身が表示されていた。

原因はすでに一度 git add していたからだった。.gitignore はgitのトラッキングに入っていないファイルを無視するものであって、すでにトラッキング済みのファイルには効かない。

次に、トラッキングを外せばいいと思って git rm -r node_modules/ を実行したら、ローカルのファイルまで消えてしまった。node_modules を削除してから npm install し直すハメになった。


解決策

.gitignoreファイルを作る

プロジェクトのルート(.git と同じ階層)に .gitignore を作る。

node_modules/
dist/
.env
.env.local
.astro/
*.log
.DS_Store

すでにトラッキング済みのファイルを管理から外す

.gitignore を追加しただけでは既存のトラッキングには効かない。git rm --cached でgitのインデックスからだけ削除する(ローカルのファイルは残る)。

# 特定のファイルをトラッキングから外す
git rm --cached .env

# ディレクトリごと外す
git rm -r --cached node_modules/

# インデックスへの変更をコミットする
git add .
git commit -m "remove node_modules and .env from tracking"

--cached を付けると、ローカルのファイルはそのままでgitの管理からだけ外れる。

テンプレートを使って生成する

https://www.toptal.com/developers/gitignore でOS・エディタ・言語を選ぶと自動生成できる。Node.js + macOS + VSCodeの組み合わせで生成したものをベースにして、プロジェクト固有のパスを追加するのが早かった。

特定のパターンだけ除外する書き方

# *.log は無視するが error.log は無視しない
*.log
!error.log

# ルート直下のTODO.txtのみ無視(サブディレクトリのは無視しない)
/TODO.txt

# buildディレクトリ以下を全て無視
build/

ハマったポイント

  • .gitignore は「まだgitに追加されていないファイル」だけに効く。すでにコミット済みのファイルは git rm --cached で明示的に外さないといけなかった。これを知らずに「なぜ効かないんだ」と30分悩んだ
  • git rm -r node_modules/git rm -r --cached node_modules/ は全然違う。--cached なしでやるとローカルのファイルが消える
  • .env をコミットしてしまってGitHubにpushしたことがある。「削除してpushし直せばOK」ではなく、git historyに残るのでAPIキーやパスワードは必ず変更する
  • .gitignore の書き方はパターンに注意。node_modules と書くとルート以外のサブディレクトリの node_modules も無視される。/node_modules と書くとルート直下のみ。どちらでも大体の用途には問題ないが、モノレポ構成のときは注意が必要だった
  • git status で除外されているはずのファイルが出てきたら git check-ignore -v ファイルパス.gitignore のどのルールが当たっているか(または当たっていないか)確認できる

関連記事

おすすめのVPS