GeneralAndroid 大文件迁移进展记录

1. 当前阶段结论

当前已经完成:

  • MinIO 迁移方案设计
  • 目标桶创建
  • 前40大文件迁移映射清单生成
  • 上传 / 下载 / 查询 / 更新 / 删除 脚本接入
  • bootstrap 初始化流程接入
  • 本地 hook 与 GitLab CI 大文件规则接入
  • 资产历史记录接入
  • TOP40 范围内需要迁移的条目已全部上传到 MinIO 并登记进 manifest

说明:

  • MinIO 路线可行
  • mc + 本机 MinIO API 的上传路径可用
  • 上传速度正常,适合继续推进工作区本体移除与后续历史清理
  • 迁移流程中的“脚本 + manifest + SHA256 + 历史记录”机制已经成型

当前已不再处于“只做试点”的阶段,而是已经完成第一轮正式迁移闭环。


2. 已完成工作

2.1 Git / 仓库问题确认

已确认当前仓库存在明显的大文件污染问题:

  • 仓库总大小约 31.10 GiB
  • .git 目录约 15.43 GiB
  • Git 跟踪文件总大小约 12.87 GiB
  • 前40大跟踪文件合计约 8.43 GiB

已生成报告:

  • main/blog/gitlab/repo_size_report.md

2.2 迁移总体方案已编写

已完成完整迁移方案文档:

  • main/blog/gitlab/minio_migration_plan.md

已确定采用:

  • GitLab:仅保留源码、脚本、文档、少量必要小样本
  • MinIO:托管大文件资源
  • 单桶、多目录结构:
    • generalandroid/releases/
    • generalandroid/media/
    • generalandroid/traces/
    • generalandroid/tools/
    • generalandroid/books/

2.3 MinIO 现状已确认

已阅读并核对 MinIO 文档:

  • main/blog/minio/MinIO 部署现状与维护调研.md

已确认:

  • MinIO 已部署在本机
  • 已安装 mc
  • 可直接通过本机 API 访问:http://127.0.0.1:9000
  • 本机已有 local alias
  • 现有桶可正常列出

2.4 已创建目标桶

已创建新桶:

  • generalandroid

当前上传/迁移都应以该桶为目标桶。

2.5 已生成前40大文件迁移映射清单

已完成迁移映射文档:

  • main/blog/gitlab/minio_migration_mapping.md

说明:

  • 已对前40大文件按 releases/media/traces/tools/books 分类
  • 原先暂不迁移的 main/hideapi/frida/frida-core-devkit-17.2.12-android-arm64/libfrida-core.a 已改为正式迁移
  • 当前 TOP40 范围内需要迁移的对象已全部登记进 manifest,并且实体对象已全部存在于 MinIO

2.6 已打通上传脚本与清单机制

已新增:

  • 上传脚本:scripts/upload_assets.py
  • 批量上传脚本:scripts/batch_upload_assets.py
  • 下载脚本:scripts/download_assets.py
  • 列表脚本:scripts/list_assets.py
  • 更新脚本:scripts/update_asset.py
  • 删除脚本:scripts/remove_asset.py
  • 资源清单阅读视图:assets/resource_manifest.md
  • SHA256 派生清单:assets/assets_sha256.txt
  • 结构化主清单:assets/resource_manifest.json
  • 资产历史记录:assets/asset_history.jsonl

脚本能力:

  • 读取仓库相对路径文件
  • 计算 SHA256
  • 上传到指定 MinIO 分类路径
  • 自动维护结构化主清单 / Markdown 阅读视图 / SHA256 派生文件
  • 支持列出、更新、删除已登记资源
  • 记录 upload / update / remove 操作历史
  • 支持 --dry-run
  • 下载支持 --jobs 并发、--continue-on-error、以及“本地已校验通过则跳过”的 resumable rerun
  • 批量上传支持并发 worker,但 manifest / SHA / history 只在主线程串行写入;每个上传对象都必须先通过 mc stat 远端确认

2.7 TOP40 范围内对象登记与 MinIO 实体一致

当前已确认:

  • assets/resource_manifest.json 中共有 40 条正式记录
  • mc stat 已逐条验证 manifest 中对象存在性
  • 当前 missing_objects = 0
  • main/blog/gitlab/minio_migration_mapping.md 中需要迁移的条目,当前已经全部在 manifest 中可见

这说明当前状态已经达到:

  • manifest 与 MinIO 对象实体一致
  • 当前没有“已登记但对象不存在”的漏项
  • 当前没有“应迁移但未登记”的漏项

2.8 本机 clone + bootstrap 恢复验证已通过

已完成一次本机重新 clone 验证,并执行:

bash scripts/bootstrap_repo.sh

验证结果:

  • 已迁移并登记到 manifest 的文件可以被正确恢复
  • bootstrap 初始化流程可用
  • MinIO 下载链路在本机 / 当前 alias 配置下已经跑通

这说明当前至少已经确认:

  • clone 后通过统一初始化入口恢复大文件是可行的
  • 当前 MinIO + manifest + 下载脚本 + bootstrap 的本机闭环已经成立

注意:

  • 这次验证成功的是“本机环境”
  • 外网同事是否能成功,还取决于其 mc alias 配置和 MinIO API 可达性

3. 当前已发现问题

3.1 远程同事 / 外网访问链路已明确主路径

当前已经确认:

  • 本机环境下 clone + bootstrap 恢复成功
  • 本机 alias local 指向本机 MinIO API 时流程可用
  • 外网可用 MinIO API 入口已经明确为 http://tx2.898311.xyz:9010
  • minio.898311.xyz 当前仍只是 HTML 上传页,不是 MinIO API endpoint
  • 仓库脚本已调整为支持以下环境变量:
    • GENERALANDROID_MC_ALIAS
    • GENERALANDROID_MC_ENDPOINT
    • GENERALANDROID_MC_ACCESS_KEY
    • GENERALANDROID_MC_SECRET_KEY
  • scripts/bootstrap_repo.sh 会在 alias 缺失时自动创建,不再要求远程机器预先手工配置 alias
  • 外网普通账号 uploadrw0511a 已经完成 generalandroid 桶的对象级验证:
    • mc ls uploadrw/generalandroid 成功
    • generalandroid/external-check/minio-uploadrw0511a-ga-test.txt 上传新的小测试文件成功
    • mc cat 读取该测试文件成功,返回内容 ga-check-2026-05-11
    • mc rm 删除该测试文件成功(创建 delete marker,符合版本化桶行为)
    • mc ls uploadrw/blogimg 仍返回 Access Denied,说明权限边界未被放大
  • 已完成一轮真正的公网 bootstrap 端到端验收:
    • 使用一个全新 alias tempbootstrap
    • 通过环境变量自动创建 alias 成功
    • bash scripts/bootstrap_repo.sh 已进入真实下载流程
    • 至少一个真实大文件 GPU负载优化.webm 已经通过公网 endpoint 成功恢复,下载量约 488.76 MiB
    • 该次下载耗时约 12m34s,实测速度约 662.98 KiB/s

因此当前对远程环境的结论更新为:

  • 主恢复路径已经明确并已落到脚本接口
  • uploadrw0511a 已满足 generalandroid 桶的远程列、读、写、删需求,可以作为 GeneralAndroid 远程 clone 恢复主账号
  • 远程机器只需提供上述环境变量即可接入公网 mc 恢复流程
  • 预签名下载不是当前阻塞项,而是后续可选增强
  • 当前真正需要关注的是外网下载速度优化,而不是接入可行性

3.2 重新 clone 仍然不是最小下载


4. 当前明确约束

4.1 暂不迁移文件

当前状态:

  • 暂无保留项
  • 原先暂不迁移的 main/hideapi/frida/frida-core-devkit-17.2.12-android-arm64/libfrida-core.a 已改为正式迁移,并已进入 MinIO + manifest 管理

4.3 重新 clone 是否已经最小下载

当前答案:还没有。

原因:

  1. 现在已经接入的是“未来治理流程”
    • 新增超过 40MB 的文件将被引导走 MinIO
    • 本地 hook 与 GitLab CI 会阻止新的大文件继续污染仓库
  2. 但仓库历史中的大对象仍然保留在 Git 历史里
    • 只要远端历史没有被清理
    • 新同事重新 clone 仍会拉到这些历史对象
  3. 因此当前状态只能做到:
    • 防止问题继续恶化
    • 不能立刻让新 clone 变成最小下载

结论:

  • 要实现重新 clone 的最小下载,还必须执行历史清理阶段。
  • 即:在 MinIO 承接和未来治理闭环稳定后,再做 git filter-repo / BFG 历史瘦身。

5. 当前最合理的下一步

当前不再是“继续补迁 TOP40”的阶段,而是进入两个后续方向:

方向一:从当前仓库版本逐步移除已迁移大文件本体

目标:

  • 让当前分支逐步切换到“Git 只保留元数据,MinIO 保留实体”

动作:

  1. 分批删除已迁移并已验证可恢复的大文件本体
  2. 提交删除改动
  3. 继续通过 bootstrap / 下载脚本验证恢复能力

方向二:为历史清理做准备

目标:

  • 为后续最小 clone 改造提供前置条件

动作:

  1. 确认 TOP40 对象全部在 MinIO + manifest 中
  2. 继续验证外网/远程恢复链路
  3. 准备 git filter-repo / BFG 的执行清单
  4. 进入维护窗口后做历史瘦身

6. 当前可直接复用的命令和能力

6.1 查看桶

mc ls local

6.2 查看迁移后 media 目录

mc ls local/generalandroid/media

6.3 dry-run 上传

python3 scripts/upload_assets.py "<repo-relative-path>" media --dry-run

6.5 一键初始化仓库

推荐新同事 clone 后直接执行:

bash scripts/bootstrap_repo.sh

如果在 Claude Code 中协作,也可以使用项目命令:

/clone-init

该脚本会:

  1. 检查 python3
  2. 检查 mc
  3. 配置项目 core.hooksPath
  4. 校验 local MinIO alias 是否存在
  5. 尝试恢复 manifest 中已登记的大文件
  6. 校验当前仓库是否存在 >40MB 违规文件

说明:

  • Git 出于安全模型限制,不能在 clone 后自动执行仓库脚本
  • 因此“零操作自动安装 hook”做不到
  • 当前最接近自动化的项目方案是:clone 后只执行一条 bootstrap 命令

7. 验收标准与测试步骤

本节用于约束后续实施完成后的“通过条件”,确保其他 AI 或人员只看文档也能独立完成验证。

7.1 验收目标

本次接入完成后,必须同时满足以下目标:

  1. 后续新增 >40MB 文件不能再直接进入 Git
  2. 大文件必须能通过项目脚本上传到 MinIO
  3. Git 中必须保留可供恢复的元数据/清单
  4. 本地缺失大文件时可以自动下载恢复
  5. GitLab CI 必须对违规提交做兜底拦截
  6. 已验证过的试点文件可以完成上传 → 删除本地 → 自动恢复的完整闭环

7.2 验收项 A:上传脚本可用

验收目标:

  • 对任意一个超过 40MB 的文件,上传脚本可以正确完成:
    • SHA256 计算
    • 上传到 MinIO 指定目录
    • 正确写入清单/元数据
    • 不因特殊文件名污染清单

建议测试步骤:

  1. 选择一个普通大文件执行 dry-run
  2. 选择一个包含空格、中文或特殊字符的大文件执行 dry-run
  3. 选择一个真实大文件执行实际上传
  4. 检查 MinIO 对象是否存在
  5. 检查 manifest / sha256 记录是否格式正确

建议命令示例:

python3 scripts/upload_assets.py "<repo-relative-path>" media --dry-run
python3 scripts/upload_assets.py "<repo-relative-path>" media
mc ls local/generalandroid/media

通过条件:

  • 上传成功
  • MinIO 中对象路径正确
  • 清单记录不被拆行、不脏格式
  • SHA256 可用于后续下载校验

7.3 验收项 B:下载脚本可用

验收目标:

  • 已迁移文件删除本地副本后,可以通过项目下载脚本自动恢复
  • 恢复后的文件校验值和清单一致

建议测试步骤:

  1. 先确保文件已经在 MinIO 中存在
  2. 手动删除本地文件
  3. 执行下载脚本恢复目标文件
  4. 对比 SHA256 与清单记录

通过条件:

  • 文件被恢复到预期本地路径
  • SHA256 校验通过
  • 文件内容可被正常使用

7.4 验收项 C:本地 hook 拦截 >40MB 直传 Git

验收目标:

  • 开发者如果直接把 >40MB 文件加入 Git,本地 hook 必须阻止提交
  • 提示信息必须明确告诉使用者改走 MinIO 上传流程

建议测试步骤:

  1. 安装项目 hook
  2. 构造或选取一个超过 40MB 的测试文件
  3. 执行 git add + git commit
  4. 观察 hook 是否拦截
  5. 再用一个小文件验证不会误伤正常提交

通过条件:

  • 大文件提交被拦截
  • 小文件提交不受影响
  • 拦截提示中包含明确修复路径

7.5 验收项 D:自动下载 hook 生效

验收目标:

  • checkout / merge 后,如果 manifest 中声明的大文件缺失,本地 hook 能自动拉回
  • 已存在且校验正确的文件不重复下载

建议测试步骤:

  1. 安装自动下载相关 hook
  2. 删除一个已迁移的大文件本地副本
  3. 执行一次 git checkoutgit pull / git merge
  4. 观察是否自动恢复文件
  5. 再执行一次相同行为,确认不会重复下载

通过条件:

  • 缺失文件可自动恢复
  • 已存在且校验通过的文件不重复下载

7.6 验收项 E:GitLab CI 兜底校验生效

验收目标:

  • 即使开发者本地没装 hook,也不能把 >40MB 文件直接合入 Git
  • GitLab CI 必须识别违规提交并失败

建议测试步骤:

  1. 建一个测试分支
  2. 在该分支提交一个故意违规的 >40MB 文件
  3. 推送后观察 GitLab pipeline
  4. 再提交一个合法的“manifest 更新 + 无大文件本体”变更
  5. 再次观察 pipeline

通过条件:

  • 违规提交对应 job 失败
  • 合法提交对应 job 通过

7.7 验收项 F:TOP3 试点文件闭环验证

验收目标:

使用当前已经上传成功的 TOP3 文件,完成完整闭环验证。

当前试点文件:

  1. main/blog/Android性能/稳定性/系统UI内存泄露阶段性总结报告.webm
  2. main/blog/Android知识体系系列/图形图像/GPU负载优化.webm
  3. main/blog/Android知识体系系列/图形图像/Franklin1 Android GPU内存统计串讲和答疑.webm

建议测试步骤:

  1. 确认 MinIO 中对象存在
  2. 清单中存在对应记录
  3. 删除本地文件
  4. 通过下载脚本或自动下载 hook 恢复
  5. 校验 SHA256
  6. 确认文件可正常打开/使用

通过条件:

  • 3 个文件都能从 MinIO 恢复
  • 清单与 SHA256 记录一致
  • 本地使用无异常

7.8 其他 AI / 测试人员执行要求

如果后续由其他 AI 或其他人员接手测试,必须按以下顺序执行:

  1. 先阅读:
    • main/blog/gitlab/minio_migration_plan.md
    • main/blog/gitlab/minio_migration_progress.md
    • main/blog/gitlab/minio_migration_mapping.md
  2. 先检查 MinIO 状态:
    • mc ls local
    • mc ls local/generalandroid
  3. 优先使用已迁移成功的 TOP3 文件做回归验证
  4. 每完成一项验收,记录:
    • 测试输入
    • 执行命令
    • 输出结果
    • 是否通过
  5. 如果发现失败,必须先判断失败属于:
    • 上传脚本问题
    • manifest 格式问题
    • 下载恢复问题
    • hook 问题
    • GitLab CI 问题

7.9 验收结论标准

只有当以下项目全部通过时,才可以认为“大文件治理接入”完成:

  • 上传脚本通过
  • 下载脚本通过
  • 本地拦截 hook 通过
  • 自动下载 hook 通过
  • GitLab CI 兜底通过
  • TOP3 闭环验证通过

在这之前,不应直接放量到 TOP40 全量迁移。


8. 下一阶段实施建议

当前已完成:

  • MinIO 接入主流程
  • 上传 / 下载脚本
  • bootstrap 初始化
  • 本地 hook
  • GitLab CI 大文件拦截
  • 资产管理脚本:upload / download / list / update / remove
  • 资产历史记录:assets/asset_history.jsonl

下一阶段建议继续补齐资源管理闭环,优先级如下:

  1. scripts/remove_asset.py
    • 删除 manifest 条目
    • 删除或归档 MinIO 对象
  2. scripts/list_assets.py
    • 列出当前已登记资源
    • 支持按 category / path 查询
  3. scripts/update_asset.py
    • 上传新版本对象
    • 自动更新 manifest
  4. 继续扩大已迁移资源范围
    • 先从 TOP10 扩到 TOP40
  5. 在资源迁移稳定后,进入历史清理阶段

这一阶段完成后,项目的大文件治理能力才算具备完整的增删改查与长期维护能力。


9. 总结

当前迁移工作已经从“方案阶段”进入“执行验证阶段”。

已经证明的事情:

  • MinIO 可用
  • 桶已建好
  • 上传可行
  • 内网上传路径可用
  • TOP3 已成功落桶

当前阻塞批量迁移的核心问题只有一个:

  • 上传脚本对特殊文件名的记录机制还不够稳

所以当前最合理的决策不是立刻全量冲 TOP40,而是:

  • 先修脚本和清单格式,再继续批量迁移