2023-8-7 23:56 /
前言

笔者近日整理自己的 GitHub repo 库的时候,发现其体积意料之外地巨大。尤其是其中一个 repo,本体约 30MB,repo 竟超过 500MB。


笔者对 Git 一知半解,于是查了些资料:Git 的版本管理机制会使 repo 不断膨胀,commit 越频繁的 repo 膨胀越快。且这个复杂的机制使得历史版本不好删除,这也是笔者撰写本教程的缘由。


工具部署

本文以 Windows 环境为例,使用其他操作系统的读者请参考其他教程。在使用批处理工具之前,读者需要先部署以下工具:

Git for Windows
对 GitHub repo 进行高级操作的基本工具。

BFG Repo-Cleaner
GitHub repo 历史版本清理工具,本教程的主角。

Java Runtime Environment
上述工具依赖 Java 运行环境。

④ 网络代理工具 与 SSH
俗称梯子。本文提供的批处理代码默认使用SSH代理来 push commit,以避免恼人的网络问题。
本文不赘述SSH的配置方法。若您不使用SSH,可自行修改批处理代码。


制作批处理文件

打开文本编辑器(例如 Visual Studio Code),粘贴以下代码:
chcp 65001
@echo off
title Git repo 历史文件清除器 (不clone)

echo.
echo ● 说明:本工具依赖 BFG repo 清理器,请先安装好 Java 环境。请确保本工具与 bfg.jar 一并位于 repo 库的目录下,即 repo 目录的上一层。
echo.
echo ▶ 键入 GitHub 用户名:
set /p var_username=
echo ▶ 键入代理端口 (例如 7890):
set /p var_port=
echo ▶ 键入 repo 名称:
set /p var_repo_name=
echo ▶ 键入分支名称 (一般是 master 或 main):
set /p var_branch_name=
echo ▶ 键入文件体积阈值 (单位为MB,仅键入数值),大于此体积的历史文件均会被清除:
set /p var_size_threshold=

echo.
echo ● 开始处理…

echo.
echo ● 启用代理…
git config --global http.proxy http://127.0.0.1:%var_port%
git config --global https.proxy http://127.0.0.1:%var_port%
ssh -T git@github.com
echo ● 清除历史文件…
java -jar bfg.jar --strip-blobs-bigger-than %var_size_threshold%M %var_repo_name%
echo ● 应用更改…
cd %var_repo_name%
git reflog expire --expire=now --all
echo ● 垃圾回收…
git gc --prune=now --aggressive
echo ● 正在 push…
git remote set-url origin git@github.com:%var_username%/%var_repo_name%.git
git branch -M %var_branch_name%
git push -f origin %var_branch_name%

echo.
echo ● 清理完成!(请注意 Git 输出结果,以其为准)

echo.
echo ▶ 处理结束,按任意键关闭
pause >nul


然后保存为 .bat 批处理文件,编码为 UTF-8。

接下来将这个 .bat 文件以及 BFG 的 .jar 文件放置在 repo 库目录下,即 repo 目录的上一层,再将 .jar 文件重命名为「bfg.jar」:



开始清理

双击运行 .bat 文件,按照提示键入所需信息:


批处理工具开始自动清理 repo 并提交至 GitHub。请留意 Git 输出的信息,确认清理是否成功:



清理效果




参考资料

[1] 清理 git 仓库太繁琐?试试 bfg!删除敏感信息删除大文件一句命令搞定(比官方文档还详细的使用说明)
[2] 使用git filter-repo、BFG Repo-Cleaner轻松搞定仓库代码瘦身
[3] Git设置代理解决被墙
[4] Using SSH over the HTTPS port - GitHub Docs
#1 - 2023-8-8 00:34
好东西,mark了
话说原理是什么?
#1-1 - 2023-8-8 08:19
Sam Toki
BFG 工具会在 .git 文件夹里搜刮历史 commit 中,最新 commit 里不存在的文件,将其设为作废状态,然后交给 Git 的 garbage collection(垃圾回收)机制去处理。
(我说的可能不太准确,可以参考 BFG 官方文档)