メインコンテンツへスキップ
ブログ一覧に戻る
Web制作・運用

.gitignoreに書いたのに無視されない|適用範囲・優先順位と原因を特定する手順

2026年10月30日
18分で読めます

この記事でわかること

.gitignoreに書いたファイルがgit statusに出続ける原因は、追跡済みであること以外にもあります。Git公式が定める4段階の優先順位と「同じ段では最後に一致したパターンが決める」規則、追跡をやめる手順が作業ツリーをどう扱うか、診断コマンドの既定動作を確認日つきで整理します。

.gitignore に書いた。それでも git status に出てくる。

ここで最初に当たるのは「すでに追跡しているファイルには効かない」という説明です。これは公式ドキュメントに明記されている事実で、当サイトでもAPIキーの管理とリポジトリとは何かで、出典を引いて書いてきました。

ただ、この説明で解決しない場合があります。追跡した覚えがないのに出てくる。追跡をやめたはずなのに戻ってくる。別の人の手元では無視されているのに自分の手元では無視されない。こうした状況は「追跡済みだから」では説明が付きません。 原因が別のところにあるからです。

この記事では、Git 公式が定める無視の判定の適用範囲と優先順位、そして原因を特定するための診断コマンドの既定動作を扱います。扱わないのは、履歴からファイルを除去する手順(参照した文書に記述がありません)と、パターン記法の網羅的な解説です。秘密情報を誤ってコミットした場合の対応はAPIキーの管理に書いています。

参照したのは gitignore、git rm、git check-ignore、git add の4件で、いずれも2026年10月29日に取得しました。以下の引用はすべてドキュメントの記述であり、本記事でコマンドを実行した結果ではありません。

30秒で要点

  • 無視の判定は4つの情報源から読まれ、優先順位が定められている。.gitignore に書いたパターンは、そのうちの1つにすぎない
  • 同じ優先順位の段の中では、最後に一致したパターンが結果を決める。前の行に書いたパターンは、後ろの行に上書きされる
  • 追跡をやめる手順は「インデックスから外す → .gitignore に加える」の順である。--cached を付けた場合、作業ツリーのファイルは変更の有無にかかわらず残る。付けない既定の動作は作業ツリーからも削除する
  • git check-ignore は、既定で追跡済みファイルを一切表示しない。理由は「追跡済みファイルは除外規則の対象ではない」ためである
  • したがって「出力が何も無い」には2つの意味がある。追跡済みなのか、どのパターンにも一致しないのか、出力からは区別できない
  • git add は、無視ファイルを正確なファイル名で指定したときは失敗して一覧を出すが、そうでなければ黙って無視する

公式が定める適用範囲は、意外と狭い

最初に、ドキュメントが何を目的として宣言しているかを確認します。gitignore のドキュメントは、DESCRIPTION で適用範囲を限定しています。

Files already tracked by Git are not affected; see the NOTES below for details.

そして NOTES で目的を定義します。

The purpose of gitignore files is to ensure that certain files not tracked by Git remain untracked.

「追跡されていないファイルを、追跡されないまま保つ」。これが宣言されている目的です。追跡をやめさせる機能ではありません。だから追跡をやめる手順は別に書かれています。

To stop tracking a file that is currently tracked, use git rm --cached to remove the file from the index. The filename can then be added to the .gitignore file to stop the file from being reintroduced in later commits.

順序に注目してください。.gitignore への追記は、インデックスから外したあとに「後で再び取り込まれないようにするため」の後続手順として書かれています。原文も "can then be added" です。.gitignore を書いただけでは、1つ目の手順が済んでいません。

ここまでが既知の部分です。以下が、この記事の本体にあたります。

無視の判定は、4つの情報源から読まれる

.gitignore に正しく書いたのに効かない。追跡済みでもない。この状態の原因は、パターンが別の場所にも書かれていることです。

gitignore のドキュメントは、無視するかどうかを判定するとき、Git が複数の情報源からパターンを読むと規定し、優先順位の高い順に4つを挙げています。

  1. コマンドラインで渡されたパターン
  2. 対象パスと同じ階層、またはその親階層の .gitignore
  3. $GIT_COMMON_DIR/info/exclude
  4. 設定変数 core.excludesFile が指すファイル

When deciding whether to ignore a path, Git normally checks gitignore patterns from multiple sources, with the following order of precedence, from highest to lowest

2番目には補足があります。上位階層のファイルのパターンは、対象ファイルを含むディレクトリまで下っていく過程で、下位階層のファイルのパターンに上書きされる。そしてパターンは、その .gitignore が置かれた位置を基準に照合される。

この一覧が示しているのは、自分が書いた .gitignore の外側に、3種類の別の置き場所があるということです。3番目と4番目は、リポジトリの中に見えません。info/exclude はリポジトリの管理領域にあり、core.excludesFile は設定が指す別のファイルです。だから「別の人の手元では無視されているのに自分の手元では違う」という状況が起きえます。設定が人ごとに違うからです。

なお core.excludesFile の既定値は、ドキュメントでは環境変数の有無による条件付きで書かれています。条件を落として1つのパスを「既定」と覚えないほうがよく、実際に何が設定されているかは、使っている環境で確認する対象です。

同じ段の中では、最後に一致したパターンが決める

4つの情報源のあいだの優先順位とは別に、同じ段の中の規則があります。条文は括弧の中に置かれています。

(within one level of precedence, the last matching pattern decides the outcome)

最初に一致したパターンではなく、最後に一致したパターンが結果を決める。 .gitignore を長く育てていくと、この規則が効いてきます。上の方に書いた除外が、下の方に書いた否定パターンで打ち消されることがあります。追加した本人は上の行を見ていて、効かない理由が分かりません。

「最後」がファイル内の行順を指すと読めますが、ドキュメントはこれ以上の定義を与えていません。行番号で説明するには、どの行が効いたかを表示する手段が必要になります。それが次節の診断コマンドです。

追跡をやめる手順は、作業ツリーのファイルを消さない

ここで、1つ目の手順に戻ります。git rm --cached が何をするのか。

git rm のドキュメントは、OPTIONS でこう書いています。

Use this option to unstage and remove paths only from the index. Working tree files, whether modified or not, will be left alone.

インデックスからのみ外し、作業ツリーのファイルは変更の有無にかかわらずそのまま残る。 設定ファイルや環境ファイルを追跡から外したいとき、手元のファイルは消えません。

ただし、--cached を付けない既定の動作は違います。DESCRIPTION は、git rm がインデックスから、または作業ツリーとインデックスの両方からパスを削除すると書いています。

Remove files matching pathspec from the index, or from the working tree and the index. git rm will not remove a file from just your working directory.

この2つを混ぜて覚えると、手元のファイルを消すことになります。 「追跡をやめたい」という意図に対して、オプションを1つ落とすだけで「ファイルを消す」が実行されます。作業ツリーから消えたファイルは、コミットされていない変更を含んでいれば戻せません。コピーを取ってから実行する手順にしておくのが妥当です。

なお --cached を指定する場合の条件も書かれています。ステージされている内容が、ブランチの先端かディスク上のファイルのいずれかと一致していることが必要です。

git check-ignore は、既定で追跡済みファイルを表示しない

原因を特定する道具として用意されているのが git check-ignore です。ドキュメントは、与えられたパス名について .gitignore(または除外機構への他の入力ファイル)によって除外されているかを調べ、除外されていればそのパスを出力すると説明します。

そして既定動作に、この記事の主題と同じ線が引かれています。

By default, tracked files are not shown at all since they are not subject to exclude rules; but see '--no-index'.

既定では追跡済みファイルを一切表示しない。理由は「追跡済みファイルは除外規則の対象ではない」ため。 道具の既定動作が、gitignore の適用範囲そのものから導かれています。

言い換えると、調べたいパスが追跡済みなら、このコマンドは黙ります。「出てこないから無視されていないのだろう」と読むと、原因から遠ざかります。

インデックスを見ずに判定するオプションも用意されています。

Don't look in the index when undertaking the checks. This can be used to debug why a path became tracked by e.g. git add . and was not ignored by the rules as expected by the user

このオプション(--no-index)は、git add . でパスが追跡されてしまった理由を調べるために用意されていると明記されています。目的がドキュメントに書かれているオプションなので、迷ったときに使う対象として覚えておけます。

どのパターンが効いたかを見るには -v を付けます。ドキュメントは、除外パターンに一致した各パスについて、パターンとパスを一緒に出力すると書き、形式を <source> <COLON> <linenum> <COLON> <pattern> <HT> <pathname> と規定しています。情報源と行番号が出るので、前節の「最後に一致したパターン」がどれだったかを突き合わせられます。

ただし1点、読み替えが必要です。

Matching an exclude pattern usually means the path is excluded, but if the pattern begins with "!" then it is a negated pattern and matching it means the path is NOT excluded.

一致は、必ずしも除外を意味しません。感嘆符で始まる否定パターンに一致した場合、そのパスは除外されない側になります。「一致した=無視される」と読まないでください。

「何も出力されない」には、2つの意味がある

出力の読み方を整理します。ドキュメントは OUTPUT で、既定では無視パターンに一致したパス名が1行ずつ出力されると書き、続けてこう規定しています。

If no pattern matches a given path, nothing will be output for that path; this means that path will not be ignored.

つまり「何も出力されない」が指しうる状態は2つあります。

  • 追跡済みである(既定では表示されない。前節の規定)
  • どのパターンにも一致しない(無視されない、という意味になる)

出力が空であることだけでは、この2つを区別できません。 区別するには、インデックスを見ない判定(--no-index)と通常の判定を比べる、という手順が必要になります。一致しなかったパスを表示する別のオプション -n(--non-matching)もありますが、ドキュメントは「これは --verbose が有効なときにのみ意味を持つ」と書いています。

診断の出力を読むときに起きやすい誤りは、沈黙を情報として読んでしまうことです。この道具の沈黙は、2つの状態に重なっています。

git add は、正確なファイル名のときだけ失敗する

もう1つ、追跡済みになる経路に関わる規定があります。git add のドキュメントです。

The git add command will not add ignored files by default. You can use the --force option to add ignored files. If you specify the exact filename of an ignored file, git add will fail with a list of ignored files. Otherwise it will silently ignore the file.

3つの挙動が1つの段落に収まっています。

  1. 既定では、無視ファイルを追加しない
  2. --force(-f)を付けると追加できる
  3. 無視ファイルを正確なファイル名で指定した場合は失敗して無視ファイルの一覧を出すが、そうでなければ黙って無視する

3番目の非対称が効いています。git add path/to/secret.env と書けば止められます。git add . と書けば、何も言われません。同じ無視ファイルに対する操作なのに、指定の仕方で警告の有無が変わります。

これは、「.gitignore に書いたファイルが追跡済みになっている」経路の1つとして挙げられます。ただし、目の前のファイルがその経路で追跡されたと断定するには、履歴を読む必要があります。一般論として経路が存在する、というところまでが言える範囲です。

なぜ「書いたのに効かない」が繰り返されるのか

4つの規定を並べてみると、共通する性質が見えます。どれも「書いた側から見えない場所」に関わっています。

優先順位の3番目と4番目は、リポジトリの中を見渡しても出てきません。info/exclude は管理領域の中にあり、core.excludesFile は設定を読まないと分かりません。最後に一致したパターンという規則は、ファイルを上から読んでいる限り意識されません。そして診断コマンドは、追跡済みのパスについて既定で黙ります。

そのうえで、.gitignore は成功体験が積み重なるファイルです。新しいプロジェクトで node_modules と書けば効く。.env と書けば効く。何十回も効いた経験のあとに「効かない」が来たとき、最初に疑うのは書き方です。パターンのスペルを直し、スラッシュの位置を変え、アスタリスクを増やす。しかし原因が適用範囲や別の情報源にあるなら、どう書き直しても変わりません。

成功体験で裏打ちされた道具は、失敗したときに「書き方が悪い」と解釈されやすい。 書き方以外の原因を探す入口が、公式ドキュメントの適用範囲と優先順位の節に置かれています。

判断軸:いま分かっていないのは、どちらか

原因の特定を、次の順序で行うことを提案します。

  1. 問いを2つに分ける。 「このパスは追跡済みか」と「このパスはどのパターンに一致するか」は別の問いです。混ぜたまま調べると、どちらの答えも得られません
  2. 追跡済みかどうかを先に確定させる。 追跡済みなら、.gitignore をどう書いても結果は変わりません。この場合の手順は、インデックスから外す(作業ツリーのファイルは残る)ことから始まります
  3. 追跡済みでないなら、どの情報源のどの行が効いたかを見る。 -v の出力形式には情報源と行番号が含まれます。想定していた .gitignore 以外の情報源が出てきたら、そこが原因です
  4. 否定パターンの有無を確かめる。 一致したパターンが感嘆符で始まっていれば、そのパスは除外されない側です
  5. 同じ段の後ろの行を見る。 期待した行が効いていないなら、同じ情報源の下の方に打ち消す行がある可能性があります

この順序の要点は、1番目を省略しないことです。追跡済みかどうかが決まっていない状態でパターンを直し始めると、効かなかったことが「このパターンは間違い」という誤った学習になります。

手元で確かめられる最小の手順

いま .gitignore に書いたのに git status に出ているパスがあるなら、次の手順で原因の所在が分かります。

  1. そのパスについて、通常の判定を -v 付きで行う
  2. 同じパスについて、インデックスを見ない判定を -v 付きで行う
  3. 2つの結果を比べる

1番目で何も出ず、2番目でパターンが出たなら、そのパスは追跡済みです(既定では追跡済みが表示されないため)。両方で何も出なければ、どのパターンにも一致していません。つまりパターンの書き方の問題です。1番目でパターンが出たなら、表示された情報源と行番号が、想定していた場所かを確認します。

棚卸しをするなら、次の指標で数えられます。

  • 分子:.gitignore に書いたのに git status に現れるパスのうち、原因を「追跡済み」「別の情報源のパターン」「否定パターン」「不一致」のいずれかに分類できた件数
  • 分母:.gitignore に書いたのに git status に現れるパスの総数
  • 単位:%(件数/件数)

比率を上げること自体が目的ではありません。分母に入っていて分子に入らないパスは、原因が分からないまま .gitignore を書き足されている対象です。書き足しは、効かないうえに、次に読む人へ「ここは対処済み」という誤った目印を残します。分子に入らない1件を選び、上の3手順で分類する——それが最初の一手になります。

確かなことと、確かでないこと

確かなこと(2026年10月29日に4件の公式ドキュメントを取得して確認した範囲):追跡済みファイルが影響を受けないという記述と、gitignore の目的の定義。追跡をやめる手順とその順序。無視の判定を読む4つの情報源とその優先順位、上位階層が下位階層に上書きされること、パターンが .gitignore の位置を基準に照合されること。同じ段では最後に一致したパターンが結果を決めること。--cached が作業ツリーのファイルを残し、既定の動作が作業ツリーからも削除すること。git check-ignore が既定で追跡済みファイルを表示しないこと、その理由、-v の出力形式、否定パターンの読み替え、不一致のときに何も出力されないこと、--no-index の目的。git add の既定動作と --force、および正確なファイル名を指定したときだけ失敗する非対称。

確かでないこと:「インデックスから外してコミットすると、他の人が取得したときに手元のファイルがどうなるか」。実務では重要な点ですが、今回参照した文書に記述がなく、確認していません。また Git のバージョンごとの差異も扱っていません。参照したページには版の表示がありますが、各版のリリース日を確認していないため、本記事ではバージョン番号に言及していません。

本記事が踏み込んでいないこと:履歴からファイルを除去する手順(参照した4件に記述がありません)。パターン記法(アスタリスク・スラッシュ・感嘆符などの意味)の網羅的な解説。core.excludesFile の既定値の断定。本記事はコマンドの出力例を載せていません。出力は環境によって変わり、今回実行していないためです。

無視されないときに立ち返る3つの問い

  1. このパスは、追跡済みか。 これが決まらないうちは、パターンの議論に入れません
  2. 効いているパターンは、どこの何行目にあるか。 自分が書いた場所とは限りません
  3. この .gitignore は、誰の手元でも同じ結果になるか。 情報源のうち2つは環境ごとに異なりえます

Git の操作で詰まる場面は、たいてい「どのファイルがどの状態にあるか」が見えていないことから来ます。追跡・インデックス・コミットという状態の区別についてはGitとは何かとコミットとは何かで基礎から扱っています。

参考資料・引用元

よくある質問(FAQ)