25.

.gitignoreの書き方|パターン記法と追跡済みファイルの除外

編集

.gitignoreは、Gitの管理対象から除外したいファイルやディレクトリを1行1パターンで書き並べる設定ファイルです。プロジェクトのルートに置いた.gitignoreへ無視したいパターンを記述すれば、ログやビルド成果物、環境変数ファイルなどがコミットに紛れ込むのを防げます。本記事では、パターンの記法から具体例、そして「すでに追跡済みのファイルには効かない」という最大の落とし穴とその外し方までを解説します。

この記事の要点
  • .gitignoreはGitの管理対象外にするファイルを指定するテキストファイルで、ルートに置くのが基本です。
  • 書き方は1行1パターン。先頭が#の行はコメントとして無視されます。
  • *.logは拡張子、dir/はディレクトリ、/fileはルート限定、**/は再帰、!は除外解除を表します。
  • すでにGitが追跡しているファイルには.gitignoreは効きません。git rm --cachedで追跡を外す必要があります。
  • OSやエディタ固有のファイルは、ユーザー単位のグローバルgitignoreにまとめると便利です。

.gitignoreとは

.gitignoreは、Gitに「このファイルやディレクトリはバージョン管理しなくてよい」と伝えるための設定ファイルです。Gitはこのファイルに書かれたパターンと一致するファイルを、変更検知(git status)やステージング(git add)の対象から外します。これにより、リポジトリには本当に管理したいソースコードや設定だけが残り、ノイズの少ないクリーンな履歴を保てます。

無視する対象として代表的なのは、次のようなファイルです。

  • ビルドやインストールで自動生成されるもの(node_modules/dist/*.class など)
  • パスワードやAPIキーを含む環境設定ファイル(.env など)
  • OSやエディタが勝手に作る一時ファイル(.DS_StoreThumbs.db*.swp など)
  • ログやキャッシュなど、再生成可能で履歴に残す必要のないもの

.gitignoreは通常、プロジェクトのルートディレクトリに1つ置きます。サブディレクトリにも個別の.gitignoreを置くことができ、その場合はそのディレクトリ配下に対して追加のルールが適用されます。

基本の書き方

.gitignoreの記述はシンプルで、1行につき1つのパターンを書くのが原則です。覚えておきたいルールは次の3点です。

  • 1行1パターン:ファイル名・ディレクトリ名・ワイルドカードを使ったパターンを1行ずつ書きます。
  • コメントは#:行頭が # の行はコメントとして扱われ、無視されます。セクションの見出しやメモに使います。
  • 空行は無視:空行は単なる区切りとして扱われるため、グループ分けに使えます。

たとえば、次のように書きます。

# ログとキャッシュは管理しない
*.log
.cache/

# 環境変数ファイル
.env

パターンは、書かれた.gitignoreが置かれているディレクトリを基準に解釈されます。スラッシュ / の位置によって意味が変わるため、次の表で代表的な記法を整理します。

パターン記法の一覧

記法意味マッチするもの
*.拡張子その拡張子を持つファイルすべて(全階層)*.logapp.loglogs/debug.log など
名前/末尾スラッシュでディレクトリのみを無視build/どの階層にある build ディレクトリも
/名前先頭スラッシュで.gitignoreと同じ階層(ルート)限定/config.jsonルート直下の config.json のみ
**/任意の階層(再帰的)にマッチ**/temp/どこにあっても temp ディレクトリ
?任意の1文字file?.txtfile1.txtfileA.txt など
!パターン否定。直前までの無視ルールを解除し、再び追跡対象にする!important.log無視対象から important.log を除外

補足として、* はスラッシュ以外の任意の文字列にマッチします。たとえば *.log はすべての階層の .log ファイルにマッチしますが、logs/*.log と書けば logs ディレクトリ直下の .log ファイルだけに限定できます。再帰的に下の階層まで含めたい場合は logs/**/*.log のように ** を使います。

具体例:よく書くパターン

実際のプロジェクトでは、次のようなパターンを書くことが多くなります。Node.jsのプロジェクトを例に挙げます。

# 依存パッケージ(再インストール可能なので管理しない)
node_modules/

# 環境変数(秘密情報を含むため)
.env
.env.local
*.env

# ビルド成果物
dist/
build/
*.log

# OS・エディタが生成するファイル
.DS_Store
Thumbs.db
.vscode/
.idea/

ポイントは、「再生成できるもの」「秘密情報を含むもの」「個人の作業環境に依存するもの」を無視対象にする、という考え方です。node_modules/ はパッケージ管理ツールでいつでも再インストールできますし、.env はパスワードやキーを含むため、誤って公開リポジトリに上げると重大な情報漏えいにつながります。

否定(!)を組み合わせると、「フォルダ全体は無視しつつ、特定のファイルだけは残す」という指定もできます。

# logs配下はすべて無視するが、サンプルだけは残す
logs/
!logs/sample.log

ただし否定には順序とディレクトリの注意点があり、後述の「落とし穴」で詳しく説明します。

すでに追跡済みのファイルには効かない

.gitignoreで最もつまずきやすいのが、すでにGitが追跡(commit済み、またはステージ済み)しているファイルには.gitignoreが効かないという点です。.gitignoreは「これから新しく追加されるファイル」を無視対象にするための仕組みであり、一度追跡されたファイルは.gitignoreにパターンを書いても無視されません。

たとえば、先に config.json をコミットしてしまった後で .gitignoreconfig.json を追記しても、そのファイルは引き続き git status に変更として表示され続けます。

git rm --cached で追跡を外す

すでに追跡済みのファイルを無視させるには、Gitの追跡(インデックス)から外す必要があります。ファイル自体は手元に残したまま、Gitの管理対象からだけ外すには git rm --cached を使います。

# 1ファイルを追跡から外す(ファイル自体は削除されない)
git rm --cached config.json

# ディレクトリごと外す場合は -r を付ける
git rm -r --cached node_modules/

# 変更をコミット
git commit -m "Stop tracking ignored files"

--cached を付けると、作業ディレクトリのファイルは残したまま、Gitのインデックスからのみ削除されます(--cached を付けないと実ファイルも削除されるので注意してください)。この操作の後は.gitignoreのパターンが有効になり、以降そのファイルは無視されます。なお、過去のコミット履歴にはファイルが残るため、秘密情報を誤ってコミットしてしまった場合は履歴自体の書き換えや、漏れた認証情報の無効化が別途必要です。

グローバルgitignoreの設定

.DS_Store やエディタの設定フォルダ(.idea/ など)のように、どのプロジェクトでも共通して無視したいファイルは、プロジェクトごとの.gitignoreに毎回書くのではなく、ユーザー単位のグローバルgitignoreにまとめると管理が楽になります。

# グローバル用のファイルを登録
git config --global core.excludesfile ~/.gitignore_global

# 登録したファイルに共通の無視パターンを書く
# 例: ~/.gitignore_global の中身
# .DS_Store
# Thumbs.db
# *.swp

こうしておくと、OSやエディタが生成する個人的なファイルを各プロジェクトの.gitignoreに含めずに済みます。プロジェクトの.gitignoreは「そのプロジェクト固有のもの」だけに保てるため、チームで共有する際にも見通しが良くなります。

落とし穴

注意点内容
追跡済みには効かない最大の落とし穴です。すでにコミット・ステージされたファイルは.gitignoreでは無視されません。git rm --cached で追跡を外してから無視させます。
否定の順序!による除外解除は、その前にある無視ルールを打ち消す形で働きます。否定パターンより後で同じファイルが再び無視されると、否定は無効になります。順序に注意しましょう。
否定とディレクトリ親ディレクトリ自体がdir/で無視されていると、その中のファイルを!dir/keep.txtで残そうとしても効きません。ディレクトリの無視を解除しない限り、中のファイルは復活しません。
末尾スラッシュの有無build/はディレクトリのみにマッチしますが、buildは同名のファイルにもマッチします。ディレクトリだけを狙うなら末尾に/を付けます。
先頭スラッシュの意味/configはルート直下のみ、configは全階層にマッチします。意図せず深い階層の同名ファイルまで無視しないよう、必要に応じて先頭/で範囲を限定します。

よくある質問(FAQ)

Q1. .gitignoreが効いているか確認する方法はありますか?

あります。git check-ignore -v ファイル名 を実行すると、そのファイルがどの.gitignoreのどの行によって無視されているかが表示されます。何も出力されなければ、そのファイルは無視対象になっていないということです。意図したパターンが効いているかの確認に便利です。

Q2. 空のディレクトリをGitで管理したいのですが、無視されてしまいます。

Gitは空のディレクトリ自体を追跡しません。ディレクトリ構造だけ残したい場合は、慣例として中に .gitkeep という空ファイルを置きます。なお.gitkeepはGitの公式機能ではなく、あくまで「空ファイルを置いてディレクトリを存在させる」ための慣習的な名前です。

Q3. .gitignore自体はコミットすべきですか?

はい、プロジェクトの.gitignoreはコミットして共有するのが基本です。チーム全員が同じ無視ルールを使えるようになり、不要なファイルの混入を全体で防げます。一方、個人の環境にだけ依存するルールは、前述のグローバルgitignoreや、リポジトリに含めない .git/info/exclude に書くとよいでしょう。

まとめ

.gitignoreは、Gitの管理対象から不要なファイルを除外し、リポジトリをクリーンに保つための基本ツールです。書き方は1行1パターンとシンプルですが、/の位置や末尾スラッシュ、!による否定など、パターン記法には意味の違いがあります。そして何より重要なのは、すでに追跡済みのファイルには.gitignoreが効かないという点です。その場合は git rm --cached で追跡を外してから無視させましょう。共通ルールはグローバルgitignoreにまとめ、プロジェクト固有のルールはコミットして共有することで、チーム全体で快適なバージョン管理を実現できます。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 用語一覧
  2. エラー一覧
  3. git本体のインストール(Linux)
  4. Linuxサーバーへのgit導入とクライアントのセットアップ
  5. リモートリポジトリをローカルリポジトリとしてクローンする方法
  6. リモートとローカルのリポジトリを同期(pull)する方法
  7. 設定の確認
  8. gitユーザー名とemailの設定
  9. リモートリポジトリの作成
  10. ローカルリポジトリの作成
  11. 新規ファイル/ディレクトリをインデックスに登録
  12. インデックスの登録状態を確認
  13. ローカルリポジトリの変更をコミット
  14. コミット履歴の確認
  15. クライアントからリモートリポジトリの接続設定、確認、削除
  16. リポジトリへのプッシュ
  17. リモートリポジトリからクライアントへのSSHクローン
  18. リモートとローカルの差分表示
  19. バージョンの確認
  20. プロキシの設定
  21. ローカルをリモートリポジトリの状態に戻す
  22. ブランチの作成, 一覧表示, 切り替え
  23. ブランチのマージと削除
  24. リベース
  25. .gitignoreの書き方
  26. .gitignoreの設定が反映されない場合
  27. 特定のファイルをgitの管理から外す方法
  28. 参照(ORIG_HEAD, HEAD, FETCH_HEAD)
  29. git rm [-r --cached] の取り消し
  30. 一部のディレクトリ/ファイルのみをリポジトリから復元する方法
  31. ローカルとリモートリポジトリの有無を同期
  32. pushの取消し方法
  33. マージツールの起動方法
  34. Gitで「MERGING」の状態

最近更新/作成されたページ