太坑了。。。Git仓库为什么越来越大

背景

上个月开源了一套低代码平台 marsview ,陆陆续续有一些对低代码感兴趣的兄弟加入,开启了贡献之路,有不少功能都是小伙伴提交的。

然后最近发生一件事儿,小伙伴发现开源仓库越来越大,克隆的时候已经有 200 多 M 了,可是下载仓库包发现只有 4.7M ,这是为什么?

其实,我第一反应就是,.git 记录了历史缓存,但我没想到的是,克隆包居然高达200多M,不能容忍….

问题跟踪

marsview 当前仓库源码其实只有4.7M,究竟是什么原因导致变成了250M,我们也就迭代了一个月左右。

于是,我开始翻找历史提交记录,果不其然,我们在开源后的一周,上线了开发文档,当时,我跟小伙伴录制了几个视频,一开始为了节省 CDN 流量,我把视频文件放到了文档仓库提交到远程了,后来感觉不合理,又选择上传到了百度云,但是视频文件最终是被删除的,没想到变成了历史文件,虽然当前视频文件已经被删除了,但是 git 的历史包里面却被打包进去了。

当前开源项目下载包大小

image.png

历史提交的视频文件记录

image.png

打开项目.git目录查看历史打包文件大小

image.png

所以,我们已经找到根本原因了,只要你历史提交过大文件,那你的代码仓库就会有记录,即使你最后又删除了大文件也没用。

这样带来的影响是什么 ?

最大的影响就是别人克隆你的仓库非常慢,一看250M,直接走了。

解决思路

说实话,这个问题解决起来很棘手,我尝试在网上寻找答案:有说,git reset ,有说,git revert ,也有人说 git rebase

其实仔细想一想,前两个都不太可能,我们是要抹除历史记录,相当于要把曾经提交视频的那一次给它干掉,我尝试了使用git rebase,因为它可以把历史记录进行合并、修改或删除。

使用 git rebase

1. 找到添加视频的那一次提交

image.png

2. 复制版本号,执行rebase

git rebase -i a256f5058c3478ea12244db0a6ccb980825d98bd^

我们加一个^,往前执行一步

image.png

很快就发现了这两次提交记录,我们输入i进入输入模式,把那两次提交前面的pick改成drop,这样最终的提交记录里面就找不到这两次视频的提交。

这个过程中,如果有冲突,就解决一下冲突,直接提交commit,然后继续执行:git rebase --continue,直到把所有冲突解决完,然后强推上去。

3. 强推一下,查看效果

通过git rebase以后,我查看了github提交记录,确实已经找不到这两个视频的提交了,然而我去重新克隆仓库,发现依然是250M,见鬼了,说明通过git reset/revert/rebase这种操作只是处理提交日志,解决不了历史缓存问题。

【这里我当时忘了截图了,查看GitHub已经找不到视频的提交记录了】

git filter-branch

网上介绍说,需要通过git filter-branch来解决历史缓存问题,于是我就照搬了。 幸亏我在执行git rebase之前,把仓库备份了,要不然还挺麻烦。

1. 执行命令

git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch packages/docs/src/pbulic/project.mp4' --tag-name-filter cat -- --all

git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch packages/docs/src/pbulic/editor.mp4' --tag-name-filter cat -- --all

参数解释:

  • filter-branch 是让git重写每一个分支。

  • --force 假如遇到冲突也让git强制执行。

  • --index-filter 选项指定重写的时候应该执行什么命令,要执行的命令紧跟在它的后面,在这里就是git rm --cached --ignore-unmatch password.txt ,让git删除掉缓存的文件,如果有匹配的话。

  • --prune-empty 选项告诉git,如果因为重写导致某些commit变成了空(比如修改的文件全部被删除),那么忽略掉这个commit。

  • --tag-name-filter 表示对每一个tag如何重命名,重命名的命令紧跟在后面,当前的tag名会从标注输入送给后面的命令,用cat就表示保持tag名不变。

  • -- 表示分割符。

执行的时候,它会生成一个重写的.git-rewrite目录,看起来有效果,当时全部执行完以后,发现objects目录大小并没有变化,但objects下面多了很多子目录,看起来是每一次提交的历史日志,然而.pack文件大小始终没有变化。

image.png

image.png

我们最重要的就是要把这个pack文件降下去,否则就是徒劳。

2. 通过gc回收

第一步查找记录,删除日志文件,第二步就是清理,因为历史记录都是打包在.pack文件里面的。

设置过期

git reflog expire --expire=now --all

打包、回收

git gc --aggressive --prune=now

image.png

果然.pack文件变小了,说明前面几步执行是成功的,因为我们视频没有删除完,所有当前还有32M

强推、查看提交记录

  • 继续执行上面的命令,删除所有视频文件。
  • 强制推送代码到远程:git push origin main --force
  • 查看github远程记录

image.png

查看GitHub历史,分析只有代码,没有视频文件了。

总结

随着版本的迭代,仓库大小会越来越大,对于大文件的提交(视频、jar、SDK..)一定要慎重考虑是否提交到仓库,避免不必要的困扰。

如果不小心发生了,跟我一样的情况,就按这个思路解决:

  1. 执行git filter-branch
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch packages/docs/src/pbulic/editor.mp4' --tag-name-filter cat -- --all
  1. 执行git reflog
git reflog expire --expire=now --all
  1. 执行git gc
git gc --aggressive --prune=now

号外

最近低代码强力更新,欢迎大家体验

image.png

image.png

image.png

体验地址: www.marsview.cc/

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=20692,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?