git-filter-repoを利用してGitからファイルを履歴も合わせて削除する
概要
Gitに既にコミットしてプッシュしたデータの中に機密性が高いデータが存在したときに
そのデータの削除コミットをプッシュしただけでは削除されたことにならない。
ここでは git-filter-repo
を利用したデータの削除について解説します。
削除された事にならない理由
Gitは変更履歴を管理するツールなので、削除しても『機密性が高いデータをこの時点で消したよ』という履歴が残るだけでデータ自体は見れなくなるが過去の履歴に『機密性が高いデータが追加されたよ』が残っている限りこの機密性が高いデータは変更履歴を追うことで中身をすべて確認する事ができる。
要は履歴の積み重ねがGitの本質の為、過去に戻って確認できる限りデータは存在する。
ではどうするのか?
git-filter-repo
を利用して機密性の高いデータを全ての履歴から削除する。
履歴から対象データを削除する事で過去に戻っても対象データが存在しないので
結果的にGit管理上から完全削除される。
以前の履歴の消し方
以前は git-filter-branch
を利用していたがこちらは非推奨。
動作速度も git-filter-repo
の方が圧倒的に早いので使う理由は特にないです。
WARNING: git-filter-branch has a glut of gotchas generating mangled history rewrites. Hit Ctrl-C before proceeding to abort, then use an alternative filtering tool such as 'git filter-repo' (https://github.com/newren/git-filter-repo/) instead. See the filter-branch manual page for more details; to squelch this warning, set FILTER_BRANCH_SQUELCH_WARNING=1.
git-filter-repoのインストール
インストール方法は以下、ここではWindowsでのインストールしか確認していないのでWindowsでのインストール方法を記載します。
1. 注意点
WindowsはPythonのPathが正しく通らないとかで git-filter-repo
をインストールした後に書き換えが必要になるため、面倒くさいです。
ただ、これは各人の環境にもよると思うので必ずやるとは限らないかなと思います。
またGit(2.24.0以上)は既にインストールされているものとします。
2. Pythonのインストール
以下のURLからPythonをインストール。理由が無ければ最新版で良いと思います
注意点としてインストールするとき Add Python 3.x to PATH にチェックしてインストールしてください。
もちろんインストーラーを用いず scoop などでインストールするのでもOKです。
Python Releases for Windows | Python.org
3. git-filter-repoのインストール
scoop install git-filter-repo
これだけ。
4. git-filter-repoを動かす
git filter-repo -h
を 動かすとおそらくエラーが出てくると思います。エラーがでなければ次へ進んでください。
エラーが出た場合は原因として以下があげられます
python3 の Pathが通っていない(Windowsだとだいたいがこれ)
どうやらWindowsだと python3
とコマンドラインに打ってもPathが通っていないようです
pyhton
または py
を試してどちらならばPathが通っているか確認してください。
どちらも動かない場合はPythonインストール時に Add Python 3.x to PATH にチェックしてインストールしていない可能性があります。
または再起動してから試してください。
動いた場合は以下のファイルの1行目を python
に書き換える
Windowsでのインストール先はおそらくエラーが出たときにPathが表示されるはずなのでそちらを確認してエクスプローラーで開いて編集してください。
git-filter-repo/git-filter-repo at main · newren/git-filter-repo · GitHub
↑をしてもエラーになる場合
git-filter-repo.ps1
の python
を書き換える。
おそらく py
に書き換えれば大丈夫です。
5. git-filter-repoを利用する
【重要】以下の作業から不可逆です一度行うと取り消せません
利用する前に新しくリポジトリをCloneしましょう
履歴の改変をする時は新しくCloneした物を利用して行うべきです。
その後、masterから適当なブランチを作成してそのブランチで事前作業をして動作を確認できた後に本番を行いましょう。
git-filter-repo
のマニュアルはこちら
GitHub & BitBucket HTML Preview
多分これだけ覚えておけばOK
# 特定のファイルを全ての履歴から削除する git filter-repo --path xxx --invert-paths # 例)dir以下を全て削除する git filter-repo --path dir/ --invert-paths # 例)readme.mdを削除する git filter-repo --path readme.md --invert-paths # ちなみに --invert-paths を書かないと『そのファイルだけ残して後は全て消す』になります
6. プッシュする
履歴の改変をしたブランチはリモートリポジトリにあるブランチと確実に違うので強制プッシュ(force push)する必要があります。
git push --force-with-lease ...
※ --force-with-lease
はプッシュする時にリモートに新しいコミットがあったときに強制プッシュを止める事ができる。ただ履歴の改変をした場合はしっかり動くか不明なのでそもそも誰も操作しないブランチで作業を行うべきです。