GeneralAndroid 最小 Clone 历史清理方案
1. 目标
本方案用于回答一个明确问题:
在当前 MinIO 接入完成后,如何继续推进到“其他同事重新 clone 仓库时,尽可能接近最小下载”。
当前状态下,MinIO + 上传/下载脚本 + hook + GitLab CI 只能解决:
- 未来新增大文件不再直接进入 Git
- 大文件可以转由 MinIO 承接
但它不能自动清除历史里已经存在的大对象。
因此,要实现“重新 clone 最小下载”,必须额外执行一次 Git 历史清理。
2. 当前为什么还做不到最小 clone
当前仓库的问题分成两层:
2.1 未来污染控制
这一层已经在建设中:
- 超过 40MB 的文件必须走 MinIO
- 本地 hook 阻止直接提交大文件
- GitLab CI 兜底拦截违规提交
- 下载脚本可按 manifest 自动恢复
这一层的作用是:
- 防止问题继续恶化
2.2 历史大对象仍然存在
这一层还没有做:
- 历史中的 zip、webm、so、trace、pdf 等大对象仍然保留在 Git 历史里
- 只要远端历史不清理
- 新 clone 仍然会拉到这些旧对象
这一层决定的是:
- 新 clone 是否真的变小
结论:
- 当前只能做到“以后不再继续变差”
- 不能做到“现在重新 clone 就立刻最小下载”
3. 最小 clone 的完整实现路径
必须按两个阶段来看:
阶段 A:未来治理闭环
目标:
- 以后 >40MB 文件不再直接进入 Git
手段:
- MinIO 上传脚本
- MinIO 下载脚本
- 资源 manifest
- 本地 hook
- GitLab CI 校验
阶段 A 完成后效果:
- 仓库不会继续快速膨胀
- 但历史大对象依然存在
阶段 B:历史瘦身
目标:
- 从 Git 历史中删除已经迁移到 MinIO 的大对象
手段:
git filter-repo或 BFG- 重写 Git 历史
- 强推远端
- 团队重新 clone
阶段 B 完成后效果:
- 新 clone 显著变小
- 拉取速度改善
.git目录显著下降
只有阶段 A + 阶段 B 都完成,才能称为真正意义上的“最小 clone”。
4. 历史清理前必须满足的前提
在进入历史清理前,必须满足以下条件:
-
MinIO 承接稳定
- 需要迁移的大文件都已经上传到 MinIO
- 目标桶与目录结构稳定
- 上传/下载脚本可用
-
manifest 可恢复
- 每个已迁移文件都在 manifest 中有记录
- SHA256 完整可用
- 下载脚本可恢复这些文件
-
未来治理已经生效
- 本地 hook 已安装
- GitLab CI 已能拦截新的 >40MB 违规提交
- 避免一边清历史,一边又继续写入新大文件
-
例外项已经确认
- 例如当前明确暂不迁移:
main/hideapi/frida/frida-core-devkit-17.2.12-android-arm64/libfrida-core.a
- 这些例外项是否要继续保留在 Git,需要提前决定
- 例如当前明确暂不迁移:
-
团队切换方式已达成一致
- 历史重写后旧仓库不能继续无脑复用
- 团队成员通常需要重新 clone
-
维护窗口已确定
- 不应在多人频繁提交期间直接改写远端历史
5. 推荐执行顺序
5.1 冻结窗口前准备
- 再次导出仓库大文件报告
- 再次确认前 40 / 前 N 大文件的迁移状态
- 补齐尚未上传到 MinIO 的必要文件
- 确认 manifest 与下载脚本可以恢复这些文件
- 确认未来治理 hook / CI 已上线
5.2 备份阶段
至少做两类备份:
- 裸仓库备份
- 用于完整保留清理前历史
- 工作区备份
- 用于保留当前代码现场
建议至少保留:
- 清理前仓库完整打包
- 当前
.git体积记录 - 当前
git count-objects -vH输出记录
5.3 历史重写阶段
执行思路:
- 确定要从历史中移除的文件列表 / 路径模式
- 使用
git filter-repo或 BFG 清理历史对象 - 清理后执行:
git gcgit repack
- 检查新的仓库体积
- 在本地先做一轮全新 clone 验证
5.4 本地验证阶段
不能直接用旧工作区“感觉没问题”就结束,必须:
- 在一个全新目录重新 clone 本地清理后的仓库
- 记录:
- clone 时间
.git体积git count-objects -vH
- 验证 manifest 是否还在
- 验证下载脚本能恢复已迁移大文件
- 验证 hook / CI 规则仍然成立
5.5 远端切换阶段
确认本地验证完成后:
- 强制推送到 GitLab
- 通知所有同事不要继续基于旧仓库提交
- 发布重新 clone 指引
- 统一切换到新历史
6. 历史清理后的验收标准
只有当以下条件全部满足,才算“最小 clone”改造完成:
- 新 clone 的
.git体积明显小于清理前 - clone 不再频繁出现超时、EOF、对象传输中断
- 已迁移到 MinIO 的文件可通过脚本恢复
- 本地 hook 仍然阻止新的 >40MB 文件直接进入 Git
- GitLab CI 仍能兜底拦截违规提交
- 团队成员按新流程重新 clone 后可正常开发
7. 对其他 AI / 测试人员的要求
如果后续阶段由其他 AI 或其他测试人员接手,要求其至少完成以下动作:
7.1 清理前记录
记录以下数据:
du -sh .gitgit count-objects -vH- clone 耗时
- 仓库总大小
7.2 清理后验证
必须在全新目录执行,而不是继续使用旧工作区:
- 全新 clone 清理后的仓库
- 再记录:
du -sh .gitgit count-objects -vH- clone 耗时
- 对比清理前后差异
7.3 功能回归
还必须验证:
- manifest 存在且可解析
- 下载脚本可恢复已迁移文件
- hook 拦截仍有效
- GitLab CI 拦截仍有效
7.4 输出报告
最终应输出一份对比报告,至少包含:
- 清理前
.git体积 - 清理后
.git体积 - 清理前 clone 时间
- 清理后 clone 时间
- 恢复脚本是否成功
- hook / CI 是否仍通过
8. 直接结论
如果只是把当前改动推到远端:
- 只能防止未来继续恶化
- 不能让新同事立刻最小 clone
如果要真正做到最小 clone,必须继续执行:
- MinIO 承接全部必要大文件
- 完成未来治理闭环
- 执行 Git 历史清理
- 强推远端
- 通知团队重新 clone
因此,“最小 clone”不是当前阶段自动获得的结果,而是 MinIO 接入之后的下一阶段专项工作。