見出し画像

Git の履歴から機密ファイルを完全に削除する方法

🎯 目的

Git / GitHub の すべての履歴(過去 commit 含む) から、
パスワードや API Key が含まれていたファイルを 完全に削除 する。

例:

  • `config.php`

  • `.env`

  • 秘密鍵(`.pem`, `.key`)


なぜ「削除して commit」だけでは不十分か?

git rm config.php
git commit -m "remove config"

❌ これは 現在の状態から削除しただけ
❌ 過去の commit にはファイルが残り続ける
❌ GitHub の履歴から閲覧可能

👉 履歴を書き換える(rewrite history)必要がある


使用するツール

  • git filter-repo(公式推奨)

  • ❌ git filter-branch(非推奨・遅い)


🔐 推奨される安全な手順(完全版)

① mirror clone でリポジトリを取得

git clone --mirror <リポジトリURL> repo-clean.git
cd repo-clean.git

🔎 mirror clone とは?

  • すべての branch / tag / ref を含む

  • bare repository(作業ツリーなし)

  • 履歴操作・移行作業専用


② 履歴から特定ファイルを完全削除

git filter-repo --path "path/to/target-file.php" --invert-paths

例:

git filter-repo --path "config.php" --invert-paths

✔ 過去すべての commit から該当ファイルが消える
✔ Git の履歴そのものが書き換わる


③ remote が未設定の場合は追加

mirror clone では remote が設定されていないことがある。

git remote add origin <リポジトリURL>
git remote -v

④ GitHub に強制 push(⚠️重要)

git push --force --mirror

📌 これにより:

  • GitHub 上の 全履歴・全ブランチ・全タグ が置き換えられる

  • 機密ファイルは履歴上から完全消去


⑤ 新しい作業用リポジトリを取得

cd ..
git clone <リポジトリURL>

⚠️ 古いローカルリポジトリは使用しないこと


よくあるエラーと原因

❌ `git: 'filter-repo' is not a git command`

→ git-filter-repo が未インストール

pip install git-filter-repo

❌ `Refusing to destructively overwrite repo history`

→ fresh clone ではない
→ mirror clone を使う


❌ `No configured push destination`

→ remote が未設定

git remote add origin <URL>

作業後の必須チェックリスト ✅

  • [ ] GitHub の履歴検索で該当ファイルが見つからない

  • [ ] 旧パスワード / API Key を 必ず無効化

  • [ ] 新しい秘密情報は Repository Secrets に保存

  • [ ] `.gitignore` に機密ファイルを追加

  • [ ] チームメンバーに 再 clone 必須 と共有


推奨 `.gitignore` 設定

.env
config.php
*.key
*.pem
*.secret

🧠 覚え方(エンジニア向け一行まとめ)

通常開発は clone、履歴削除は mirror
機密情報削除 = mirror + filter-repo + force push


⚠️ セキュリティ上の注意

  • 履歴から削除しても

    • fork

    • 他人のローカル clone
      には残る可能性がある

  • 必ず秘密情報はローテーション(再発行)すること

いいなと思ったら応援しよう!