参考文章:
[分享] 极狐GitLab仓库瘦身 - 官方技术分享 - 极狐GitLab 论坛
一、瘦身概述
Git仓库随着时间推移会变得越来越大,比如很多比较大的文件加入Git仓库时,可能引起以下问题:
- 下载仓库越来越慢,因为每个人都要下载文件
- 占用服务器大量存储空间
- 触发Git仓库存储限制
重写Git仓库可以移除不想要的仓库历史,减少仓库大小。
工具方面,我们推荐使用git filter-repo. 不推荐使用git filter-branch 或者 BFG.
git filter-repo
可以实现以下目的:
-
剥离大文件(或大目录或大扩展名)
-
按路径剥离不需要的文件
-
提取想要的路径及其历史(剥离所有其他内容)
-
重组文件布局(例如将所有文件移动到一个子目录中以准备与另一个 repo 合并,使子目录成为新的顶级目录,或将两个具有独立文件名的目录合并到一个目录中)
-
重命名标签(也经常为与另一个 repo 合并做准备)
-
替换或删除敏感文本,例如密码
-
使用户名与电子邮件的邮件映射关系重写永久化
-
使移植或替换引用(refs)永久化
-
重写commits消息
特别注意: 重写仓库是一种具有破坏性的操作,不应轻易使用,建议操作之前备份仓库,最好的仓库备份方式就是导出项目。
从仓库历史删除文件
想要对仓库瘦身,您必须首先从由 GitLab 自动创建的分支、标签和其他内部引用 (refs) 中删除对大文件的引用。这些引用(refs)包括:
- refs/merge-requests/* 用于合并请求。
- refs/pipelines/* 用于管道。
- refs/environments/* 用于环境。
- refs/keep-around/* 隐藏的refs,防止数据库中被删除
我们可以首先将项目导出,本地删除这些 refs,然后推送回去。
二、操作步骤
1、准备好环境Java、Gitlab、Python(https://www.python.org/)
注意下载python要用微软商店中下载的python3,自己下载安装的不好使。。。
2、下载git-filter-repo
官网:GitHub - newren/git-filter-repo: Quickly rewrite git repository history (filter-branch replacement)
3、备份并导出项目
防止操作失败,导致出现删库跑路的事情发生
4、使用 --bare
和 --mirror
参数从bundle中克隆仓库的新副本:
git clone --bare --mirror https://gitlab.fengqingx.com/project.git
5、清理克隆仓库中文件
进入project.git
文件夹。理论上,使用git filter-repo
可以从仓库的历史(包括master)中清除任何的文件。
由于我们试图删除内部引用(refs),所以我们依靠每次运行生成的commit-map
来告诉我们要删除哪些内部引用。
git filter-repo
每次运行都会生成一个commit-map
文件,并覆盖上一次生成的commit-map
。
比如,在所有分支中(包括master),清理10M大小以上的文件,使用参数--strip-blobs-bigger-than
:
python3 D://Project//Gitlab//git-filter-repo-main//git-filter-repo --strip-blobs-bigger-than 10M
比如,指定大文件的具体路径,使用参数--path
和--invert-paths
:
python3 D://Project//Gitlab//git-filter-repo-main//git-filter-repo --path path/to/big/file.m4v --invert-paths
参考git filter-repo
的官方文档,可以获取更多清理方式
6、配置remote远端仓库地址,将本地代码推送到gitlab服务器
git remote add origin https://gitlab.fengqx.com/xuan.git
-
7.推送变更,覆盖远程所有分支。
git push origin --force 'refs/heads/*'
如果远程分支是受保护的,请先禁用保护,然后推送,然后重新启用分支保护。
-
8.从标签release中删除大文件。
git push origin --force 'refs/tags/*'
如果标签是受保护的,请先禁用保护,然后推送,然后重新启用标签保护。
-
9.防止commit中存在死链。
git push origin --force 'refs/replace/*'
-
10.运行仓库清理。
三、仓库清理
仓库清理,就是允许上传一个包含目标对象的TXT文件。GitLab会清理这些目标对象的内部引用(refs)。你可以使用git filter-repo
生成这样的文件(commit-map
文件),用于清理。
注意文件commit-map
文件,每次执行完python命令,会生成一个commit-map文件,路径在D:\test\约翰\fengqx.git\filter-repo 中有commit-map文件
从13.6开始,安全的清理仓库需要确保在操作期间,没有git push等写操作,确保仓库是只读的,否则清理仓库的请求将提交失败。
清理仓库步骤:
-
打开项目
-
打开
Settings > Repository
-
上传清单文件,比如
git filter-repo
生成的commit-map
文件;
如果commit-map
文件大小超过250KB或者3000行,那么可以拆分文件并一个一个上传:split -l 3000 filter-repo/commit-map filter-repo/commit-map-
-
点击
Start cleanup
页面会提示:Repository cleanup has started. You will receive an email once the cleanup operation is complete.
将执行的动作:
- 移除任何对旧commits的内部引用。
- 运行
git gc --prune=30.minutes.ago
删除未引用的对象,临时重新打包仓库会导致仓库的大小显着增加,因为在创建新的打包文件之前不会删除旧的打包文件。 - 取消连接到项目的任何未使用的 LFS 对象,释放存储空间。
- 重新计算磁盘上仓库的大小。
清理完成后,GitLab 会发送一封电子邮件通知,其中包含重新计算的仓库大小。
如果仓库大小没有减少,这可能是由于在过去 30 分钟内发生的 Git 操作中引用了松散对象而导致的。 在仓库休眠至少 30 分钟后,尝试重新运行这些步骤。
四、注意事项:
- 项目统计信息是有缓存的,所以你可能需要等待 5-10 分钟才能看到存储使用率的降低。
- 清理会修剪超过 30 分钟的松散对象,也就是不会立即删除过去 30 分钟内添加或引用的对象。 如果你有权限访问 Gitlab 服务器,你可以避开延迟,并运行 git gc --prune=now 立即删除所有松散的对象。
- 这个操作从 GitLab 缓存和数据库中删除了一些重写提交的副本,但是覆盖范围仍然存在许多差距,并且一些副本可能会无限期地持续存在。
五、执行完第三步,此时重新拉代码,就会是压缩之后的gitlab仓库了。瘦身完成,
从500多MB,直接变成40MB