由于git是分布式版本控制工具,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库,可以离线工作而不依赖于中央仓库的特性,造成了这么一种现象:随着项目年龄的增长,项目在经历很多提交之后,.git文件会越来越大。尤其是当管理提交做大的文件时候(可能不小心提交上去了项目打好的war包、jar包、音频视频等),哪怕大文件后续已经被清理,但是git为了保证我们能随时能还原历史,依旧在日志中保存这些大文件的二进制流,加重.git负担。
本文模拟一位小伙伴,不小心提交了大文件(jar包)到仓库,后发现后亡羊补牢,删除并瘦身git的过程
我们有一个项目,test_git
项目初始大小只有180K
小伙伴提交失误,将jar包提交上去了。这里加入模拟大文件jar(8.5M),此时整个项目占用空间为8.6M
小伙伴一顿操作,git add,git commit,提交完毕,查看大小,此时占用空间达到了16M(文件本身有8M,提交记录的二进制流8M)
呀,不对劲,多提交了jar包,删除删除!!(删除了项目中的jar包)然后提交后,查看此时占用空间,依旧还有7.7M的空间占用(文件虽然删除了,但是git日志中依旧保存着)
可以想象一下,本来几百K文件,好端端的多了几M,甚至可能是几十几百M,将严重影响公司小伙伴同步公司中央仓库的效率。赶紧给git瘦个身吧
瘦身有很多种,这里使用比较简单且好用的工具bfg
,首先下载jar包(详细使用和下载见文底备注)。
使用如下命令查询改项目历史中高于1M的历史记录
(--strip-blobs-bigger-than可以简化为-b)
java -jar bfg-1.13.0.jar --strip-blobs-bigger-than 1M test_git
注意默认情况下。bfg是默认保护上次提交,所以上述命令查询结果并不包含上次提交。
结果:
查到一个8.5M的BigFile.jar
跟进实际情况,删除大文件。这里演示删除 *.jar
java -jar bfg-1.13.0.jar --delete-files "*.jar" --no-blob-protection test_git
上述命令的参数--no-blob-protection表明忽略保护
执行完后,进入项目目录,执行日志瘦身命令
git reflog expire --expire=now --all && git gc --prune=now --aggressive
查看当前空间占用,回到了188K,瞬间感觉很清爽了
瘦身有风险,使用请注意:
这种搜身方式只是在瘦身本地项目中的历史,瘦身完毕可使用
git push -f
强制刷新瘦身版本到中央仓库。但是由于别的小伙伴本地的历史中依旧为未瘦身的文件,建议瘦身工作前,先让所有小伙伴提交所有代码,然后瘦身完毕后,重新clone新的项目