icon [Git]不要ファイル履歴削除 (2019/05/28)
・git clone が重い
・秘密のファイルを Commit してしまった
など、過去にファイルを Commit & Pull してしまった場合、問題ファイルをなかった事にしたい事がある。
「git filter-branch」を利用して履歴を削除する事で解決できるが、破壊的に履歴を書換える為、作業には注意が必要

PHPサンプルスクリプト

destory_git_history.php

オブジェクト容量の大きいファイルを検出

git_find_big.sh で大きなオブジェクトを抽出
$ du -sh .git/objects
12M .git/objects
$ sh git_find_big.sh
「git_find_big.sh」は、gitコマンドを用いて「.git/objects/pack/pack」内の容量の多いオブジェクト順で抽出している

履歴を抹消

抽出したファイルやディレクトリを削除
(refs/heads/master と refs/remotes/origin/master を書き換える。)
※ディレクトリの場合は「git rm -r」
$ git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch ファイルパス' --prune-empty -- --all
Rewrite b270c665ec3e7152d611f57caa0f2288c1b6d4b2 (71/662) (9 seconds passed, remaining 74 predicted)
...
Ref 'refs/heads/master' was rewritten

ガベージコレクションを利用して不要なオブジェクト、ログを削除
$ git gc --aggressive --prune=now
Counting objects: 29352, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (29137/29137), done.
Writing objects: 100% (29352/29352), done.
Total 29352 (delta 25019), reused 4279 (delta 0)

$ git reflog expire --expire=now --all

gitオブジェクトのリパック
$ git repack -A -d
Counting objects: 28584, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3888/3888), done.
Writing objects: 100% (28584/28584), done.
Total 28584 (delta 24481), reused 28577 (delta 24478)

$ du -h .git/objects/pack/*
804K .git/objects/pack/pack-d29fd9436341bc9c424baf3089e4acaf7fb4fa06.idx
11M .git/objects/pack/pack-d29fd9436341bc9c424baf3089e4acaf7fb4fa06.pack

強制的にPush

$ git push --force origin master
Fetching remote heads...
refs/
refs/heads/
refs/tags/
updating 'refs/heads/master'
from a24f9d199d061c9edf46ff60f5b6fc83512c5cfc
to 357aa42bd0903a3f6721c74bbedfbaae994662dc
sending 488 objects
done
共同作業している場合は、clone してもらった方が安全か?