最近,因为Github上某仓库的体积过大(主要是图片文件太多,超越300M),克隆或下载时等候时间很长,因此按照网上经验和教程帮助,完成了以下瘦身计划:
首先对仓库安装 git lfs 大文件管理插件。安装过程不复杂,下载个 Binary包(我下载的是 git-lfs-linux-amd64-v2.9.0.tar.gz ) 解压后进入目录运行
sudo ./install.sh
即可。进入仓库目录,运行
git lfs install
,以及其后配置lfs时,出现权限问题。最后一气之下改了整个项目目录下 .git 目录的用户读写权限,问题基本解决。祥见另一备忘录 《 Deepin 系统下安装 git lfs 后总是提示“权限不足”或“Permission Denied”信息 》完成lfs配置后,解决仓库体积过大的问题。主要思路就是把之前git提交历史缓存中的图片文件全部删除(因为图片已转由git lfs保存管理),这个过程具有颇大风险。切记做好备份,以策安全!
Git仓库瘦身具体流程
- 备份!备份!备份!
把仓库内涉及操作(最好是整个仓库目录下)的全部文件另行备份一份,在我的项目中主要是 dist/imgs/ 目录下(含子目录)的所有jpg图片文件,因此我将 dist/imgs/ 整个目录另行拷贝了一份。
按照网上学习所得,检查 git cache 中占用空间最多的文件:
git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5
最后的数字表示按排序显示多少个文件(我这里显示的是5个),这一步无任何风险。
根据文件哈希值获知文件名:
git rev-list --objects --all | grep 5bbc7c38d88a6643faf2c83dde12d03e5256a7f3
这一步只是显示个文件名而已,也无任何风险。
以上两步截图:
经过检查,果然占用体积大的都是imgs目录下的图片文件,和我猜测的相近,因此继续下一步。
- 仓库瘦身,删除仓库中占用体积较大的文件
警告:运行以下命令会将git cache和仓库中目前存在的文件都会删除,再次提醒备份的重要性!
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch dist/imgs/*/*.jpg" --prune-empty --tag-name-filter cat -- --all
这一点和网上经验教程不同,我的仓库情况不是一个大文件的问题,而是过多图片文件导致的体积过大,因此我使用了通配符 dist/imgs//.jpg 来匹配 imgs 目录下的所有图片文件。(实际想法是,先把这些图片文件删掉再说,然后重新添加,这样重新添加的文件就都交由lfs管理了,而且 .git 目录也能够有效减少体积)
运行后,如同所料,imgs 目录下的所有图片文件(包括git cache中相应文件)全部被删除。
强推回Github远程仓库
git push origin --force --all # 强推git全部对象(不含标签)
git push origin --force --tags # 强推标签
这步做完后基本就把体积降下来了,而且重设了HEAD为当前最新。
Git仓库的压缩清理
git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now
包括清理无效引用、设置过期标记、压缩仓库体积。
最后检查一下仓库概况
git count-objects -v
以上一切正常后,把涉及操作的备份文件重新放回原位,再次 Commit 更新。在我本次实践中,只需把预先备份 的 dist/imgs/ 下的所有目录和图片文件重新拷贝回项目的原始位置,然后做一次
git commit
和git push
操作即完成任务了。
实践结果
瘦身前:
- 原仓库Github上显示占用体积为 370M ,也就是说每次采用 git clone 或下载仓库时要下载 370M 的文件内容。
瘦身后(采用 git lfs 管理图片文件,并按以上步骤仓库操作完成):
- 目前克隆
git clone
或下载该仓库压缩文件(只有代码,不含图片)只有2M左右大小,Github显示仓库占用体积减少为 100M 出头,另外查询Github的 Setting / Billing 时,目前 Git LFS Data 显示占用 0.3G (免费额度共1G)。
结论
本次实践,基本实现计划目的。
BTW:
安装了 git lfs 大文件管理的项目,如需要完整克隆整个项目内容(含被lfs管理的文件),只需把 git clone https://.../xxx.git
替换成 git lfs clone https://.../xxx.git
即可。