git で過去のコミットから大きいファイルを探して削除する方法
概要
一度でも間違って大きいファイルを push してしまうと履歴に永遠に残るためその先のコミットで削除してもリポジトリのサイズは小さくなりません
過去の履歴から大きいファイルを削除し force push する方法を紹介します
環境
準備
numfmt コマンドを使えるようにします
大きいファイルの発見
git rev-list --objects --all --missing=print |
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' |
sed -n 's/^blob //p' |
sort --numeric-sort --key=2 |
cut -c 1-12,41- |
$(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest
結果は以下のような感じでコミットハッシュ+ファイルサイズ+ファイル名で表示されます
大きいファイルは対象のコミットハッシュにあることがわかります
c31cede47e3e 741KiB libs/android-support-v4.jar
4ebdaa9ed9f3 972KiB libs/android-support-v4.jar
65adb523789c 6.4MiB app/release/app-release.aab
293e76491255 6.9MiB app/release/app-release.aab
5ffdd4c8a823 8.7MiB cert/pepk.jar
e0b9d9b10a81 602MiB java_pid4972.hprof
対象のファイルの削除
対象のリビジョンをチェックアウトし削除して force push でもいいですがそれ以降のリビジョンにも含まれるのですべてのリビジョンに対して書き換えるのが簡単です
先ほど見つけた大きいファイル名のパスを指定して上記を実行しましょう
BFG も実行する
docker run -it --rm \
--volume "$PWD:/home/bfg/workspace" \
koenrh/bfg \
--strip-blobs-bigger-than 100M
filter-branch だと削除できないケースがあったので一応 BFG というツールも実行します
もしかするとこれだけでもいいかもです
BFG はファイル名ではなくファイルサイズで指定するので注意しましょう
gc
pack ファイルなどを削除します
force push
履歴を改変したので force push します
- git push -f origin master
リビジョンが変わっていない場合は git commit --amend
などでコメントを変えるなり reset してリビジョンを変更してから force push しましょう
履歴から大きいファイルが削除されていることの確認
先程の確認コマンドを再度実行して大きいファイルが含まれないことを確認しましょう
また以下のコマンドでリポジトリのサイズを確認しましょう
それでもリモート側のサイズが小さくならない場合は
一度リモート側を削除して再度作成し push してみましょう
これでリモート側のリポジトリサイズも小さくなるはずです
ローカル側にもリモート側にも .git ファイルのキャッシュが残っておりこのサイズが大きいとリモート側も大きくなってしまいます
ローカルで小さくできたのを確認できたらリモート側のキャッシュも削除するためにリポジトリを再作成してみましょう
最後に
無料のプライベートリポジトリは大抵の場合ファイルサイズに上限があるので大きいファイルはプッシュしないようにしましょう
参考サイト