Git 瘦身代码库,永久删除大文件

问题

在我们日常使用Git的时候,一般比较小的项目,我们可能不会注意到.git 这个文件。
其实, .git文件主要用来记录每次提交的变动,当我们的项目越来越大的时候,我们发现 .git文件越来越大。尤其当你不小心上传了某个大文件或者某批大文件时,这些文件将会随着代码的提交一直赖着,占用巨大的空间。

这个帖子就帮你解决git代码库瘦身,更好的管理你的工程。

找到大文件

git给了命令用于遍历idx文件(.git下的pack包),我们使用它寻找历史大文件

git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5

其中pack-*.idx表示你的.git/objects/pack目录下“pack”开头的idx文件。
这句话的意思使用git verify-pack指令打印的文件信息,按第三列升序排序后,选择最后的5条数据,实行结果一般这个样子:
在这里插入图片描述
其中,红框的地方就是文件的大小了,单位是字节。可以看到最后一条记录文件大约有120M,如何确切的知道这个文件名称路径呢,可以用下面的命令查找,注意ID改成上图中查到的id列表内容:

git rev-list --objects --all | grep ID

找到确切的文件后,如果想梳理该文件前因后果,可以使用下面命令找到该文件所在的所有历史记录,假设以tagInterface/test.txt为例:

git log --pretty=oneline --branches -- tagInterface/test.txt

如果想要知道这条commit id所在的分支,可以使用以下命令

git branch -a --contains <COMMIT ID>

删除大文件

当我们查到一个大文件想要从历史上彻底删除它的时候,执行以下命令,其中假设tagInterface/test.txt是我们需要删除的文件。

git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch tagInterface/test.txt' --prune-empty --tag-name-filter cat -- --all

filter-branch命令可以用来重写Git仓库中的提交
-rf命令表示如果想要删除的是文件夹,将会强制并迭代查找文件夹下所有文件并删除。
--index-filter参数用来指定一条Bash命令,然后Git会检出(checkout)所有的提交, 执行该命令,然后重新提交。
–all参数表示我们需要重写所有分支(或引用)。

成功删除的话,结果看起来像这样,如果显示 xxxxx unchanged, 说明repo里没有找到该文件, 请检查路径和文件名是否正确,重复上面的脚本,把所有你想删除的文件都删掉。
在这里插入图片描述

清理和回收空间

虽然上面我们已经删除了文件, 但是我们的repo里面仍然保留了这些objects, 等待垃圾回收(GC), 所以我们要用命令彻底清除它, 并收回空间.

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

推送到远程服务器

这里需要注意, 由于某个文件的改动可能影响了多个分支,推送时需要保证将本地修改的相关分支都推送到服务器,才能使服务器端的代码库完全瘦身。
所以刚从服务器拉取得一般只有一个分支,其它都在远程上,保证本地关联远程所有分支,才开始强制推送。

git push origin master --force --all

--all代表推送所有分支。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值