Gitで追跡対象から外したいファイルを.gitignore
に追加したのに、すでにリポジトリに登録されているファイルは無視されずステージングされてしまうことがあります。
これはGitの仕組みによるもので、既に追跡中のファイルは.gitignore
だけでは除外できません。
本記事では、その原因と具体的な解決方法を解説します。
原因:既に追跡対象になっている
.gitignore
は「まだ追跡されていないファイル」に対してのみ無視を適用します。
一度でもgit add
されてコミット履歴に登録されたファイルは、.gitignore
に追加しても追跡対象のままです。
そのため、無視リストに入れても変更があればステージされます。
解決方法1:キャッシュから削除する
既存の追跡ファイルをリポジトリから削除し、作業ディレクトリには残すことで、.gitignore
が有効になります。
# .gitignoreに対象パスを追加
echo "path/to/file.log" >> .gitignore
# インデックス(追跡状態)から削除し、作業ツリーには残す
git rm --cached path/to/file.log
# 変更をコミット
git commit -m "Stop tracking file.log"
これ以降、そのファイルは.gitignore
で無視されるようになります。
解決方法2:ディレクトリ単位で除外する
ログやビルド成果物など、ディレクトリごと除外したい場合は.gitignore
にパスを記述し、同様にキャッシュから削除します。
# .gitignoreにディレクトリを追加
echo "logs/" >> .gitignore
# キャッシュから削除
git rm -r --cached logs/
# コミット
git commit -m "Ignore logs directory"
解決方法3:全追跡ファイルを再評価する
無視パターンの追加が多い場合や、対象が広範囲に及ぶ場合は、キャッシュ全体をクリアして再登録すると効率的です。
# すべての追跡状態をクリア
git rm -r --cached .
# 再登録(.gitignoreに従う)
git add .
git commit -m "Apply updated .gitignore rules"
この方法は広範囲に影響するため、変更が多くなります。チームで共有しているリポジトリでは事前に合意を取ってから行いましょう。
解決方法4:グローバルgitignoreを使う
個人環境ごとに無視したいファイル(OSの一時ファイルやIDEの設定など)は、グローバル設定の~/.gitignore_global
に記載すると便利です。
# グローバルignoreファイルを作成
echo ".DS_Store" >> ~/.gitignore_global
# Gitに登録
git config --global core.excludesfile ~/.gitignore_global
再発防止のポイント
リポジトリ作成時や新しい機能ブランチを切った直後に.gitignore
を整備し、不要なファイルが一度も追跡されないようにすることが理想です。
また、ビルドやテストで生成されるファイルは、プロジェクトの雛形にあらかじめ無視設定を入れておくとトラブルを防げます。
まとめ
.gitignore
に追加しても既存ファイルが無視されないのは、すでに追跡対象になっているためです。
キャッシュから削除することで.gitignore
が有効になり、以降は変更が無視されるようになります。
プロジェクト開始時に無視設定をきちんと整備し、不要なファイルが履歴に入らないようにすることが再発防止につながります。