[Git]うっかりコミットしてしまった余分なファイルを.gitから削除する方法
自動生成ファイルとかを.gitignoreで無視するの忘れて、全部いっしょくたにcommitしちゃうこと、あるよね~。
後になって.gitがめちゃデカくなって後悔する事、あるよね~。
って事で、.gitを軽量化する方法。
バックアップを取る
リポジトリの履歴を書き換える作業になるので、何かあったら大変。
リポジトリのコピーを丸々とっておくとかしてバックアップを取っておく。
.git/objectsのサイズを調べる
サイズを調べておく。
1 | $ du -sh .git/objects |
.gitの中で大きいファイルを調べる
このサイトのスクリプトをダウンロード。スクリプトの中身は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #!/bin/bash #set -x # Shows you the largest objects in your repo's pack file. # Written for osx. # # @see http://stubbisms.wordpress.com/2009/07/10/git-script-to-show-largest-pack-objects-and-trim-your-waist-line/ # @author Antony Stubbs # set the internal field spereator to line break, so that we can iterate easily over the verify-pack output IFS=$'\n'; # list all objects including their size, sort by size, take top 10 objects=`git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain | sort -k3nr | head` echo "All sizes are in kB's. The pack column is the size of the object, compressed, inside the pack file." output="size,pack,SHA,location" for y in $objects do # extract the size in bytes size=$((`echo $y | cut -f 5 -d ' '`/1024)) # extract the compressed size in bytes compressedSize=$((`echo $y | cut -f 6 -d ' '`/1024)) # extract the SHA sha=`echo $y | cut -f 1 -d ' '` # find the objects location in the repository tree other=`git rev-list --all --objects | grep $sha` #lineBreak=`echo -e "\n"` output="${output}\n${size},${compressedSize},${other}" done echo -e $output | column -t -s ', ' |
これを実行すると、.gitのなかでどのファイルが大きいか調べてくれる。
1 2 3 | $ git gc --auto $ chmod 777 git_find_big.sh $ ./git_find_big.sh |
1 2 3 4 5 6 7 8 9 10 11 12 13 | USER-MacBook-Air:workspace user$ ./git_find_big.sh All sizes are in kB's. The pack column is the size of the object, compressed, inside the pack file. size pack SHA location 28036 10111 50646ee98af5fa19a4538a727261cd73304cddeb .metadata/.plugins/org.eclipse.jdt.core/3352301917.index 7054 2191 630a04c4153d31b0b917a52b6eb24514dcbc0f50 .metadata/.plugins/org.eclipse.jdt.core/1940685342.index 4904 828 ba10aebf34fd60bd0cf5b583a3cd7a26265bf602 .recommenders/index/http___download_eclipse_org_recommenders_models_neon_/_2.fdt 4198 865 ecd13c61f37be37a57f64452e4d89ae7fcac5e59 .metadata/.plugins/org.eclipse.jdt.core/2071773772.index 4021 1243 0b4fb63b024e896069e4297d5828a4853a0e33b0 .metadata/.plugins/com.python.pydev.analysis/python_v1_874innp8uovopkka84p4pwnaw/python.pydevsysteminfo 3941 1218 0b692374a3adaa49fa0744bb5ef7d12c99ed743c .metadata/.plugins/com.python.pydev.analysis/python_v1_874innp8uovopkka84p4pwnaw/python.pydevsysteminfo 3883 1198 096c00c9afb87e9fc4f8794862e668ef81acee6e .metadata/.plugins/com.python.pydev.analysis/python_v1_874innp8uovopkka84p4pwnaw/python.pydevsysteminfo 3497 1077 9781c44e0f3721f3b5299dd8a9537e733adc56f5 .metadata/.plugins/com.python.pydev.analysis/python_v1_874innp8uovopkka84p4pwnaw/python.pydevsysteminfo 2878 856 5d4b2620c4d6572690ab4ce341e7d29827f3a302 .metadata/.plugins/com.python.pydev.analysis/python_v1_bm109oo8jsa5gnqmc06ekl12p/python.pydevsysteminfo 2873 855 180f6531173e20a51fcc648e80ecf7133379df62 .metadata/.plugins/com.python.pydev.analysis/python_v1_bm109oo8jsa5gnqmc06ekl12p/python.pydevsysteminfo |
これをもとに.gitignoreを書く。
.gitリポジトリから削除
以下のようなスクリプトを書く。
TARGETSの中は、削除したいファイルを指定。
.gitignoreと同じような感じで指定できるので、.gitignoreを見ながら指定。
1 2 3 4 5 6 7 8 9 10 11 | #!/bin/bash # 指定方法は.gitignoreと似てる TARGETS=( "log_folder/" "log.dvi" "*.log" ) target=$(printf " %s" "${TARGETS[@]}") target=${target:1} # 履歴の抹消 git filter-branch --index-filter "git rm -r --cached --ignore-unmatch ${target}" -- --all |
そしたら実行。
1 | $ ./git_delete_files.sh |
終わったら、リモートリポジトリに強制的にプッシュ。
1 | $ git push origin --all --force |
そして、ローカルの.gitリポジトリのサイズを削減(今までの操作による悪影響がない事を確認してから実行する事!)。
1 2 3 | $ git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin $ git reflog expire --expire=now --all $ git gc --prune=now |
効果を確認して完了
もう一度duやgit_find_big.shを実行して、サイズが小さくなっていたら軽量化完了。
場合によってはまだ小さくなってない事もあるけど、この時点でリモートリポジトリの.gitのサイズは小さくなっているので、.gitフォルダだけリモートからダウンロードして、ローカルの.gitに上書きしてしまってもよい。
この記事へのコメントはこちら