参考html
https://harttle.land/2016/03/22/purge-large-files-in-gitrepo.htmlgit
https://git-scm.com/docs/git-rev-listpost
https://git-scm.com/docs/git-filter-branchspa
https://git-scm.com/docs/git-verify-pack3d
该文章是本身操做时查找资料的实践内容,内容彻底来自上面的做者。code
开发久了,有一些很老的东西,好比一开始没有拆分后来拆分到别的仓库的代码,编译的一些类库,或是后面删除掉的无用的模块,放在仓库中,每次clone,都很是大,能够经过git的一些方法查找,而且从仓库中删除。htm
这是个很危险的动做,有可能会丢失数据,因此操做以前最好备份或是确保删除的不是关键信息。由于作了这个操做这些东西会永远从你的git仓库中删除,而且再也找不到任何信息,没法还原,全部的历史信息都会被重写。blog
git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch <file>' --tag-name-filter cat -- --all
这里的命令就是把每一次提交都执行一次git rm -rf --cached --ignore-unmatch <file>的命令,这个命令就是把一个文件从git的跟踪仓库中删除。具体参考 https://www.cnblogs.com/studywithallofyou/p/11772684.html排序
--index-filter
参数用来指定一条Bash命令,而后Git会检出(checkout)全部的提交, 执行该命令,而后从新提交。这样的话,咱们就是在每一个提交的记录下,调用命令,移除<file>,而后再提交,这个文件便从Git的全部记录中彻底消失了。开发
这个功能主要就是靠git rm的不一样参数实现,也就是git filter-branch负责重写每次提交的历史,具体操做就是--index-filter指定的一条命令。上面的是删除一个文件,换成删除文件夹的,就能够指定删除某个文件夹下的内容。好比一开始咱们提交了一个目录,里面都是一些编译生成的类库,后来不须要了,能够把它从历史中删掉。
git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch <folder>' --tag-name-filter cat -- --all
若是咱们忘记了历史中哪些文件比较大,又想清理仓库,那么就能够用git verify-pack来查找。这个命令的做用就是列出来每次提交的内容中的详细信息,其中包含了提交内容的大小。
$ git verify-pack -v .git/objects/pack/*.idx 8fa15d279de33ce28a3289fd33951374084231e4 tree 135 137 144088922 a44a50b2ffb1f8283c8e64aafb8e7628249d7453 tree 33 43 144089059 b57d99f38fe22491e4a2d30c2b081ecb7bbb329c tree 99 97 144089102 2d4ffaffc11758d561ea1a6d57dd8ee17ee1d836 blob 644952 644959 144089199 8cf81ebfeec409f19e7a47a76517317f3bfa268d blob 695898 695871 144734158
-v(verbose)参数是打印详细信息。
输出的第一列是提交的index id,第二列表示文件(blob)或目录(tree),第三列是文件大小。 如今获得了全部的文件ID及其大小,而后咱们就能够经过写一些脚本排序找出最大提交内容的index。
先按照第三列排序,并取最大的5条,而后打印出每项的第一列(index id):
$ git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')" f846f156d16f74243b67e3dabec58a3128744352 4a1546e732b2e2a352b7bf220c1a22ad859abf89 f72d04efe6d0b41b067f9fbbc62455f28d3670d2 49bdf300ddf57d1946bc9c6570d94a38ac9d6a50 9c073d4177af5d2e43ada41f92efb18d9462a536
这条命令的做用就是,显示到git仓库目录中过滤每一条提交index的信息,而后把这些信息中,按照第三行也就是大小排序,而后把最大的几个筛选出来,最后只打印对应的index id就能够了。
上面咱们仅仅获得的是提交的index,仍是不知道这些里面哪些文件比较大,由于git rm须要指定文件名称。这时就须要git rev-list命令,这个命令的做用是列出来一个提交里面的内容信息。
$ git rev-list --objects --all c252878ac09a3979a80520b82a71dc2dae4529f9 7bc7d05c6097063f531580ba4c32921464a6c456 _drafts dcce26ed53fbb869dc7d5b71742d2f9e523bfe42 _layouts 414186c794a0d58695abb75c548bdbfec1de2763 _layouts/default.html 1934eeffe3d242375510dff28cffa6de6b3de367 _layouts/post.html 5f14647875f2177a6d37b8bfbcdb4629af595b64 _posts 6cdbb293d453ced07e6a07e0aa6e580e6a5538f4 _posts/2013-10-12-2.md
--objects:列出该提交涉及的全部文件ID。
--all:全部分支的提交,至关于指定了位于/refs下的全部引用。
若是内容很少,你能够按照上面最大index的列表,而后一个个经过git rev-list来查看哪些文件比较大,通常也不是特别多,若是比较多或是想之后使用,能够再写一个脚本,排序出最大的文件列表。
$ git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')" f846f156d16f74243b67e3dabec58a3128744352 assets/img/recent-badge.psd 4a1546e732b2e2a352b7bf220c1a22ad859abf89 assets/img/album/me/IMG_0276.JPG f72d04efe6d0b41b067f9fbbc62455f28d3670d2 assets/img/album/me/IMG_0389.JPG 49bdf300ddf57d1946bc9c6570d94a38ac9d6a50 assets/img/album/me/IMG_0813.JPG 9c073d4177af5d2e43ada41f92efb18d9462a536 assets/img/album/me/IMG_0891.JPG
上面的命令就是先经过rev-list列出全部index对应的文件信息,而后经过咱们上面查找出的最大的提交index,经过grep过滤出来。这样就能够列出来上面查找的最大的提交index中全部的文件信息。
而后就能够从里面找出能够的文件删除了。删除完成后记着push到远程分支,若是push报错,能够经过下面命令,强制把全部分支的内容推送到远程。到此结束。
git push origin --force --all