サイトアイコンmaita tomoya dev io

#34 .gitignore完全ガイド:実務でよく使うパターンと既存ファイルの除外方法

「あ、このファイルコミットしちゃった...」「秘密鍵をpushしてしまった!」そんな経験はありませんか?本記事では、.gitignoreの基本から実務でよく遭遇するケースまで、具体例を交えて徹底解説します。

⚠️ 重要な警告

本記事で紹介するgit rm --cachedコマンドは、チーム全体に影響を与える可能性があります。実行前に必ずチームメンバーと相談してください。また、秘密情報を誤ってコミットした場合は、即座にキーの無効化を行ってください。

📚 目次

.gitignoreとは

.gitignoreは、Gitに無視してほしいファイルやディレクトリを指定するファイルです。

🔰 初心者向け:Gitの「追跡」とは?

Gitでは、ファイルを「追跡対象」として認識すると、そのファイルの変更を監視し始めます。

# 新規ファイルの状態確認
git status
# Untracked files: (未追跡ファイル)
#   newfile.txt

# ファイルを追跡対象に追加
git add newfile.txt

# 追跡開始後の状態
git status
# Changes to be committed: (コミット予定の変更)
#   new file: newfile.txt

重要: .gitignoreはまだ追跡されていないファイルに対してのみ効果があります。

なぜ必要?

プロジェクトフォルダ/
├── src/            # ← コミットしたい
├── node_modules/   # ← コミットしたくない(巨大)
├── .env           # ← コミットしたくない(秘密情報)
├── build/         # ← コミットしたくない(自動生成)
└── README.md      # ← コミットしたい

.gitignoreの効果

  • リポジトリサイズの削減: node_modulesなどの巨大ファイルを除外
  • セキュリティ向上: APIキーや秘密鍵の誤公開を防ぐ
  • クリーンな履歴: 自動生成ファイルによる無駄なコミットを防ぐ

基本的な書き方

1. コメント

# これはコメントです
# 開発環境
.env

# ビルド成果物
/build/

2. ファイル・ディレクトリの指定

# 特定のファイル
secret.txt

# 特定の拡張子
*.log
*.tmp

# ディレクトリ
node_modules/
dist/

# ルートディレクトリのみ
/config.json    # ルートのconfig.jsonのみ
config.json     # すべてのconfig.json

3. パターンマッチング

# ワイルドカード
*.log           # すべての.logファイル
temp-*          # temp-で始まるファイル

# 複数階層
**/*.tmp        # すべてのディレクトリの.tmpファイル
**/logs         # すべてのlogsディレクトリ

# 否定(除外の除外)
*.log
!important.log  # important.logは追跡する

実務でよく使うパターン

ケース1: 環境設定ファイル

# 環境変数
.env
.env.local
.env.*.local
.env.production

# IDE設定
.vscode/
.idea/
*.swp
*.swo
.DS_Store

実例:

# .envファイルに秘密情報を記載
echo "API_KEY=sk-xxxxxxxxxxxxx" > .env

# .gitignoreに追加
echo ".env" >> .gitignore

# これでgit statusしても.envは表示されない
git status

ケース2: ビルド成果物・依存関係

# Node.js
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# ビルド出力
dist/
build/
out/
.next/

# キャッシュ
.cache/
.parcel-cache/
.turbo/

ケース3: OS固有ファイル

# macOS
.DS_Store
.AppleDouble
.LSOverride
Icon
._*

# Windows
Thumbs.db
ehthumbs.db
Desktop.ini

# Linux
*~
.directory
.Trash-*

ケース4: 個人用ファイル

# 個人的なメモ
NOTE.md
TODO.md
personal/

# ローカル設定
*.local
local-config/

.gitignoreの変更が反映されるタイミング

📅 .gitignoreはいつ効果を発揮するか?

.gitignoreの変更は即座に効果を発揮しますが、対象となるのは未追跡ファイルのみです。

# 実例:.gitignoreの動作タイミング
# 1. 新規ファイルを作成
echo "test" > newfile.txt
git status
# → newfile.txt が Untracked files として表示される

# 2. .gitignoreに追加
echo "newfile.txt" >> .gitignore

# 3. 即座に効果発揮(masterマージ不要)
git status
# → newfile.txt は表示されなくなる

🔄 .gitignore変更の反映パターン

パターン1:新規ファイルの場合(即座に反映)

# .gitignoreに「*.log」を追加
echo "*.log" >> .gitignore

# 新しいログファイルを作成
touch debug.log

# 確認
git status
# → debug.log は最初から無視される(表示されない)

パターン2:既に追跡中のファイルの場合(手動対応が必要)

# 既存ファイルがある状態
git add existing.log
git commit -m "Add existing.log"

# .gitignoreに追加しても...
echo "*.log" >> .gitignore

# まだ追跡される
echo "update" >> existing.log
git status
# → existing.log の変更が表示される(.gitignoreが効かない)

# 手動で追跡を解除する必要がある
git rm --cached existing.log
git commit -m "Stop tracking existing.log"

🌐 チーム開発での.gitignore変更の流れ

graph LR A[開発者A: .gitignore変更] --> B[ローカルで即座に効果] B --> C[git commit & push] C --> D[masterマージ] D --> E[開発者B: git pull] E --> F[開発者Bでも効果発揮]

重要なポイント:

  1. .gitignoreの変更自体: ローカルで即座に効果(コミット不要)
  2. チームへの共有: masterマージ後、他メンバーがpullした時点で反映
  3. 既存ファイルの追跡解除: git rm --cachedが必要(これは要注意)

⚠️ よくある誤解と真実

誤解真実
「.gitignoreはmasterマージしないと効かない」❌ ローカルでは即座に効果を発揮
「.gitignoreに追加すれば全ファイルが無視される」❌ 未追跡ファイルのみが対象
「git pullしたら.gitignoreが自動で既存ファイルに適用」❌ 既存ファイルは手動でgit rm --cachedが必要

既に追跡されているファイルを除外する方法

🔴 よくある問題

「.gitignoreに追加したのに、まだgit statusに表示される!」

原因: すでにGitで追跡されているファイルは、.gitignoreに追加しても無視されません。

⚠️ 重要な注意事項

git rm --cachedチーム全体に影響します。実行前に必ずチームメンバーと相談してください。

⚠️ 警告: git rm --cachedの影響
• 他の開発者がgit pullすると、ローカルファイルが削除される
• ファイルが必要な場合は、事前にバックアップを共有
• チーム全体への周知が必要

✅ 解決方法

方法1: ローカルでのみ無視(安全)

# 他の開発者に影響しない方法
git update-index --skip-worktree config/database.yml

# 解除方法
git update-index --no-skip-worktree config/database.yml

方法2: チーム全体から除外(注意が必要)

# 1. .gitignoreに追加
echo "NOTE.md" >> .gitignore

# 2. Gitの追跡から除外(ファイルは残る)
git rm --cached NOTE.md

# 3. コミット
git commit -m "chore: NOTE.mdをGit管理から除外"

# ⚠️ 他の開発者への影響:
# git pullするとNOTE.mdが削除されるため、
# 事前にファイルのバックアップを周知

方法2: ディレクトリの場合

# 1. .gitignoreに追加
echo "temp/" >> .gitignore

# 2. ディレクトリ全体を追跡から除外
git rm -r --cached temp/

# 3. コミット
git commit -m "chore: tempディレクトリをGit管理から除外"

方法3: 複数ファイルを一括処理

# 1. .gitignoreを更新
cat >> .gitignore << EOF
*.log
*.tmp
.cache/
EOF

# 2. .gitignoreに基づいて一括削除
git rm --cached \$(git ls-files -i -c --exclude-from=.gitignore)

# 3. コミット
git commit -m "chore: 不要なファイルをGit管理から除外"

🚨 緊急対応:秘密情報をコミットしてしまった場合

ケーススタディ:AWSキーの漏洩

# 🔴 危険:このようなファイルがコミットされると...
aws-credentials.json
{
  "accessKeyId": "AKIA...",
  "secretAccessKey": "..."
}

# 結果:
# - 不正アクセスで高額請求
# - データベース内容の漏洩
# - サービス停止

即座に実行すべき対応

  1. キーの無効化(最優先)
# AWSの場合
aws iam delete-access-key --access-key-id AKIA...

# GitHubトークンの場合
# Settings > Developer settings > Personal access tokensから削除
  1. Git履歴からの完全削除

実践例:誤ってコミットした.envファイルを除外

# 状況:.envファイルをコミットしてしまった
$ git log --oneline
a1b2c3d feat: 新機能追加(.envも含まれている)

# 対処法
# 1. .gitignoreに追加
echo ".env" >> .gitignore

# 2. 追跡から除外
git rm --cached .env

# 3. コミット
git commit -m "security: .envファイルをGit管理から除外"

# 4. 履歴からも完全に削除する場合(重要)
git filter-branch --force --index-filter \
  "git rm --cached --ignore-unmatch .env" \
  --prune-empty --tag-name-filter cat -- --all

# 5. 強制プッシュ(チーム開発の場合は要相談)
git push origin --force --all

よくある失敗と対処法

失敗1: node_modulesをコミットしてしまった

# 😱 間違えてコミット
git add .
git commit -m "初回コミット"
# → リポジトリが巨大に!

# 🔧 対処法
# 1. .gitignoreに追加
echo "node_modules/" >> .gitignore

# 2. 追跡から除外
git rm -r --cached node_modules/

# 3. コミット
git commit -m "fix: node_modulesをGit管理から除外"

失敗2: .gitignoreが効かない

# 😕 .gitignoreに追加したのに...
echo "debug.log" >> .gitignore
git status
# → まだdebug.logが表示される

# 🔍 原因確認
git check-ignore -v debug.log
# → 何も表示されない = すでに追跡されている

# 🔧 対処法
git rm --cached debug.log
git commit -m "chore: debug.logを追跡から除外"

失敗3: 必要なファイルまで無視してしまった

# 😱 間違った設定
*.config    # すべての.configファイルを無視

# 🔧 修正版
*.config
!app.config    # app.configは追跡する
!system.config # system.configも追跡する

言語・フレームワーク別テンプレート

Node.js / JavaScript

# Dependencies
node_modules/
jspm_packages/

# Build
dist/
build/
*.js.map

# Testing
coverage/
.nyc_output

# Logs
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Environment
.env
.env.*

# IDE
.vscode/
.idea/
*.sublime-*

# OS
.DS_Store
Thumbs.db

Python

# Byte-compiled
__pycache__/
*.py[cod]
*$py.class

# Virtual Environment
venv/
env/
ENV/

# Distribution
dist/
build/
*.egg-info/

# Testing
.pytest_cache/
.coverage
htmlcov/

# Jupyter
.ipynb_checkpoints/

# Environment
.env

Java

# Compiled
*.class
target/
out/

# Package Files
*.jar
*.war
*.ear

# IDE
.idea/
*.iml
.eclipse
.project
.settings/

# Build tools
.gradle/
build/

React / Next.js

# Dependencies
node_modules/
/.pnp
.pnp.js

# Testing
/coverage

# Production
/build
/.next/
/out/

# Misc
.DS_Store
*.pem

# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Local env files
.env*.local

# Vercel
.vercel

# TypeScript
*.tsbuildinfo
next-env.d.ts

高度な使い方

グローバル.gitignore

個人環境固有のファイルは、グローバル設定で管理:

# グローバル.gitignoreを作成
touch ~/.gitignore_global

# 設定
cat >> ~/.gitignore_global << EOF
# OS
.DS_Store
Thumbs.db

# IDE
.vscode/
.idea/
*.swp

# 個人用
NOTE.md
TODO.md
EOF

# Gitに登録
git config --global core.excludesfile ~/.gitignore_global

.gitignoreの階層構造

project/
├── .gitignore          # プロジェクト全体
├── src/
│   └── .gitignore     # srcディレクトリ専用
└── tests/
    └── .gitignore     # testsディレクトリ専用

各.gitignoreは、そのディレクトリ以下に適用されます。

条件付き無視

# 開発環境のみ無視
[Dd]ebug/
[Rr]elease/

# 特定の深さのみ
/config/*
!/config/default.json

# 特定パターンの除外
logs/*.log
!logs/important-*.log

トラブルシューティング

Q1: .gitignoreを追加したのに反映されない

# キャッシュをクリア
git rm -r --cached .
git add .
git commit -m "fix: .gitignoreを反映"

Q2: どのルールで無視されているか確認したい

# ファイルが無視される理由を確認
git check-ignore -v ファイル名

# 例
$ git check-ignore -v node_modules/
.gitignore:3:node_modules/    node_modules/

Q3: 一時的に.gitignoreを無視したい

# 強制的に追加
git add -f 通常は無視されるファイル

# 例:設定ファイルのテンプレート
git add -f .env.example

Q4: .gitignore自体を無視したい

# ローカル専用の除外設定
echo "personal-ignore.txt" >> .git/info/exclude

# .git/info/excludeはリポジトリには含まれない

CI/CD環境での.gitignore戦略

環境別設定ファイルの管理

# 本番環境用設定
config/
├── database.yml.example      # テンプレート(追跡する)
├── database.yml              # 実際の設定(無視する)
└── secrets.yml.enc           # 暗号化済み(追跡する)

# .gitignore設定
config/database.yml
config/secrets.yml
!config/secrets.yml.enc

GitHub Actionsでの活用

# .github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      # 環境変数から設定ファイルを生成
      - name: Setup config files
        run: |
          echo "${{ secrets.DATABASE_YML }}" > config/database.yml
          echo "${{ secrets.ENV_FILE }}" > .env

ベストプラクティス

1. プロジェクト開始時に設定

# プロジェクト初期化と同時に.gitignore作成
git init
curl -o .gitignore https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
git add .gitignore
git commit -m "initial commit: add .gitignore"

2. チーム共通 vs 個人設定の分離

# === チーム共通設定 ===
# Dependencies
node_modules/

# Build
dist/
build/

# Environment
.env

# === 個人設定はグローバル.gitignoreへ ===
# IDE設定 → ~/.gitignore_global
# OS固有ファイル → ~/.gitignore_global

3. セキュリティファーストの設定

# セキュリティ最優先
*.key
*.pem
*.p12
*.pfx
.env*
!.env.example  # サンプルのみ許可
secrets/
credentials/

4. コメントで意図を明確に

# === Dependencies ===
# npm/yarn packages - インストール可能なので除外
node_modules/

# === Build Outputs ===
# ソースから生成可能なので除外
dist/
build/

# === Sensitive Data ===
# セキュリティのため絶対に除外
.env
*.key

# === Temporary Files ===
# 一時ファイルは不要
*.tmp
*.cache

5. 定期的な見直し

# 不要になった設定を整理
# 1. 現在追跡されているファイルを確認
git ls-files

# 2. .gitignoreされているが存在するファイルを確認
git status --ignored

# 3. .gitignoreをクリーンアップ
# 不要な行を削除、整理

実践演習

演習1: 新規プロジェクトのセットアップ

# 1. プロジェクト作成
mkdir my-app && cd my-app
git init

# 2. .gitignore作成
cat > .gitignore << 'EOF'
# Dependencies
node_modules/

# Environment
.env
.env.*
!.env.example

# Build
dist/
build/

# Logs
*.log

# OS
.DS_Store
Thumbs.db

# IDE
.vscode/
.idea/
EOF

# 3. 確認
git status

演習2: 既存ファイルの除外

# 状況:config.localを誤ってコミット済み

# 1. 現状確認
git ls-files | grep config

# 2. .gitignoreに追加
echo "*.local" >> .gitignore

# 3. 追跡除外
git rm --cached config.local

# 4. コミット
git commit -m "chore: ローカル設定ファイルを除外"

# 5. 確認
touch another.local
git status  # another.localは表示されない

チートシート

よく使うパターン一覧

# === ファイルパターン ===
*.log           # 拡張子
!important.log  # 除外の除外
temp-*          # プレフィックス
*-backup        # サフィックス

# === ディレクトリパターン ===
logs/           # ディレクトリ
/logs/          # ルートのみ
**/logs/        # すべての階層

# === 複合パターン ===
*.tmp
!config/*.tmp   # configディレクトリは除外しない
build/**/*.js   # build以下のすべてのjs

コマンド早見表

# 追跡状況確認
git ls-files                     # 追跡中のファイル一覧
git status --ignored             # 無視されているファイル表示
git check-ignore -v ファイル名    # 無視理由を確認

# 追跡から除外
git rm --cached ファイル名       # ファイルを残して除外
git rm -r --cached ディレクトリ/  # ディレクトリを除外

# 強制操作
git add -f ファイル名            # .gitignore無視して追加
git clean -fdX                   # 無視ファイルを削除

まとめ

📝 重要なポイント

  1. .gitignoreは予防策: 最初から設定することが重要
  2. 既存ファイルにはgit rm --cached: 追跡済みファイルは別途対処が必要
  3. チーム共通と個人設定を分離: グローバル.gitignoreを活用
  4. セキュリティファースト: 秘密情報は必ず除外
  5. 定期的なメンテナンス: プロジェクトの成長に合わせて更新

🎯 実務での心得

  • プロジェクト開始時に必ず設定
  • コミット前にgit statusで確認
  • 秘密情報は.env.exampleでテンプレート化
  • IDEやOS固有ファイルはグローバル設定へ
  • チームで.gitignoreルールを共有

🚀 次のステップ

  1. 自分のプロジェクトの.gitignoreを見直す
  2. グローバル.gitignoreを設定する
  3. gitignore.ioでテンプレート生成
  4. チームで.gitignoreのルールを決める

適切な.gitignore設定により、クリーンで安全なリポジトリ管理が可能になります。今すぐ実践してみましょう!

参考リンク


本記事で紹介した実例は、実際の開発現場でよく遭遇するケースを基にしています。