こんにちは寝る

古い記事の情報は参考程度にお願いします

git-filter-repoを利用してGitからファイルを履歴も合わせて削除する

概要

Gitに既にコミットしてプッシュしたデータの中に機密性が高いデータが存在したときに
そのデータの削除コミットをプッシュしただけでは削除されたことにならない。

ここでは git-filter-repo を利用したデータの削除について解説します。

github.com

削除された事にならない理由

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でのインストール方法を記載します。

github.com

1. 注意点

WindowsPythonの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.ps1python を書き換える。

おそらく 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 はプッシュする時にリモートに新しいコミットがあったときに強制プッシュを止める事ができる。ただ履歴の改変をした場合はしっかり動くか不明なのでそもそも誰も操作しないブランチで作業を行うべきです。