提交大文件导致.git/objects/pack目录很大解决办法

之前有同学不小心把编译后的二进制文件提交了,后面虽然已经删除,并把这些文件永久加入.gitignore文件,但是发现项目目录还是很大,du 之后发现,主要是 .git/objects/pack/目录比较大,记录下原因及解决办法

原因

提交大文件到git仓库后,它会被一直跟踪,虽然后续做了删除操作,但是历史记录仍然在,所以即使删除了(并提交)文件,.git目录下历史记录仍然会占有很大的空间

解决办法

感谢以下两篇文章作者

简要记下解决步骤

1、准备工作

  • 先clone一份,作为代码备份
  • 把远端分支都拉到本地(默认在master上),如果分支比较多可用如下脚本来完成
    1
    2
    3
    4
    #!/bin/bash
    for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
    git branch --track ${branch#remotes/origin/} $branch
    done

2、查找大文件列表,并把它写入到文件,可通过改 tail -5 查找前n大的文件,一般来说比较大的都是些编译后的可执行文件,或者log什么的

1
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}'" > large-files.txt

输出的文件里会有n行,格式类似如下

1
2
f846f156d16f74243b67e3dabec58a3128744352 build/bin/cli
……

3、处理一下,只取文件

1
cat large-files.txt| awk '{print $2}' | tr '\n' ' ' > large-files-inline.txt

4、删除所有大文件

1
git filter-branch -f --prune-empty --index-filter "git rm -rf --cached --ignore-unmatch `cat large-files-inline.txt`" --tag-name-filter cat -- --all

5、推到远端

1
git push origin --force --all

6、依次切到所有分支,然后执行上述 3、4 步骤,如果分支比较多,可以考虑写个脚本来自动处理

修改提交历史是个很危险的动作,所以尽量避免提交无用大文件