编程 克隆 Linux 内核不用等几小时:--filter=blob:none 把 3.26GB 压到 1.13GB

2026-09-21 21:05:38

克隆 Linux 内核不用等几小时:--filter=blob:none 把 3.26GB 压到 1.13GB

参考文档:

全量 clone 慢在哪

git clone 默认会下载整个仓库生命周期内的所有提交、树对象和 blob。对超大仓库来说,这一下就是数小时甚至数天,磁盘占用轻松上百 GiB。Linux 内核是个典型例子:100 万+ 提交、830 万+ 对象,仓库体积约 3.3GB。

要加速,得先分清自己卡在哪个环节。三种手段解决的是三类不同问题。

Git LFS:仓库里躺了二进制大文件

当体积膨胀来自非文本文件——美术资源、模型、编译产物——用 Git LFS。给特定后缀配置走 LFS 之后,克隆过程不会把这些文件的历史版本拉下来,本地只在检出时拿到当前版本。

有一点要注意:LFS 必须在提交之前就配置好。历史里已经进了普通 blob 的文件,事后再补得走 git lfs migrate 迁移。

浅克隆:根本不要历史

只构建最新代码、不关心历史的场景,浅克隆最直接:

git clone --depth 1 --single-branch

--depth 会截断历史,只下载给定深度内的提交——--depth 1 就是最近一次提交;--single-branch 让它只跟一个分支。构建流水线用这个组合基本够。

部分克隆:历史留着,对象按需取

Git 2.22+ 提供 --filter

git clone --filter=blob:none

它保留完整的历史信息,只把 blob 过滤掉;缺失的对象在真正被用到时才从 promisor remote 动态获取。

Linux 内核上的实测数据:对象数从 834 万降到约 602 万,数据量从 3.26GB 降到 1.13GB。按 2MB/s 的带宽估算,克隆耗时大约是全量克隆的三分之一。

还有更激进的 treeless 模式 --filter=tree:0,下载量更小,但开发场景下会频繁触发缺失对象下载,代价反而更高,不推荐日常使用;如果只是构建、只取最新版,可以考虑。

部分克隆 + 稀疏检出:大 monorepo 的用法

git clone --filter=blob:none --sparse
cd
git sparse-checkout init --cone          # --cone 模式,Git 2.25+
git sparse-checkout set  # 可多个目录,空格分隔

--no-checkout 可以加在 clone 上,避免克隆完成后自动检出时把当前分支的所有文件都拉下来。

这套组合适合微服务单根仓,比如安卓开发:不同成员只下载自己关心的目录,不必每次拿全仓。

其它几个技巧

  • git clone --dissociate:与原始仓库完全分离,避免不必要的对象复制。
  • git clone --reference :本地已有仓库时复用已有对象,减少网络传输。
  • 网络差到 partial clone 都不稳定时,改用 git bundle:把对象库打包成单一文件,离线分发后再 fetch。
git bundle create repo.bundle --all
git fetch --update-head-ok  refs/heads/*:refs/remotes/origin/*

这条路绕开了 HTTP/SSH 的 RPC 超时,本质是把仓库同步变成文件复制。

怎么选

  • 有二进制大文件 → Git LFS。
  • 只要最新代码构建 → 浅克隆(--depth 1 --single-branch)。
  • 要历史但要快,或只关心部分目录 → 部分克隆(--filter=blob:none,可加 --sparse)。

三者不冲突,可以叠加使用,比如部分克隆 + LFS。

一个细节:部分克隆会在本地仓库加上扩展 extensions.partialClone,作用是防止旧版本 Git 因为找不到对象而中途失败。缺失对象由 Git 自动按需下载,一般情况下不需要额外配置。

复制全文 生成海报 Git 大仓库 partial clone CI

推荐文章

程序员茄子在线接单