Fragments of verbose memory

冗長な記憶の断片 - Web技術のメモをほぼ毎日更新

Jan 10, 2026 - 日記

.gitignore だけじゃない: Git ファイル無視の4つの方法と使い分け

.gitignore だけじゃない: Git ファイル無視の4つの方法と使い分け cover image

Git でファイルを無視する方法として .gitignore は有名ですが、実は他にも3つの方法があります。環境依存の設定ファイルをローカルだけ変更したい、巨大なSDKの差分チェックを省きたい、といったケースでは .gitignore だけでは解決できません。

本記事では、Gitのファイル無視方法4つを比較し、状況ごとの使い分けを整理します。

先に結論: 4つの方法の使い分けフローチャート

以下のフローチャートで、状況に応じた最適な方法を選択できます。

flowchart TD
    A[ファイルを無視したい] --> B{ファイルは
Git管理下?} B -->|未追跡| C{チーム全体で
無視したい?} B -->|追跡済み| D{目的は?} C -->|はい| E[.gitignore] C -->|いいえ| F[.git/info/exclude] D -->|パフォーマンス
最適化| G[--assume-unchanged] D -->|ローカル設定
変更保護| H[--skip-worktree] E --> E1[チーム共有
リポジトリにコミット] F --> F1[個人ローカル
他人に影響なし] G --> G1[変更チェックを省略
フラグは揮発的] H --> H1[ローカル変更を保護
フラグは永続的] style E fill:#90EE90 style F fill:#87CEEB style G fill:#FFB6C1 style H fill:#FFD700

4つの方法の概要

1. .gitignore(未追跡ファイル・チーム共有)

使用場面: ビルド成果物、ログファイル、依存関係ディレクトリなど、チーム全体で無視すべきファイル

特徴:

  • リポジトリにコミットされる(全員が共有)
  • 未追跡のファイルのみ対象
  • すでにGit管理下にあるファイルには効果なし

:

# ビルド成果物
dist/
*.pyc
__pycache__/

# 依存関係
node_modules/
venv/

# 環境変数ファイル
.env

公式ドキュメント: gitignore Documentation

2. .git/info/exclude(未追跡ファイル・個人ローカル)

使用場面: 個人的な作業ファイル、エディタ設定、ローカルスクリプトなど、他人に影響を与えたくない無視設定

特徴:

  • リポジトリにコミットされない(個人ローカル)
  • .gitignore と同じ記法
  • クローン時には含まれない

:

1
2
3
4
# .git/info/exclude ファイルを編集
echo "*.swp" >> .git/info/exclude
echo ".vscode/" >> .git/info/exclude
echo "my-local-notes.md" >> .git/info/exclude

使用例: エディタの一時ファイル、個人的なメモ、ローカル開発用スクリプト

3. --assume-unchanged(追跡済みファイル・パフォーマンス最適化)

使用場面: 大規模なSDKやライブラリなど、変更チェックが高コストなファイル

特徴:

  • パフォーマンス最適化が目的
  • ファイルが変更されていないと仮定してチェックをスキップ
  • フラグは揮発的(git pull で変更があると自動的にリセット)
  • 設定ファイルの管理には不適

コマンド:

1
2
3
4
5
6
7
8
# フラグを設定
git update-index --assume-unchanged path/to/file

# フラグを確認(h = assumed-unchanged)
git ls-files -v | grep "^h"

# フラグを解除
git update-index --no-assume-unchanged path/to/file

注意: Git公式ドキュメント では「設定ファイルの無視には使わないこと」と明記されています。

4. --skip-worktree(追跡済みファイル・ローカル設定変更)

使用場面: 環境依存の設定ファイルなど、ローカルで変更が必要だが上流には反映したくないファイル

特徴:

  • ローカルの変更を保護することが目的
  • フラグは永続的(git pull でもリセットされない)
  • git reset --hard でも変更が保護される

コマンド:

1
2
3
4
5
6
7
8
# フラグを設定
git update-index --skip-worktree path/to/config.json

# フラグを確認(S = skip-worktree)
git ls-files -v | grep "^S"

# フラグを解除
git update-index --no-skip-worktree path/to/config.json

典型的な使用例:

1
2
3
4
5
# 本番用設定ファイルがリポジトリにある
# ローカル開発では別の設定を使いたい
git update-index --skip-worktree config/database.yml
vim config/database.yml  # ローカル用に編集
git status  # 変更として表示されない

assume-unchanged と skip-worktree の違い

この2つは似ていますが、挙動に重要な違いがあります。

操作assume-unchangedskip-worktree
git pull(上流に変更あり)フラグがリセットされるフラグは保持される
git stashローカル変更が破棄されるstashが失敗(変更は保護される)
git reset --hardフラグがリセットされるファイルは保護される
ブランチ切り替えエラーになることがあるエラーになることがある

Git公式ドキュメント より:

Users often try to use the assume-unchanged and skip-worktree bits to tell Git to ignore changes to files that are tracked. This does not work as expected, since Git may still check working tree files against the index when performing certain operations. In general, Git does not provide a way to ignore changes to tracked files, so alternate solutions are recommended.

(訳: ユーザーは assume-unchanged と skip-worktree ビットを使って追跡済みファイルの変更を無視しようとすることがありますが、これは期待通りには動作しません。Gitは特定の操作を行う際にワークツリーファイルをインデックスと照合することがあるためです。一般的に、Gitは追跡済みファイルの変更を無視する方法を提供していないため、代替ソリューションを推奨します。)

つまり、どちらも設定ファイル管理の「正攻法」ではないということです。

Git公式が推奨する設定ファイル管理方法

公式ドキュメント(Git 2.25.1以降)では、代替案として以下を推奨しています:

方法1: テンプレートファイル方式

1
2
3
4
5
6
7
# リポジトリ構成
config.json.example    # リポジトリにコミット
config.json            # .gitignore で無視

# セットアップ手順
cp config.json.example config.json
vim config.json  # ローカル用に編集

.gitignore:

config.json

方法2: スクリプトによる自動生成

1
2
3
4
5
#!/bin/bash
# setup-config.sh
# テンプレートから環境変数を置換してconfig.jsonを生成

envsubst < config.json.template > config.json

config.json.template:

1
2
3
4
{
  "api_url": "${API_URL}",
  "debug": "${DEBUG_MODE}"
}

この方法なら、環境変数でローカル設定を管理できます。

方法3: smudge/clean フィルター(上級者向け)

content filter driver を使うと、チェックアウト時に自動的にテンプレート展開できます。

詳細は別記事で扱う予定です。

実例: 環境依存ファイルの管理パターン

「ビルド時に環境変数が置換される設定ファイル」や「開発環境と本番環境で内容が異なるファイル」は、以下のように管理します:

❌ 間違った方法

1
2
3
# これは公式非推奨
git update-index --assume-unchanged config/api-config.js
git update-index --skip-worktree src/constants.js

問題点:

  • git pull で予期しない挙動が起きる可能性がある
  • チームメンバーごとに異なる方法を使うと混乱する
  • フラグの設定を忘れると設定ファイルが上書きされる

✅ 正しい方法

パターン1: テンプレートファイル + ビルドスクリプト

1
2
3
# build.sh
envsubst < config/api-config.js.template > config/api-config.js
npm run build

.gitignore:

config/api-config.js

メリット:

  • 環境変数で管理するため、CI/CD と統合しやすい
  • テンプレートはバージョン管理下に置ける
  • チーム全体で一貫した方法を使える

パターン2: 環境別ファイルの切り替え

1
2
3
4
config/
  ├── config.development.json   # 開発環境用
  ├── config.staging.json       # ステージング環境用
  └── config.production.json    # 本番環境用

ビルド時に環境変数で切り替え:

1
cp config/config.${NODE_ENV}.json config/config.json

メリット:

  • 環境ごとの設定を明示的に管理できる
  • 環境の切り替えがシンプル

まとめ

Gitのファイル無視方法は4つありますが、目的に応じて使い分けることが重要です:

方法対象共有範囲用途
.gitignore未追跡チーム全体ビルド成果物、依存関係
.git/info/exclude未追跡個人エディタ設定、個人メモ
--assume-unchanged追跡済み個人パフォーマンス最適化(非推奨)
--skip-worktree追跡済み個人ローカル設定変更(非推奨)

重要なポイント:

  • --assume-unchanged--skip-worktree は設定ファイル管理の正攻法ではない
  • 公式推奨は「テンプレートファイル + .gitignore」方式
  • どうしても使う場合は --skip-worktree の方が安全(ローカル変更が保護される)

設定ファイル管理で困っている方は、まず「テンプレートファイル方式」を検討してみてください。

参考リンク