发现项目越来越大,主要是git历史提交记录占用很大空间
可以查看项目根目录下\ .git\objects\pack 这个目录所有文件的大小,该目录下的文件会保留着历史所有提交数据,并不会随着文件的删除而删除该历史提交记录,所以导致项目变得越来越大
git仓库过大会导致哪些问题?
-
git仓库体积过大,占用电脑本地闪存的存储空间;
-
clone git仓库时,耗时过长,甚至完全clone不下来导致git报错;
-
git pull
时会由于引用对象过多会报错,导致本地代码无法更新; -
在切换分支的时候经常会出现cpu占满,内存占满的情况导致电脑死机;
多种解决方案:
方案一:不建议
删除远程仓库并且删除本地项目下的.git文件夹,然后执行git init之后重新推送到新仓库,这会导致历史commit记录全都被删除,如果今后想回滚到某一次commit那就没办法了,所以这种办法要慎重。 (注意:所有分支记得全部本地备份,重新全部推送到远程)
方案二:不建议
新创建仓库,把原项目除了node_modules和.git文件夹,其他文件全部拷贝到新仓库,注意: 需要把所有分支都要这么执行一次,比较繁琐,也没有commit提交记录,很不建议,不推荐。
方案三:不是很建议
用filter-branch去做git仓库的清理, 优化git仓库历史提交记录, 操作耗时比较长,效率不高,容易出错。
方案四:强烈推荐(需要有java开发环境)
使用BFG工具优化,专注做git仓库清理工作的工具, 特点: 快~、好用~、功能强大、使用简单。
分析哪些文件比较大
实战项目: ***管理系统
- 先查看下 pack 的空间大小
git count-objects -v
优化前:OA \ .git\objects\pack 目录大小: 514MB
对历史提交文件大小排序分析
在git bash窗口执行下面这段命令会依次对历史提交中的文件大小进行排序,可以查看哪些文件比较大
git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| sed -n 's/^blob //p' \
| sort --numeric-sort --key=2 \
| cut -c 1-12,41- \
| $(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest
执行上面命令记录太多,可能在控制台看不全,可以使用以下命令,输出到一个文件中(info.txt),方便查看
git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| sed -n 's/^blob //p' \
| sort --numeric-sort --key=2 \
| cut -c 1-12,41- \
| $(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest > info.txt
方案三实战:用filter-branch去做git仓库的清理
移除commit中某个文件的引用
该命令仅仅只是移除commit中对某文件的引用,如果某次commit同时提交了要删除的文件和要保留的文件,该命令只会移除要删除文件的引用,并不会移除要保留的文件和当次commit记录,所以无需担心会把不该删除的文件删掉了。
- 单独移除某个文件的引用
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch 文件路径/文件名' --tag-name-filter cat -- --all
示例:
移除某个文件夹下所有文件的引用, 例如移除 node_modules/ 文件夹下面所有文件的引用
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch node_modules/*.*' --tag-name-filter cat -- --all
删除指向旧提交的指针
rm -rf .git/refs/original/
让历史记录全部过期
设置所有未关联对象过期时间为现在,默认为90天。
目的是放弃所有未关联对象恢复的可能性,因为reflog 是找寻它们踪迹的最后途径了。
git reflog expire --expire=now --all
重新打包
执行完成后此命令后.git\objects\pack目录下会生成新的打包文件,垃圾文件会保留在pack的上层目录
git repack -A -d
对仓库进行 gc 操作
执行完成此命令后,会把刚才repack的垃圾文件进行删除,此时再看仓库大小已经明显被优化了。
git gc --aggressive --prune=now
强制推送到远程分支
git push --force
重新从远程仓库clone代码&检查项目大小
注意!注意!注意!
所有协作开发的小伙伴都要新建目录,重新clone代码,切勿使用原来本地的目录了+不要push,否则前功尽弃。
方案四:使用BFG工具优化
前置条件和注意事项:
1、把码云仓库自动发布停掉;
2、把仓库全权限收回,防止在操作过程中有小伙伴提交代码;
3、安装java环境;
4、下载bfg.jar工具包 ;
5、把下载好的bfg.jar放到项目目录上一层目录下;
实战项目: OA
先看下优化前大小:
-
拉取代码(仅拉取镜像) 提前下载好两个镜像
一个用来操作的:oa_management-mirror.git , 一个用来做安全备份:oa_management-mirror-copy.git
## 操作
git clone --mirror https://gitee.com/yz_rd_frontend/oa_management.git oa_management-mirror.git
## 用于备份
git clone --mirror https://gitee.com/yz_rd_frontend/oa_management.git oa_management-mirror-copy.git
-
备份库需要删除remot引用,断绝污染:
git remote remove origin
;
cd oa_management-mirror-copy.git && git remote remove origin
cd ..
-
bfg 推荐的优化(删除大于50M的文件)
java -jar bfg.jar --strip-blobs-bigger-than 50M oa_management-mirror.git
-
删掉dist (不一定哈,通过扫描结果来觉得清理哪些文件)
java -jar bfg.jar --delete-folders {dist} --no-blob-protection oa_management-mirror .git
-
清理完指定的对象后,需要对git的reflog记录进行清空, 并且进行git仓库的垃圾处理删除无意义的git对象
cd oa_management-mirror.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
-
推送镜像
需要有推送权限(注意: 码云仓库设置: 功能设置->约束>强制推送, 把禁止强制推送关闭,操作完成后再开启)
git push --mirror
-
在本地新建一个文件(不要使用原来的项目文件夹),新拉取代码
get clone https://xxxxxxxxxxxx.git
-
检查下最新代码占用体积大小
git count-objects -v
优化后大小:40M
-
恢复码云自动发布webhook + 相关开发权限等配置
备份镜像库可以之后再删除