不知不觉项目已经commit了一千多次,项目变成了107M。
是因为在项目的.git\objects\pack*.pack文件里会保留着历史所有提交数据,并不会随着文件的删除而删除该历史提交记录。
久而久之项目会变得越来越大。
最好的办法是删除远程仓库并且删除本地项目下的.git文件夹,然后执行git init之后重新推送到新仓库。
但是这会导致历史commit记录全都被删除了,如果今后想回滚到某一次commit那就没办法了,公司也不允许这样操作。
于是本小菜也来学习下优化git仓库大小。
在git bash窗口执行下面这段命令会依次对历史提交中的文件大小进行排序
git rev-list --objects --all \ | 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
通过对历史提交进行排序可以看到大部分都是因为这两个文件夹里面的文件导致项目变大。
report/app/public/pdf/ 和 report/app/publish/font/
要删除大文件先要判断文件是否可以被删除。
转到目录report/app/public/pdf/ 和 report/app/publish/font/ 下面发现文件已经被删除。
证明历史提交中所有关于这两个文件夹下面的文件引用都可以被删除。
该命令仅仅只是移除commit中对某文件的引用,如果某次commit同时提交了要删除的文件和要保留的文件,该命令只会移除要删除文件的引用,并不会移除要保留的文件和当次commit记录,所以无需担心会把不该删除的文件删掉了。
单独移除某个文件的引用
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch 文件路径/文件名' --tag-name-filter cat -- --all
移除某个文件夹下所有文件的引用,我想要移除report/app/public/pdf/文件夹下面所有文件的引用,所以我写的report/app/public/pdf/*.*
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch report/app/public/pdf/*.*' --tag-name-filter cat -- --all
开始执行命令
命令执行完成
移除继续移除report/app/public/font/文件夹下面所有文件的引用
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch report/app/public/font/*.*' --tag-name-filter cat -- --all
rm -rf .git/refs/original/
设置所有未关联对象过期时间为现在,默认为90天。
目的是放弃所有未关联对象恢复的可能性,因为reflog 是找寻它们踪迹的最后途径了。
git reflog expire --expire=now --all
执行完成后此命令后.git\objects\pack目录下会生成新的打包文件,垃圾文件会保留在pack的上层目录
git repack -A -d
执行完成此命令后,会把刚才repack的垃圾文件进行删除,此时再看仓库大小已经明显被优化了。
git gc --aggressive --prune=now
git push --force
还需要告诉一起开发的小伙伴,让他们全部以clone的方式重新拉取代码再做修改提交。
如果有人从优化前的代码进行修改commit,那么上面所有操作都是无用功。