仓库大文件如何清理?

背景

如果在代码库中提交了大量的二进制文件,可能导致代码库容量超出限制而无法写入,或者单个文件过大,超出单文件大小限制而无法写入。

此时可以对已提交代码库的历史大文件进行清理,然后将大文件使用 Git-LFS 进行存储管理。

数据备份

清理操作会改写代码库提交历史,清除历史的大文件,建议将远程代码库克隆下来,先在本地进行备份。

工具安装

清理仓库大文件需要修改仓库的提交历史,git-filter-repo 是 Git 官方社区推荐的修改仓库提交历史的工具,本文介绍使用 git-filter-repo 来清理仓库大文件的方法。

安装方法参考帮助文档,或直接使用下述命令安装:

pip3 install git-filter-repo

克隆裸库

从 Codeup 上克隆待处理的代码库裸库,以 http 协议为例:

git clone --mirror --bare https://codeup.aliyun.com/example/example.git

清理大文件

进入克隆好的裸库中

cd example.git

git-filter-repo 支持三种方式的大文件清理:按照文件大小、路径或者按照文件 blob ID,具体可以参考官方文档,以下通过示例详细说明其使用方法。

按文件大小清理

假如要清理大于 100M 以上的文件,执行下述命令:

git filter-repo --strip-blobs-bigger-than 100M

--strip-blobs-bigger-than 参数支持K、M和G三种单位,比如这儿的100M也可以换成10K,1G等。

按文件路径清理

假如已知大文件的路径,可以通过组合 --path 和 --invert-paths 参数来清理相关大文件。例如,要从仓库的提交历史中删除 path/of/large/file.lib 文件和 bin/ 目录,可以执行下述命令:

git filter-repo --path path/of/large/file.lib --path /bin/ --invert-paths

这两个参数组合起来可保留除了--path 指定的目录/文件外的其他所有文件/目录,即从仓库历史提交中清除 --path 指定的所有目录/文件。

按文件 blob ID 清理

假如已知大文件的 blob ID,可以将大文件的 blob ID写入一个文件中,比如在文件 ids.txt 中写入下述几个大文件 blob ID

e152814d14939a20f5399acf80b606ad018f872a
b747204ba81985a3f41314ef55d4c4a24868ede2

然后执行

 git filter-repo  --strip-blobs-with-ids ids.txt

更新服务端仓库

首先更新 example.git 仓库配置,在 example.git 中执行下述命令

git config remote.origin.mirror false

使用本地去除大文件后的仓库强制更新远程仓库

git push -u origin refs/heads/*:refs/heads/* -f
git push -u origin refs/tags/*:refs/tags/* -f

查看远端更新效果

在 Codeup 页面上确认对应代码库的相关大文件已经从各个分支的提交历史中被清除。

仓库立即清理

执行完上述操作后,由于清理存在等待周期,服务端仓库大小此时可能并没有明显变化。

如需立即生效,需要仓库管理员在仓库的“设置”中点击“立即清理”,并选择“立即删除”,执行完清理操作后相关大文件将从服务端仓库中彻底清除。

1

二进制大文件托管解决方案

为了避免大文件拖慢库访问速度和占据巨大容量,二进制大文件强烈建议使用 Git-LFS 存储,参见Git 大文件存储

其他场景的大文件清理

通过 Agit 集中式流程创建的评审,源提交可能也携带了大文件,其清理方式参见如何清理 Agit 集中式评审引入的大文件空间?

阿里云首页 云效2020 相关技术圈