部分克隆的代价
部分克隆把文件内容的下载推迟到用时进行:克隆只取提交与目录树,缺失的对象由 promisor 远端按需补齐,克隆后仓库配置里会写入 remote.origin.promisor=true 与过滤器设置(如 blob:none)。日常检出单个版本没有差别,但离线环境、全量检索与批量导出会集中触发下载,「历史完整、内容不全」的代价就显现出来。理解触发点,才能决定什么时候用部分克隆、什么时候退回完整克隆。
基本信息
| 本质 | 克隆时跳过文件内容,按需向 promisor 远端补拉 |
|---|---|
| 常见过滤器 | blob:none 只缺文件内容;tree:0 连目录树也按需 |
| 触发时机 | checkout、diff、grep、打包等一切需要对象内容的操作 |
| 配置检查 | git config --get remote.origin.promisor / remote.origin.partialclonefilter |
| 高风险场景 | 离线开发、全量 grep、镜像导出、构建需要全部资源 |
| 缓解思路 | 提前触发所需内容下载、CI 缓存对象、必要时改用完整克隆 |
典型使用场景
- CI 快速建库:流水线只用少量文件时,克隆耗时与磁盘占用明显下降
- 大仓库日常开发:固定分支工作流下大部分历史用不到,按需下载即可
- 代码平台按路径取文件:展示层只读所需文件,省下全量副本的存储
- 弱网环境:先让当前分支可用,历史文件留到真正需要时再取
- 培训与演示:临时建库做练习,不必让每个人拉一份全量历史
常用示例
常用示例
git clone --filter=blob:none https://example.com/big/repo.git # 只取提交与目录树,文件内容按需
git config --get remote.origin.promisor # 输出 true 表示已开启按需拉取
git rev-list --objects --all --missing=print # 列出本地缺失对象,行首 ? 表示未下载
git fetch --refetch --filter=blob:none # 过滤策略变更后重新取数(仍按过滤器执行)
git grep -n 'TODO' -- '*.go' || true # 首次全量检索会批量下载,注意耗时
git count-objects -v # 查看本地对象数量与占用场景对照
| 场景 | 触发行为 | 后果 |
|---|---|---|
| 离线检出未下载文件 | promisor 远端不可达 | 直接报错,需提前取好内容或备完整副本 |
| 全量 grep 或翻历史 diff | 批量请求缺失对象 | 首次执行很慢,耗时取决于网络 |
| 镜像导出与归档工具 | 逐个请求对象内容 | 流程被按需拉取反复拖慢 |
| CI 缓存随镜像固化 | 缓存中对象不全 | 换任务时缺对象问题集中暴露 |
| 离线打包机与审计机 | 无稳定外网 | 不适合部分克隆,应使用完整克隆 |
给团队文档写明「本仓库为部分克隆」并注明 promisor 远端地址,避免同事把偶发缺对象误判为仓库损坏;换远端或迁移仓库时,这份说明要一起更新。
git fetch --refetch 常被当成全量预热:它仍按仓库保存的过滤器执行(remote.<name>.partialclonefilter),不会补回被过滤掉的对象;要本地全量内容应重新做完整克隆。
按需下载是自动发生的:promisor 远端可达时,检出缺失文件与首次检索都会即时补齐,不需要手工执行额外命令。