手順

.gitignore ファイル: Git の対象から除外する方法と、追跡済みファイルの外し方

更新日: · Skillaria.Top

リポジトリのルートにある .gitignore ファイルには、Git が追跡しないファイルやフォルダのパターンを書きます。依存関係、ビルド結果、ログ、秘密情報などが対象です。除外は未追跡のファイルにだけ効くため、すでにコミットされているファイルは git rm --cached で追跡対象から外す必要があります。

git ignore は、「このファイルには触れず、git status に表示せず、git add . でも追加しない」ことを Git に伝える仕組みです。ルールは .gitignore というテキストファイルに書き、プロジェクトと一緒にコミットします。こうすればチーム全体で同じルールが共有されます。注意すべき点は1つです。除外は、Git がまだ追跡していないファイルにのみ働きます。

.gitignore によく入れるもの

  • 依存関係: node_modules/、vendor/、.venv/。パッケージマネージャーが復元できるものです。
  • ビルドの成果物: dist/、build/、*.class、__pycache__/。
  • ログと一時ファイル: *.log、tmp/、*.swp。
  • 秘密情報とローカル設定: .env、鍵、マシンごとの設定ファイル。
  • OS やエディタのごみ: .DS_Store、Thumbs.db、.idea/。これらはグローバルな除外設定に入れるのが望ましく、後述します。

原則は単純です。リポジトリに入れるべきものは人が書いたものであり、プログラムが生成したものや、特定のマシンに依存するものは入れません。

.gitignore の作り方

リポジトリのルートにあるただのテキストファイルです。作成し、1行に1つずつパターンを書いて、コミットします。

cat > .gitignore <<'EOF'
# 依存関係
node_modules/
# ビルド
dist/
# ログ
*.log
# 秘密情報
.env
EOF

git add .gitignore
git commit -m "chore: .gitignore を追加"

主要な言語やフレームワーク向けの定番テンプレートは、github/gitignore リポジトリにあります。GitHub と GitLab でも、プロジェクト作成時にテンプレートを選べます。それを土台にして、不要なものを削るとよいでしょう。

.gitignore のパターンの書き方

パターン除外される対象
*.logどのフォルダにあっても、拡張子が .log のファイル
build/どの階層にあっても build フォルダ(末尾のスラッシュはフォルダだけを指す)
/buildリポジトリ直下の build だけ(先頭のスラッシュは .gitignore のあるフォルダを基準にする)
docs/*.pdfdocs 直下の pdf。docs/old/ 内は除外されない
docs/**/*.pdfdocs とその下のすべてのフォルダにある pdf
**/tempどのフォルダにある temp も
!keep.log例外: keep.log は除外しない
file?.txt? は任意の1文字
[ab].txta.txt または b.txt
# コメントコメント行

注意すべき点があります。途中にスラッシュを含まないパターン(config.json)は、どの階層でも一致します。先頭や途中にスラッシュがあるパターン(/config.json、src/config.json)は、その .gitignore があるフォルダを基準にします。

感嘆符による例外

*.log
!important.log

落とし穴があります。親のフォルダ全体が除外されていると、その中のファイルを例外で戻すことはできません。Git は除外されたフォルダの中に入らないためです。次の例は動きません。

logs/
!logs/keep.txt     # 動かない

正しくは、フォルダではなく中身を除外します。

logs/*
!logs/keep.txt

同じ方法で、空のフォルダをリポジトリに残せます。Git は空のフォルダを保存しないので、.gitkeep というファイルを入れ、そのファイルだけを例外にします。

除外設定を置く場所

場所効果の範囲リポジトリに入るか
ルートとサブフォルダの .gitignoreチーム全体入る
.git/info/excludeこのクローンだけ入らない
グローバルなファイル(core.excludesFile)自分のすべてのリポジトリ入らない

OS や IDE のごみは、共通の .gitignore を汚さないようにグローバルな除外設定に入れるとよいでしょう。

git config --global core.excludesFile ~/.gitignore_global
echo ".DS_Store" >> ~/.gitignore_global
echo ".idea/" >> ~/.gitignore_global

core.excludesFile が設定されていない場合、Git は存在すれば ~/.config/git/ignore を読みます。

.gitignore が効かないとき

よくある不満は、「.gitignore にファイルを追加したのに、Git が変更を表示し続ける」というものです。原因はほぼ常に1つです。ファイルがすでに追跡されているのです。除外は、一度コミットに入ったファイルには効きません。

どのルールが働いているか(あるいは働いていないか)を確認するには git check-ignore を使います。

git check-ignore -v logs/app.log
# .gitignore:3:*.log	logs/app.log

出力にはファイルと該当するルールの行が表示されます。出力が空なら、そのファイルは除外されていません。ほかの原因として、パターンの末尾の空白や、ファイルの文字コードの問題があります(PowerShell で作ると UTF-16 になることがあります)。

コミット済みのファイルを追跡から外す: git rm --cached

git rm はファイルをインデックスとディスクの両方から削除します。--cached を付けると、インデックスからだけ削除します。ファイルは手元に残りますが、追跡されなくなります。

echo ".env" >> .gitignore
git rm --cached .env
git commit -m "chore: .env を追跡対象から除外"
git push

フォルダの場合は -r が必要です。

git rm -r --cached node_modules/

どのファイルがリポジトリに入ってしまったか分からない場合は、インデックスを全体的に作り直せます。git rm -r --cached . を実行し、git add . を実行してコミットします。コミットの前に git status で確認してください。インデックスから外されたファイルが表示されます。

注意: 秘密情報は履歴に残る

git rm --cached はそれ以降のコミットからファイルを取り除きますが、過去のコミットからは取り除きません。パスワードやトークンがリポジトリに入ってしまったら、クローンを持つ誰でも履歴から見られます。その秘密情報は漏えいしたものとみなし、再発行してください。履歴を書き換えるには git filter-repo などのツールを使えますが、すべてのコミットのハッシュが変わり、チーム全員との調整が必要になります。

もう1つの影響として、同僚が git pull を実行すると、--cached で追跡から外されたファイルがディスクからも削除されることがあります。.env の場合は、事前に伝えておくか、リポジトリに .env.example というひな形を置いておきましょう。

git rm: ファイルを削除する

git rm old.py              # ディスクとインデックスから削除
git rm -r legacy/          # フォルダを削除
git rm -n '*.tmp'          # ドライラン: 削除される対象を表示
git rm -f changed.py       # 未コミットの変更があるファイルも削除

通常の rm でファイルを削除すると、Git はそれを「deleted」と認識しますが、削除を反映させるには git add か git rm が必要です。git rm は両方の手順を一度に行います。-f を付けない場合、未コミットの変更があるファイルは削除を拒否します。作業の消失を防ぐための安全策です。

git mv: 名前の変更と移動

git mv utils.py helpers.py
git mv helpers.py src/helpers.py

git mv は、mv、古いパスに対する git rm、新しいパスに対する git add を一度に行うコマンドです。Git は名前の変更を別途記録しません。git status、git log --follow、git diff の出力時に、内容の類似度から判断します。そのため、git mv を使っても、通常の mv の後に git add -A を実行しても、結果は同じです。

実践的なヒントとして、名前の変更と内容の変更は別々のコミットに分けてください。名前を変えると同時にファイルの内容が大きく変わると、Git が同じファイルだと認識できず、--follow による履歴が途切れることがあります。

Windows や macOS では、ファイル名の大文字と小文字だけを変えたい場合があります(これらのファイルシステムは大文字と小文字を区別しません)。その場合は git mv readme.md README.md を使ってください。エクスプローラーで単純に名前を変えると、Git が変更を検出しないことがあります。

ルールの順序と優先順位

1つのファイル内では、ルールは上から順に読まれ、最後に一致したものが優先されます。そのため、例外の !keep.log は *.log より下に書かなければ、打ち消されてしまいます。ファイル同士の優先順位は次のとおりです。サブフォルダの .gitignore はルートより優先されます。グローバルな除外設定と .git/info/exclude は最も優先順位が低くなります。

Web プロジェクトの .gitignore の例

以下は、Node.js のフロントエンドと Python のバックエンドを持つプロジェクトで実際に使える例です。コメントに注目してください。半年後には、誰もそのルールを追加した理由を覚えていないからです。

# --- 依存関係 ---
node_modules/
.venv/

# --- ビルドとキャッシュ ---
/dist
/build
__pycache__/
*.pyc
.pytest_cache/
coverage/

# --- ログ ---
*.log
npm-debug.log*

# --- 環境と秘密情報 ---
.env
.env.*
!.env.example

# --- ユーザーのアップロード。フォルダは残す ---
uploads/*
!uploads/.gitkeep

ここでは、例外を使う2つの方法が使われています。.env.* はローカルの環境ファイルをすべて除外しますが、ひな形の .env.example はリポジトリに残ります。また uploads フォルダは、.gitkeep のおかげでクローンに存在し続けます。

除外してはいけないもの

除外のしすぎも問題です。依存関係のロックファイル(package-lock.json、poetry.lock、composer.lock)は、アプリケーションでは通常コミットします。すべての開発者と CI で同じバージョンのパッケージが入ることを保証するためです。フォーマットの共通設定(.editorconfig、リンターの設定)も、リポジトリに入れておくべきものです。

判断が分かれるのは IDE の設定です。.vscode/ フォルダは丸ごと除外されることが多いですが、推奨する拡張機能やビルドタスクだけをコミットする場合もあります。その場合は .vscode/* を書き、続けて !.vscode/extensions.json を書きます。どうするかはチームが決めることです。大切なのは、個人のパスや鍵を共有リポジトリに入れないことです。

よくある事故: node_modules をコミットしてしまった

新人によくあるミスは、.gitignore を作る前に git add . を実行して、数万個のファイルがコミットに入ってしまうことです。修正は3ステップです。

echo "node_modules/" >> .gitignore
git rm -r --cached node_modules
git commit -m "chore: node_modules をリポジトリから除外"

まだサーバーに push していないなら、重いファイルを履歴に残さないよう、コミットをやり直すとよいでしょう。git reset --soft HEAD~1 を実行してから、同じコマンドで新しいコミットを作ります。push 後はファイルが履歴に残り、履歴を書き換えない限りクローンのサイズは減りません。

こうしたミスを防ぐには、最初の git add の前に .gitignore を作り、コミットの前に毎回 git status を見る習慣をつけましょう。新規ファイルのリストが異常に長ければ、そこで立ち止まるサインです。

まとめ

.gitignore は、新しいプロジェクトで最初にコミットすべきファイルです。依存関係、ビルド成果物、ログ、秘密情報はリポジトリに入れる必要がありません。除外は未追跡のファイルにしか効かないため、すでに追加されたファイルは git rm --cached で外します。ルールは git check-ignore -v で確認できます。削除や名前の変更には、git rm と git mv を使えば、変更がすぐにインデックスに反映されます。インデックスと最初のリポジトリの扱い方は、Gitコースで実践的に解説しています。

よくある質問

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

はい。チーム全員に同じルールが適用されるようにするためです。個人的な除外は .git/info/exclude やグローバルな除外設定に書きます。

.gitignore は複数あってもよいですか?

はい。どのサブフォルダにも置けます。そのルールはそのフォルダを基準に働き、ルートのルールを補います。

除外されているファイルを強制的にコミットするには?

git add -f パス を使います。その後はファイルが追跡され、.gitignore はそのファイルに影響しなくなります。

プロジェクト内の除外されたファイルを一覧表示するには?

git status --ignored または git ls-files --others --ignored --exclude-standard を実行します。

コミット済みのファイルの変更を一時的に追跡しないようにするには?

git update-index --skip-worktree ファイル という方法がありますが、これはローカルだけの設定で、.gitignore の代わりにはなりません。

動画でこのテーマを学ぶ

このテーマはコース「Git:初心者から自信を持って使える開発者へ」で実践とともに詳しく解説しています。

コースへ