Git

Gitに反映した秘匿情報を履歴からも消す(ファイルごと)

Gitに間違えてsecretKeyやパスワードなどの秘匿情報をコミットしてしまった場合の対応です。

特定のコミットを削除したり、状況により方法は色々ありますが
ここでは汎用性の高い「特定のファイルを全ての履歴からも抹消する」という手段を紹介します。

コマンドは下記です。
path/to/secret_fileのところを該当するファイルへのパスに変更してください。
※該当ファイルの一部いらないだけで他は必要、という場合はバックアップをとっておき修正したファイルを新たにコミットしましょう。

$ git filter-branch --force --index-filter "git rm --cached --ignore-unmatch path/to/secret_file" --prune-empty --tag-name-filter cat -- --all
$ git push origin --force --all

解説

git filter-branch コマンドは、リポジトリのすべてのコミットを再作成するために使用されます。

上記のコマンドは、次のようになっています。

  • --force: 強制的に実行します。
  • --index-filter: インデックスに対してフィルターを適用します。
    ここでは、git rm --cached --ignore-unmatch path/to/secret_file コマンドを使用して、特定のファイルを削除します。
  • --prune-empty: 空のコミットを削除します。指定のファイルを削除することで中身がなくなったコミットを消します。
  • --tag-name-filter cat: タグを変更しません。タグを一定の規則で自動的に書き換えるコマンドですが、catを指定することで変更しないというドキュメントでも案内されている定型文です。
  • -- --all: リポジトリのすべてのブランチを対象にします。

このコマンドは、リポジトリのすべてのコミットを再作成し、指定されたファイルを除外することにより、秘匿情報を削除します。

コマンドを実行すると、書き換えられたコミットや、どのブランチは変更されてどのブランチは変更がなかったかの処理情報が出ます。

最後に git push origin --force --all コマンドを実行し、リモートリポジトリに変更を反映します。

確認

これでリモートから削除されますが、実は作業前にすでにクローンしてきたリポジトリには残っています
存在しなくなったcommitへcheckoutしたり、該当箇所の変更があるコミットをgit log -p {commit id} すると見れてしまいます。

一番簡単な確認は、新たにgit cloneして落としてくることです。
そのリポジトリ内では先程は確認できたファイルの変更コミットや存在が確認できなくなっています。

リモートからの削除はできているのでひとまずは目標達成ですが、
既に落としていた人たちの分は元々みれていたのでOKとするか、
どうしてもであれば各自、一度削除して再度cloneしてもらいましょう。

-Git