[Git]うっかりコミットしてしまった余分なファイルを.gitから削除する方法

   2018/02/04

自動生成ファイルとかを.gitignoreで無視するの忘れて、全部いっしょくたにcommitしちゃうこと、あるよね~。

後になって.gitがめちゃデカくなって後悔する事、あるよね~。

って事で、.gitを軽量化する方法。

バックアップを取る

リポジトリの履歴を書き換える作業になるので、何かあったら大変。
リポジトリのコピーを丸々とっておくとかしてバックアップを取っておく。

.git/objectsのサイズを調べる

サイズを調べておく。

$ du -sh .git/objects

.gitの中で大きいファイルを調べる

このサイトのスクリプトをダウンロード。スクリプトの中身は以下の通り。

#!/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のなかでどのファイルが大きいか調べてくれる。

$ git gc --auto
$ chmod 777 git_find_big.sh
$ ./git_find_big.sh
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を見ながら指定。

#!/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

そしたら実行。

$ ./git_delete_files.sh

終わったら、リモートリポジトリに強制的にプッシュ。

$ git push origin --all --force

そして、ローカルの.gitリポジトリのサイズを削減(今までの操作による悪影響がない事を確認してから実行する事!)。

$ 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に上書きしてしまってもよい。

 

タイトルとURLをコピーしました

この記事へのコメントはこちら

メールアドレスは公開されませんのでご安心ください。
また、* が付いている欄は必須項目となりますので、必ずご記入をお願いします。

内容に問題なければ、下記の「コメント送信」ボタンを押してください。

5 × 2 =

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください