リポジトリに node_modules が入ってしまった、ビルド成果物のせいで差分が読めない、うっかり設定ファイルをコミットしてしまった——これらは .gitignore の設計で防げるトラブルです。ところが .gitignore は「書いたのに効かない」ことがあり、パターンの書き方にも独特のルールがあるため、なんとなく使っていると事故につながります。この記事では、Gitで除外するファイルを設計する手順を、除外対象の整理からパターンの理解、動作確認、追跡済みファイルの解除まで順番に紹介します。
1. 何を除外すべきかを整理する
まず、リポジトリに入れるべきでないものを整理します。判断基準はシンプルで、「再生成できるもの」「環境ごとに異なるもの」「秘密の情報」の3つです。再生成できるものは、node_modules や vendor などの依存パッケージ、dist や build などのビルド成果物、キャッシュファイルです。これらはコマンド一つで復元できるため、リポジトリを重くするだけでなく、差分レビューの邪魔になります。環境ごとに異なるものは、エディタの設定ファイル(.vscode、.idea)やOSが作るファイル(.DS_Store、Thumbs.db)です。そして秘密の情報が .env などの環境変数ファイルで、これは最も事故が重いカテゴリです。逆に、package-lock.json や yarn.lock のようなロックファイルは、環境を再現するために必要なのでコミットします。
2. 言語・フレームワークに応じた雛形を用意する
除外すべきものは、使う言語やフレームワークによって決まっている部分が大きいため、ゼロから書く必要はありません。.gitignore Generator で使用中の環境を選ぶと、その定番の除外設定をまとめて生成できます。Node.js なら node_modules や各種ログ、Python なら __pycache__ や仮想環境、macOS なら .DS_Store といった具合に、忘れがちなものも含めて網羅されます。複数を組み合わせて生成できるので、たとえば「Node.js + Next.js + macOS + VSCode」のように、自分の環境に合わせた設定を一度に作れます。生成された内容には目を通し、プロジェクト固有の除外(生成される中間ファイル、ローカル用のスクリプトなど)を追記しておくと万全です。まずは雛形から始めて、必要に応じて足していくのが効率的です。
この手順で使うツール
.gitignore Generator
言語・フレームワーク別テンプレートを組み合わせて .gitignore を即生成
3. パターンの書き方を理解する
.gitignore のパターンには、知っておくべきルールがいくつかあります。まず、スラッシュを含まないパターン(例:`*.log`)は、どの階層のファイルにもマッチします。一方、先頭にスラッシュを付ける(例:`/build`)と、リポジトリのルート直下だけを指します。末尾にスラッシュを付ける(例:`temp/`)と、ディレクトリだけにマッチします。アスタリスク1つは階層を越えませんが、2つ重ねると階層を越えてマッチします(例:docs 以下すべてのPDFを対象にする書き方)。そして重要なのが否定パターンで、`!` を付けると除外を打ち消せます。ただし、親ディレクトリ自体が除外されている場合、その中のファイルを `!` で復活させることはできません。この挙動は分かりにくく、「除外したディレクトリの中の1ファイルだけ含めたい」というときにハマる典型です。その場合は、ディレクトリ自体は除外せず、中身をワイルドカードで除外してから例外を指定します。
4. パターンが意図通りか確認する
書いたパターンが本当に狙ったファイルにマッチするかは、頭の中だけで判断せず確認するのが安全です。Glob Pattern Tester にパターンとファイルパスを入力すると、どれがマッチするかをその場で検証できます。特に、アスタリスクを2つ重ねた階層をまたぐ指定や、否定を組み合わせた設定は、思い込みとずれやすいので確認する価値があります。Git自体で確認する方法もあり、`git check-ignore -v <ファイルパス>` を実行すると、そのファイルがどの行のルールで除外されているかが分かります。「なぜかコミットされない」ファイルがあるときは、このコマンドで原因の行を特定できます。逆に「除外したいのに追跡されてしまう」場合は、次の手順の問題であることがほとんどです。
この手順で使うツール
Glob Pattern Tester
glob パターンのマッチングをリアルタイムで確認
5. 「書いたのに無視されない」を解決する
最もよくある混乱が、「.gitignore に追加したのに、そのファイルが差分に出続ける」というものです。原因はシンプルで、.gitignore は「まだGitが追跡していないファイル」にしか効かないからです。一度でもコミットされたファイルは、その後 .gitignore に書いても追跡され続けます。解決するには `git rm --cached <ファイル>` で追跡だけを解除します(`--cached` を付ければ手元のファイルは消えません)。ディレクトリごとなら `-r` を付けます。注意点として、この操作をコミットすると、他の人の環境ではそのファイルが削除されます。共有ファイルの場合は事前にチームへ周知してください。また、秘密情報を誤ってコミットしていた場合は、追跡解除だけでは履歴に残るため、まず該当のキーを失効・再発行することが最優先です。履歴の掃除はその後で構いません。
まとめ
.gitignore の設計は「除外すべきものを整理する → 雛形を使う → パターンの規則を理解する → 動作を確認する → 追跡済みファイルは rm --cached で解除する」という流れで進めれば、事故を減らせます。特に「.gitignoreは追跡済みファイルには効かない」「除外したディレクトリ内は ! で復活できない」の2点は、知らないと必ずハマるポイントなので覚えておく価値があります。