git sparse-checkout 能精准控制工作区检出内容,节省磁盘空间,尤其适用于 monorepo;它与 --filter 本质不同,后者仅减少对象下载,不控制工作区文件。

git sparse-checkout 可以在 clone 后让工作区只保留你指定的路径——不是“下载更少”,而是“检出更少”。这能显著节省磁盘空间,尤其对 monorepo 有效。
为什么 git clone --filter 不够用?
很多人先试 git clone --filter=blob:none 或 --filter=tree:0,以为能跳过某些文件下载。但它只影响对象数据库的传输量,工作区仍会完整检出(除非配合 sparse-checkout)。单独用 filter 会导致:git status 显示大量未跟踪文件、git add . 误加无关路径、甚至 git checkout 失败。真正控制“工作区内容”的,只有 sparse-checkout。
git sparse-checkout init 和 set 的关键区别
init 只启用基础配置并生成默认规则(通常为 /* + !/*),但不会自动删掉已存在的多余文件;set 才是生产环境该用的命令——它会立即重写工作区,只留下你指定的路径。
-
git sparse-checkout init --cone:启用 cone 模式(推荐),规则更简洁,性能更好,只允许目录级通配(如src/、docs/) -
git sparse-checkout set src/ docs/:立刻应用规则,删除工作区中除src/和docs/外的所有 tracked 文件 - 如果执行
set后发现删错了,运行git restore .无法恢复——必须先git sparse-checkout set *或git sparse-checkout disable,再手动git checkout
cone 模式下路径规则怎么写才生效
cone 模式要求规则必须是“目录前缀”形式,不支持 **/test.js 或 !src/*.log 这类复杂 glob。合法写法只有:
-
src/→ 包含整个src/目录及其所有子目录 -
package.json→ 只包含根目录下的package.json(注意:不带斜杠) -
!scripts/→ 排除scripts/目录(需放在src/之后才有效)
错误示例:src/**/*.ts 会被忽略;README.md 在子目录里不会被匹配;!node_modules/ 没用——因为 node_modules/ 本来就不在 Git 跟踪范围内。
git sparse-checkout 对其他命令的影响
开启 sparse-checkout 后,很多 Git 行为会静默改变,容易引发 CI 或协作问题:
-
git checkout branch-name不会更新未包含在 sparse 规则里的文件,即使它们在目标分支中存在变更 -
git commit -a不会把规则外的已修改文件标记为 deleted,可能导致遗漏 -
git status默认不显示规则外的修改(除非加-v或改用git status --ignored) - CI 脚本若依赖
ls -R或find . -name "*.py",可能因文件不在工作区而失败
最常被忽略的一点:sparse-checkout 是 worktree 级别的配置,git worktree add 新建的工作树默认不继承原规则,必须单独 git sparse-checkout set。


















