在使用Git的过程中,常常会出现不小心commit了没用作用的大文件,导致无法push到远程的情况,并且即使删除了该文件重新commit,该文件也已经保存在历史commit中,仍然无法push到远程,此时可以通过如下步骤在历史commit中删除该误提交的大文件。
1、找出需要删除的大文件
通过如下命令找到git中保存的大小排名前5的大文件
git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5
如果执行该命令后报如下错误
fatal: Cannot open existing pack file '.git/objects/pack/pack-*.idx'
.git/objects/pack/pack-*.pack: bad
请先执行git gc --prune=now
。在执行git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5
后可以得到如下信息
3398205a67d1b767d2a23a532fbc1a90f075d68d blob 2975408 71431 31225931
1d0341c489f2bed3a60d3685a1c21a60065aba0e blob 6492176 1433463 28798927
18dc87a4a4e28763e5d93b7752532c1ff6e62d64 blob 10213408 2288984 26251380
5f938c203fb1342ef856f53f2b223907c909c590 blob 13312128 4487050 21764293
2c536772b7e4571c800b85cea4f00d7750b2c950 blob 120897206 11760164 253527
最后一条就是最大的文件记录,2c536772b7e4571c800b85cea4f00d7750b2c950是其id,通过如下命令找到该文件的位置
git rev-list --objects --all | grep 2c536772b7e4571c800b85cea4f00d7750b2c950
可以得到如下结果
2c536772b7e4571c800b85cea4f00d7750b2c950 logtest.txt
logtest.txt
即为文件的位置,一般情况下这里的文件位置应该为文件夹/文件夹/文件的格式,例如4cc1f9dcef1004355d2a595d45808e99f100dc4d app/src/main/assets/Android群英传.pdf
,只不过笔者这里凑巧大文件就在根目录下
2、将大文件从历史commit中删除
git log --pretty=oneline --branches -- logtest.txt
3、重写所有commit
git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch logtest.txt' --tag-name-filter cat -- --all
4、收尾
到这里,历史记录中已经没有该文件了。不过运行 filter-branch 产生的日志还是会对该文件有引用,所以还需要运行以下几条命令,把该文件的引用完全删除:
rm -Rf .git/refs/original
rm -Rf .git/logs/
git gc
git prune
5、push
git push --force