在使用Git时偶尔会有小伙伴提交一些错误的大文件到版本控制,等到发现用git rm 删除掉那个文件。但这样做是不够的,这些文件之后并没有真正在项目中被用到,与此同时这些大文件的存在会导致整个 git 仓库的容量暴增,影响每次 clone 和 fork 代码仓库的时间。文件还一直存在历史log中,需要重写历史后执行清理后才能彻底清除。
- git verify-pack 命令查看 pack 文件包的相关详细信息,通过文件大小进行排序,这里只列出5个最大的文件。
git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5
output
988821841808f2a04123b4a16c88912bb04e3cfa blob 31157 14012 747972
2c958c8b8521738c76269812c280b20a08b7b0fc blob 31170 8443 306412
9108ebc4238d195101622febd15ecafc93ccc18e blob 31714 14196 728479
2d842e61422a013354e7865f946dad1058bce5a1 blob 32110 14395 575722
777e8697e5dc1017ca901c8cf226d707b6e96b06 blob 62678 22645 248106
- git rev-list 列出该对象文件名等更多信息
git rev-list --objects --all | grep 777e8697e5dc1017ca901c8cf226d707b6e96b06
output
777e8697e5dc1017ca901c8cf226d707b6e96b06 go.sum
以上两步可以全并成一条命令,方便快速查询。
git rev-list --objects --all |grep $(git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -1|awk '{print $1}')
在日志中查找这个文件
git log --pretty=oneline --branches -- go.sum
filter-branch 修改提交历史的命令
–tree-filter表示修改文件列表。 –msg-filter表示修改提交信息,原提交信息从标准输入读入,新提交信息输出到标准输出。 –prune-empty表示如果修改后的提交为空则扔掉不要。在一次试运行中我发现虽然文件被删除了,但是还剩下个空的提交,就查了下 man 文档,找到了这个选项。 -f是忽略备份。不加这个选项第二次运行这个命令时会出错,意思是 git 上次做了备份,现在再要运行的话得处理掉上次的备份。 –all是针对所有的分支。
git filter-branch --index-filter 'git rm --cached --ignore-unmatch go.sum -- --all
到这里,历史记录中已经没有该文件了。不过运行 filter-branch 产生的日志还是会对该文件有引用,所以还需要运行以下几条命令,把该文件的引用完全删除:
rm -Rf .git/refs/original
rm -Rf .git/logs/
git gc
git prune
查看.git目录,已经小了很多了
du -sh .git
强制 push
git push --force
需要注意把涉及重写后的分支全部强制推送到远程共享库。同步提醒其他小伙伴重新clone 代码仓库,否则其他人提交就前功尽弃了。
云效代码仓库删除大文件 官网git-filter-branch
filter-branch 常用功能 修改提交用户名
git filter-branch -f --env-filter "GIT_AUTHOR_NAME=xxx" -- --all
修改提交邮箱
git filter-branch -f --env-filter "GIT_AUTHOR_EMAIL=xxx@xxx.com" -- --all
|