タイトル: 特定のファイルをgitの管理から外す方法
SEOタイトル: git で特定ファイルを管理から外す方法完全ガイド
| この記事の要点 |
|
状況別の対処早見表
| 状況 | 対処 |
|---|---|
| まだ追跡していない(新規ファイル) | .gitignore に追加するだけ |
| 既に追跡中。ファイルは残したい | git rm --cached file + .gitignore |
| 既に追跡中。ファイルも削除 | git rm file |
| 追跡継続のまま自分のローカル変更を無視 | git update-index --skip-worktree |
| 全ローカルで無視(個人設定) | ~/.gitignore_global |
| 原因の .gitignore ルールを特定 | git check-ignore -v file |
パターン1: 新規ファイルを追跡対象から外す(.gitignore)
まだ git add していないファイルなら、リポジトリのルートに .gitignore を作って書くだけです。
# .gitignore の例
# 完全一致
config/secret.php
# 拡張子全部
*.log
*.tmp
# ディレクトリ配下全部
node_modules/
vendor/
storage/logs/
# 例外(除外を打ち消す)
!storage/logs/.gitkeep
# 階層任意
**/dist/
# 行頭の / でルート起点
/.env
パターン2: 既に追跡中のファイルを管理から外す
過去に git add + git commit してしまったファイルは、.gitignore に書いただけでは追跡解除されません。git rm --cached で明示的に追跡解除します。
# 1. .gitignore に追加
echo "config/secret.php" >> .gitignore
# 2. 追跡解除(ワーキングツリーのファイルは残る)
git rm --cached config/secret.php
# 3. .gitignore と削除をコミット
git add .gitignore
git commit -m "stop tracking secret.php"
git push
# ディレクトリ丸ごとの場合
git rm -r --cached storage/logs/
注意: 他のメンバーが pull すると、その人の手元ではファイルが削除されます。秘密情報なら問題ありませんが、共有していたファイルなら別途配布が必要です。
パターン3: 全ファイル再評価で .gitignore を尊重させる
.gitignore を整備したのに「過去に追跡してしまった」ファイルが残っている場合、一気に整理する裏技。
# 全ファイルの追跡を一旦解除(ワーキングツリーは無傷)
git rm -r --cached .
# .gitignore を尊重した状態で再 add
git add .
# 差分を確認
git status
# コミット
git commit -m "honor .gitignore"
パターン4: 追跡継続のまま一時的に無視(skip-worktree)
「config ファイルはリポジトリに置きたいが、自分のローカル変更は push したくない」というケース。代表例は .env.example をコピーした個人設定。
# 推奨: skip-worktree
# → ローカル変更を git が無視。チェックアウト時も上書きされない
git update-index --skip-worktree config/local.php
# 解除
git update-index --no-skip-worktree config/local.php
# 確認(先頭 S が skip-worktree)
git ls-files -v | grep '^S'
# ----------------------------------------------
# 非推奨: assume-unchanged
# → pull で更新されると壊れる、用途が違う
git update-index --assume-unchanged file
| フラグ | 用途 | 用途違いリスク |
|---|---|---|
--skip-worktree | ローカルカスタマイズを保護 | 低(推奨) |
--assume-unchanged | 性能最適化(巨大ファイルの mtime チェック省略) | 高(pull で壊れる) |
パターン5: グローバル無視(自分の全リポジトリ共通)
OS が生成するゴミ(macOS の .DS_Store、Windows の Thumbs.db、エディタの .vscode/ 等)は個人の ~/.gitignore_global に書くのが定石。チームの .gitignore に入れるべきではありません。
# 設定
git config --global core.excludesfile ~/.gitignore_global
# ~/.gitignore_global の例
cat > ~/.gitignore_global <<'EOF'
.DS_Store
Thumbs.db
.idea/
.vscode/
*.swp
*~
.envrc
EOF
原因調査: なぜ無視されている / されていないのか
# どのルールがマッチしているか
git check-ignore -v path/to/file
# 出力例:
# .gitignore:3:*.log src/app.log
# → .gitignore 3行目の *.log が効いている
# 全ファイルの ignore 判定
git ls-files --others --ignored --exclude-standard
# 追跡中のファイルは ignore ルールでは弾かれない
# → 必ず git rm --cached を併用
関連: git stash / git clean
# 未コミット変更を一時退避
git stash
git stash pop # 戻す
git stash list
# 追跡されていないファイルを削除(危険・確認後に実行)
git clean -n # ドライラン
git clean -fd # 削除実行
git clean -fdx # .gitignore 対象も含めて削除(最強)
本番運用の注意
- 秘密情報を一度コミットしたら .gitignore だけでは不十分。push 済なら漏洩したと扱い、認証情報をローテーション
- 履歴からも消すには
git filter-repo推奨(旧filter-branchは非推奨) - パブリックリポジトリへ commit してしまった場合 → 即時キー無効化 → 履歴改変 → force push
.env/id_rsa/credentials.jsonは必ず最初から .gitignore
FAQ
Q: .gitignore に書いたのに無視されない
A: 既に追跡されているからです。git rm --cached で追跡解除してください。
Q: 一度 push した秘密情報を消したい
A: git filter-repo --path secret.txt --invert-paths → force push。ただしその秘密情報は流出した扱いでローテーションを。
Q: ディレクトリだけ追跡したくない(中身も)
A: logs/ のように末尾 / を付けます。中身を残したいなら logs/* + !logs/.gitkeep。