git clone --filter=tree:0 比普通 clone 快得多,因为它仅下载当前分支的 commit 对象,跳过所有 tree 和 blob(含 LFS 指针),形成元数据骨架,配合 --no-checkout 可跳过检出,大幅减少初始下载量。

git clone --filter=tree:0 为什么比普通 clone 快得多
因为 Git 2.39+ 的部分克隆(Partial Clone)默认只下载当前分支的 commit 和 tree 对象,跳过所有 blob(包括 LFS 指针文件本身)和历史分支数据。配合 LFS 使用时,它直接绕过了“下载大量指针再触发 smudge”的冗余流程,让 git clone 只拉取元数据骨架。
实操建议:
- 必须确保远程仓库支持
uploadpack.allowFilter(Git 服务器需开启,如 GitHub、GitLab 2023 年后版本默认支持) - 命令中
--filter=tree:0表示“不下载任何 tree 下的 blob”,LFS 指针文件也属于 blob,所以不会被拉下——这正是提速关键 - 搭配
--no-checkout可进一步跳过检出阶段,适合 CI 场景:git clone --filter=tree:0 --no-checkout <url> - 注意:首次
git checkout或git lfs pull仍会触发指针解析和大文件下载,但此时已无网络阻塞在 clone 阶段
git checkout 卡在 “Checking out files” 怎么破
这不是 Git 本身慢,而是 LFS 的 smudge 过滤器在逐个下载并解压大文件。尤其当工作区已有旧版指针、或本地缓存失效时,git checkout 会同步拉取所有匹配的 LFS 对象。
解决路径:
- 先禁用自动 smudge:
git lfs install --skip-smudge,再执行git checkout,此时只写入指针文本 - 用
git lfs fetch按需拉取:比如只拉当前分支最近 7 天的 LFS 文件:git lfs fetch --recent --recent-commits=7 - 精确控制范围:
git lfs fetch --include="models/*.bin" --exclude="data/archive/**",避免误拉冷数据 - 切完分支后手动触发:
git lfs checkout(而非git checkout),它只处理当前索引中的 LFS 指针,不扫描整个树
lfs.concurrenttransfers 和 lfs.batchsize 怎么设才不翻车
并发数不是越高越好。设太高会导致连接复用失败、LFS 服务器限流或本地 fd 耗尽;太小又浪费带宽。关键是看你的网络延迟与文件平均大小。
推荐配置组合:
- 高延迟(>50ms)、大文件(>100MB):设
lfs.concurrenttransfers=4,lfs.batchsize=20 - 低延迟(lfs.concurrenttransfers=12,
lfs.batchsize=100 - 永远加上
lfs.batch=true(默认开启),关闭它等于退化到单文件逐个请求,API 开销爆炸 - 验证是否生效:运行
git lfs fetch -v,观察日志里是否出现类似batch request for 87 objects的提示
为什么 git lfs pull 总是重下同一文件
常见原因是本地 LFS 缓存未命中,或服务器返回了不同 oid 的对象(比如文件被覆写但没更新指针)。Git LFS 不校验文件内容,只认 oid 和 size。
排查与修复:
- 检查缓存是否启用:
git config lfs.cache应输出true;若为false,执行git config --global lfs.cache true - 确认缓存路径可写:
git config lfs.cachepath,默认是~/.cache/git-lfs,磁盘满或权限错都会导致缓存失效 - 强制刷新本地指针状态:
git lfs fsck,它会报告哪些指针找不到对应缓存文件 - 慎用
--force:除非明确知道远端对象已变更且 oid 一致,否则git lfs pull --force会绕过所有缓存逻辑,纯下载
--filter=tree:0 就可能静默退化为全量克隆——务必用 git version 和 git ls-remote --symref origin HEAD 配合验证。


















