Gitignore のトラブルシューティングとデバッグガイド
よくある .gitignore の問題を解決:ファイルが無視されない、追跡済みファイルの削除、ルールのデバッグ。git check-ignore、rm --cached、エッジケースを網羅します。
詳細な説明
.gitignore が期待通りに動作しない場合、開発者は原因の推測に何時間も費やすことがあります。幸い、git にはファイルが無視される理由やされない理由を正確に特定するためのデバッグツールが用意されています。
問題 1: .gitignore がファイルを無視しない
最も一般的な原因:無視ルールを追加する前にファイルが既に追跡されていたことです。.gitignore は未追跡のファイルが追加されるのを防ぐだけです。既に git のインデックスにあるファイルには影響しません。
解決策: ローカルファイルを削除せずに追跡を解除します:
git rm --cached path/to/file
git commit -m "Untrack file now covered by .gitignore"
ディレクトリ全体の場合:
git rm -r --cached path/to/directory/
この後、.gitignore ルールが将来の操作に対して有効になります。
問題 2: どのルールがマッチしているかのデバッグ
git check-ignore を使用して、ファイルが無視される原因となっているルール(どのファイルのどの行か)を正確に追跡します:
git check-ignore -v path/to/file
出力例:.gitignore:5:*.log path/to/file.log — .gitignore の5行目のパターン *.log が原因であることがわかります。
問題 3: 否定パターンが機能しない
!important.txt がファイルを再包含しない場合、親ディレクトリが末尾スラッシュ付きで完全に無視されている可能性があります。build/ を無視すると、git は中を一切見ません。build/* に変更すると否定が正しく機能します。
問題 4: サブディレクトリの .gitignore
Git は任意のディレクトリレベルで .gitignore ファイルをサポートしています。ネストされた .gitignore のルールは親ディレクトリのルールをオーバーライドします。優先順位(高い順):
- コマンドラインパターン(
git add -fはルールに関係なく強制追加) - ファイルと同じディレクトリの
.gitignore - 親ディレクトリの
.gitignore(リポジトリルートまで遡る) .git/info/exclude(リポジトリレベルの個人的な除外、コミットされない)- グローバル gitignore(
core.excludesFile)
問題 5: 空白とエンコーディングの問題
- パターンの末尾の空白は無言の失敗を引き起こす可能性があります。
*.log(末尾にスペース)はerror.logにマッチしません。 .gitignoreが BOM(バイトオーダーマーク)なしの UTF-8 エンコーディングであることを確認してください。#で始まる行はコメントです。名前が#で始まるファイルにマッチするには\#を使用してください。
最終手段: .gitignore がどうしようもなく壊れている場合、インデックスを一からやり直すことができます:
git rm -r --cached .
git add .
git commit -m "Reset index to respect current .gitignore rules"
これによりインデックスからすべてのファイルが削除され、現在のすべての .gitignore ルールを適用して再追加されます。インデックス全体が書き換えられるため、大規模リポジトリでは慎重に使用してください。
ユースケース
開発者が .env を .gitignore に追加しましたが、git がまだファイルの変更を追跡しており、既に追跡されているファイルに無視ルールが効果を持たないように見える理由に困惑しています。