Git 删除已提交的大文件
在使用 git 管理代码仓库的时候,有可能不小心提交了一些大文件,虽然后来从工作区删除了,但是已经于事无补,大文件的历史记录仍然保存在 git 仓库里。以下提供了基于文件大小排序的 Git 仓库文件搜索和删除方法。
查找大文件
在 Git 仓库目录下执行命令对归档的文件进行排序,并给出文件大小前 5 的文件 ID 等信息:
1 | git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5 |
输出结果如下,依次是文件 ID、文件类型、文件字节数、size-in-packfil
和 offset-in-packfile
:
1 | 10eaa37e6e1999cf5652e9b4c6b3ca5fa43a90b1 blob 14873202 11312961 77109113 |
根据文件的 ID(SHA1),查找文件路径:
1 | git rev-list --objects --all | grep <targrt_file_ID> |
示例输入如下:
1 | git rev-list --objects --all | grep 66e27e2c0159a8439a744d57f058d63dbe192e95 |
输出结果如下,以此是文件 ID 和文件路径:
1 | 66e27e2c0159a8439a744d57f058d63dbe192e95 projects/duifei/duifei_online_acq_par/duifei_online_acq_par_20230511.xpr.zip |
将要删除的大文件从各个分支中移除
执行下面命令,将文件从分支的提交中移除
1 | git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch <target_file_path>' --prune-empty --tag-name-filter cat -- --all |
示例输入如下:
1 | git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch projects/duifei/duifei_online_acq_par/duifei_online_acq_par_20230511.xpr.zip' --prune-empty --tag-name-filter cat -- --all |
示例输出如下:
1 | WARNING: git-filter-branch has a glut of gotchas generating mangled history |
删除缓存下来的 ref 和 git 操作记录
1 | git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin |
垃圾回收
上面 2 步把大文件的索引都切断了,这个时候进行垃圾回收,就可以很明显看到效果。
1 | git gc --prune=now |
这时候的仓库中的大文件就已经被删除了,把仓库推送到新的远程仓库或者强制推送到现在的远程仓库都是可以的。
1 | git push --force |