はじめに

機密情報など外部に流出させてはいけない情報を誤ってGitHubにコミットしてしまったことはありますか?
修正しても、Git履歴には機密情報が残ってしまいますよね。
今回は履歴まで完全に消したかったのでやってみました。

やりたいこと

  • 最新コミットではないコミットに含まれる機密情報を消したい
  • 具体的には、数年前にSlack Webhook URLを間違えてあげてしまっていたので削除し新規コミットにて修正したが、履歴には残ってしまっているので履歴からも完全に消したい

作業条件

  • 複数人でリポジトリを操作している
  • リポジトリの削除はしたくない
  • 機密情報を含むファイルのまるごと削除もしたくない

使用ツール

GitHub推奨ツールの「git-filter-repo」
https://github.com/newren/git-filter-repo

手順

Git履歴にある特定の文字列を、別の文字列に一括置換できるようなのでやってみました。
GitGuardianのページを参考にして進めました。
https://blog.gitguardian.com/rewriting-git-history-cheatsheet/

準備

履歴を操作するのが不安だったので、事前にリポジトリをミラーしてバックアップを作成しておきました(プルリクやイシューはミラーされないので注意)
https://docs.github.com/ja/repositories/creating-and-managing-repositories/duplicating-a-repository

git-filter-repoをインストール(mac)

brew install git-filter-repo

対象のリポジトリをclone

安全のために新規でのcloneが推奨されていました

git clone {url}

リモートリポジトリの情報を全てpull

git pull --all --tags

「replacements.txt」に置換したい文字列と置換後の文字列を記載

今回はreplacements.txtファイルをリポジトリフォルダの1階層上に配置しました
「置換したい文字列==>置換する文字列」 の形式で記載。(文字列はクォーテーションで括ってません)

https://hooks.slack.com/services/{secret...}/{secret...}/{secret...}==>xxx

コミット履歴の書き換えを実行

ワーニングが出たので--forceをつけて実行

git filter-repo --replace-text ../replacements.txt --force

リモードブランチの再設定

安全のためリモードブランチの情報がクリアされるようなので再設定する

git remote add origin {url}
git remote -v # 確認

リモードブランチへコミット履歴の書き換えを反映

git push --all --force && git push --tags --force

コミット履歴画面を確認し、機密情報がxxxに書き換えられていることを確認できました!

複数人で作業されている場合は以下に注意

  • 書き換え作業をする前に各メンバーのローカルでの変更があればリモートへあげておいてもらう
  • 書き換え作業の後は各メンバーに変更を取り込んでもらうよう連絡する

おわりに

  • コミット履歴の書き換えなので、取り扱いには注意
  • コミット履歴を書き換えず、機密情報をローテーションしてもよい