Skip to content

大型仓库优化

大型仓库(大量提交历史、大量文件、大量分支)会导致克隆慢、操作卡顿。Git 提供了多种优化策略。

浅克隆:git clone --depth

浅克隆只下载指定深度的提交历史,大幅减少初始克隆时间:

bash
# 只获取最近 1 次提交(最浅)
git clone --depth 1 https://github.com/user/large-repo.git

# 获取最近 50 次提交
git clone --depth 50 https://github.com/user/large-repo.git

# 浅克隆指定分支
git clone --depth 1 --branch main https://github.com/user/repo.git

浅克隆的限制:

  • 无法访问完整历史(git log 显示有限)
  • 某些 git 操作(如 rebase 到更早提交)可能失败
  • 不适合需要完整历史的开发工作

将浅克隆转为完整克隆:

bash
# 获取完整历史
git fetch --unshallow

# 或者逐步加深
git fetch --depth=100   # 获取最近 100 个提交

部分克隆:git clone --filter

部分克隆(Partial Clone)只下载需要的对象,按需获取其他对象(Git 2.19+):

bash
# 不下载 Blob 对象(文件内容),按需获取
git clone --filter=blob:none https://github.com/user/repo.git

# 不下载 Tree 和 Blob 对象(更激进)
git clone --filter=tree:0 https://github.com/user/repo.git

# 不下载大于 1MB 的 Blob
git clone --filter=blob:limit=1m https://github.com/user/repo.git

部分克隆适合:

  • 仓库中有大量历史大文件(如图片、视频)
  • 只需要最新版本,不需要完整历史
  • CI/CD 环境的快速克隆
bash
# CI/CD 推荐配置(浅克隆 + 部分克隆)
git clone --depth 1 --filter=blob:none --no-checkout https://github.com/user/repo.git
cd repo
git checkout main

稀疏检出:git sparse-checkout

稀疏检出(Sparse Checkout)只检出仓库的部分目录,适合 Monorepo 场景:

bash
# 启用稀疏检出
git clone --no-checkout https://github.com/user/monorepo.git
cd monorepo
git sparse-checkout init --cone

# 指定要检出的目录
git sparse-checkout set packages/frontend
git sparse-checkout set packages/shared

# 添加更多目录
git sparse-checkout add packages/backend

# 查看当前配置
git sparse-checkout list

# 检出文件
git checkout main

# 禁用稀疏检出(检出所有文件)
git sparse-checkout disable

稀疏检出(非 cone 模式,支持 glob 模式):

bash
git sparse-checkout init
git sparse-checkout set '/*' '!/packages' '/packages/frontend'

单分支克隆:--single-branch

只克隆单个分支,减少远程分支的下载:

bash
# 只克隆 main 分支
git clone --single-branch --branch main https://github.com/user/repo.git

# 配合浅克隆
git clone --depth 1 --single-branch --branch main https://github.com/user/repo.git

# 之后如果需要其他分支
git remote set-branches origin '*'
git fetch origin

git maintenance 自动维护

Git 2.31+ 提供了专门的维护命令,定期优化仓库性能:

bash
# 启动定时后台维护任务
git maintenance start

# 手动运行维护
git maintenance run

# 运行特定任务
git maintenance run --task=commit-graph    # 优化 git log 速度
git maintenance run --task=incremental-repack  # 增量打包
git maintenance run --task=loose-objects   # 打包松散对象
git maintenance run --task=prefetch        # 后台预获取

# 停止自动维护
git maintenance stop

commit-graph 的优化效果:

bash
# 手动写入 commit-graph(加速 git log、git status 等操作)
git commit-graph write --reachable

# 验证
git commit-graph verify

Git LFS(Large File Storage)

Git LFS 将大文件存储在专用的 LFS 服务器上,Git 仓库只保存指针:

安装

bash
# macOS
brew install git-lfs

# Ubuntu/Debian
sudo apt install git-lfs

# 初始化(每个用户只需一次)
git lfs install

配置追踪大文件类型

bash
# 追踪特定文件类型
git lfs track "*.mp4"
git lfs track "*.zip"
git lfs track "*.pdf"
git lfs track "*.psd"
git lfs track "*.ai"
git lfs track "design/**"

# 查看当前追踪配置
git lfs track

# 这会更新 .gitattributes 文件
cat .gitattributes
# *.mp4 filter=lfs diff=lfs merge=lfs -text
# *.zip filter=lfs diff=lfs merge=lfs -text
bash
# 提交 .gitattributes
git add .gitattributes
git commit -m "chore: 配置 Git LFS 追踪大文件"

使用 LFS

bash
# 添加大文件(自动使用 LFS 存储)
git add video.mp4
git commit -m "feat: 添加演示视频"
git push

# 查看 LFS 管理的文件
git lfs ls-files

# 查看 LFS 文件状态
git lfs status

迁移已有大文件到 LFS

bash
# 迁移历史中所有 .mp4 文件到 LFS
git lfs migrate import --include="*.mp4" --everything

# 只迁移未推送的提交
git lfs migrate import --include="*.mp4"

# 推送(包括 LFS 对象)
git push --all

LFS 的注意事项

bash
# 克隆包含 LFS 文件的仓库(自动下载 LFS 文件)
git clone https://github.com/user/repo.git

# 如果 LFS 文件下载失败,手动拉取
git lfs pull

# 不下载 LFS 文件(只获取指针)
GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/user/repo.git

# 之后需要时下载
git lfs pull --include="*.mp4"

性能对比

优化策略减少克隆大小减少克隆时间操作影响
--depth 1无法访问完整历史
--filter=blob:none按需下载文件内容
--single-branch只有一个分支
sparse-checkout只检出部分目录
Git LFS高(历史中)需要 LFS 服务器
git maintenance优化本地操作速度

总结

场景推荐方案
CI/CD 快速构建--depth 1 --filter=blob:none
Monorepo 开发sparse-checkout
历史中有大量大文件Git LFS 迁移
日常操作缓慢git maintenance start
只需最新代码--depth 1 --single-branch