.git 缩小体积

之前用LFS传了一些文件,却发现github对LFS有1G的限额,就又都从仓库里删了,操作了好多次,这也导致了我的.git文件夹变得很大,其中主要是一些一直存储着的文件的索引和内容,即使在本地仓库中删除了这些文件,在.git中还是会一直保存着的。
操作前提:删除所有分支,只留下一个master

1查找出大文件

1
2
3
4
5
6
7
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"
#命令解析:
#rev-list 命令用来列出Git仓库中的提交,我们用它来列出所有提交中涉及的文件名及其ID。 该命令可以指定只显示某个引用(或分支)的上下游的提交。
#--objects:列出该提交涉及的所有文件ID。
#--all:所有分支的提交,相当于指定了位于 /refs 下的所有引用。
#verify-pack 命令用于显示已打包的内容,我们用它来找到那些大文件。
#-v(verbose)参数是打印详细信息。

通过 rev-list得到了<文件名 : ID>的对应关系,通过 verify-pack 得到了最大的5个文件ID。 用后者筛选前者便能得到最大的5个文件的文件名

2删除大文件

1
2
3
4
5
6
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch YOUR-FILE-NAME' --tag-name-filter cat -- --all
#命令解析:
#filter-branch命令可以用来重写Git仓库中的提交
#--index-filter参数用来指定一条Bash命令,然后Git会检出(checkout)所有的提交, 执行该命令,然后重新提交。
#–all参数表示我们需要重写所有分支(或引用)。
#YOUR-FILE-NAME 你查找出来的大文件名字

如果你确定某一个文件夹下面都不是你需要的,那么你可以直接删除整个文件夹,比如:

1
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch YOUR-FOLDER-NAME -r' --tag-name-filter cat -- --all

3回收空间

最后,虽然上面我们已经删除了文件, 但是repo里面仍然保留了这些 objects , 等待垃圾回收(GC), 所以我们要用命令彻底清除它, 并收回空间,命令如下:

1
2
3
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now

完成后,以强制覆盖的方式推送你的repo, 命令如下:
1
2
3
4
5
6
git push --force --all

git remote -v
git remote remove origin
git remote add origin
git push -u origin --all