Skip to content

浅层克隆

概述

浅层克隆(Shallow Clone)是一种只获取最近几次提交历史的克隆方式,可以显著减少下载时间和磁盘空间占用。

什么是浅层克隆

浅层克隆通过 --depth 参数限制克隆的提交深度:

  • 只下载指定深度的提交历史
  • 减少网络传输和磁盘占用
  • 适合只需要最新代码的场景

对比

克隆类型命令历史记录大小
完整克隆git clone完整历史最大
浅层克隆git clone --depth 1最近 N 次提交最小
单分支克隆git clone --single-branch单分支历史中等

git clone --depth

基本用法

bash
# 克隆最近 1 次提交
git clone --depth 1 https://github.com/user/repo.git

# 克隆最近 10 次提交
git clone --depth 10 https://github.com/user/repo.git

# 克隆最近 50 次提交
git clone --depth 50 https://github.com/user/repo.git

结合其他选项

bash
# 浅层克隆 + 单分支
git clone --depth 1 --single-branch --branch main https://github.com/user/repo.git

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

# 浅层克隆 + 指定目录
git clone --depth 1 https://github.com/user/repo.git my-project

# 浅层克隆 + 递归子模块
git clone --depth 1 --recursive https://github.com/user/repo.git

查看浅层克隆信息

bash
# 查看是否是浅层克隆
git rev-parse --is-shallow-repository

# 查看浅层深度
git config core.shallow

# 查看浅层提交
cat .git/shallow

浅层克隆限制

功能限制

bash
# 无法查看完整历史
git log --oneline
# 只显示浅层深度内的提交

# 无法比较历史提交
git diff HEAD~10
# 错误:提交不存在

# 无法创建某些分支
git checkout -b feature HEAD~5
# 错误:提交不存在

# blame 可能不完整
git blame file.txt
# 可能无法追溯到完整历史

操作限制

bash
# 无法推送到某些远程
git push origin --all
# 可能失败

# 无法变基到浅层历史之外
git rebase HEAD~10
# 错误:提交不存在

# 某些合并操作受限
git merge origin/feature
# 可能需要完整历史

子模块限制

bash
# 子模块也需要单独设置浅层
git submodule update --init --depth 1

# 或者在 .gitmodules 中配置
[submodule "libs/library"]
    path = libs/library
    url = https://github.com/user/library.git
    shallow = true

转换为完整仓库

方法一:unshallow

bash
# 转换为完整仓库
git fetch --unshallow

# 这会获取完整的历史记录

方法二:增加深度

bash
# 增加历史深度
git fetch --depth=100

# 继续增加
git fetch --depth=500

# 最终获取完整历史
git fetch --unshallow

方法三:重新克隆

bash
# 备份当前修改
git stash

# 重新完整克隆
git clone https://github.com/user/repo.git repo-full

# 应用修改
cd repo-full
git stash pop /path/to/old/repo/.git/stash

方法四:从 bundle 恢复

bash
# 如果有完整仓库的 bundle
git bundle unbundle full-history.bundle

# 获取历史
git fetch origin main

浅层克隆工作流程

场景一:CI/CD 构建

bash
# CI 中使用浅层克隆加速
git clone --depth 1 https://github.com/user/repo.git
cd repo
npm install
npm run build
yaml
# GitHub Actions
steps:
  - uses: actions/checkout@v3
    with:
      fetch-depth: 1  # 浅层克隆

场景二:部署应用

bash
# 部署时只需要最新代码
git clone --depth 1 --branch v1.0.0 https://github.com/user/repo.git
cd repo
./deploy.sh

场景三:快速查看项目

bash
# 快速克隆查看代码
git clone --depth 1 https://github.com/user/repo.git
cd repo
# 浏览代码...

场景四:贡献代码

bash
# 1. 浅层克隆
git clone --depth 1 https://github.com/user/repo.git
cd repo

# 2. 创建功能分支
git checkout -b feature

# 3. 进行修改
vim src/file.js
git add .
git commit -m "添加新功能"

# 4. 如果需要完整历史(如需要变基)
git fetch --unshallow

# 5. 推送分支
git push origin feature

深度管理

查看当前深度

bash
# 查看浅层文件
cat .git/shallow

# 查看提交数量
git rev-list --count HEAD

# 查看可访问的提交
git log --oneline | wc -l

调整深度

bash
# 增加深度到 50
git fetch --depth=50

# 增加深度到 100
git fetch --depth=100

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

# 获取特定提交
git fetch --depth=1 origin <commit-hash>

按日期获取

bash
# 获取特定日期以来的历史
git clone --shallow-since="2024-01-01" https://github.com/user/repo.git

# 获取最近 30 天的历史
git clone --shallow-since="30 days ago" https://github.com/user/repo.git

# 获取特定时间范围
git fetch --shallow-since="2024-01-01" --shallow-exclude="v1.0.0"

按排除标签获取

bash
# 获取到某个标签之前的历史
git clone --shallow-exclude=v1.0.0 https://github.com/user/repo.git

# 获取多个标签之外的历史
git fetch --shallow-exclude=v1.0.0 --shallow-exclude=v2.0.0

浅层克隆与远程操作

推送浅层克隆

bash
# 浅层克隆可以推送
git clone --depth 1 https://github.com/user/repo.git
cd repo
git checkout -b feature
git commit --allow-empty -m "新提交"
git push origin feature

# 但推送所有分支可能失败
git push --all origin
# 需要先 unshallow

拉取更新

bash
# 浅层克隆可以正常拉取
git pull origin main

# 但只能获取浅层深度内的更新
# 如果远程有大量新提交,可能需要增加深度

获取特定提交

bash
# 获取特定提交
git fetch origin <commit-hash>

# 获取特定标签
git fetch origin tag v1.0.0

# 获取特定分支
git fetch origin feature

性能对比

克隆时间对比

bash
# 完整克隆
time git clone https://github.com/torvalds/linux.git
# 实际时间:约 30 分钟

# 浅层克隆
time git clone --depth 1 https://github.com/torvalds/linux.git
# 实际时间:约 2 分钟

磁盘空间对比

bash
# 完整克隆
du -sh linux
# 约 3.5 GB

# 浅层克隆
du -sh linux-shallow
# 约 200 MB

操作速度对比

bash
# 完整克隆中的 git log
time git log --oneline | wc -l
# 约 1 秒

# 浅层克隆中的 git log
time git log --oneline | wc -l
# 约 0.1 秒

最佳实践

1. CI/CD 中使用浅层克隆

yaml
# GitHub Actions
steps:
  - uses: actions/checkout@v3
    with:
      fetch-depth: 1

# GitLab CI
variables:
  GIT_DEPTH: 1

# Jenkins
options {
  checkoutToSubdirectory('src')
}

2. 部署脚本

bash
#!/bin/bash
# deploy.sh

REPO_URL="https://github.com/user/repo.git"
DEPLOY_DIR="/var/www/app"
BRANCH="main"

# 浅层克隆
if [ ! -d "$DEPLOY_DIR/.git" ]; then
    git clone --depth 1 --branch $BRANCH $REPO_URL $DEPLOY_DIR
else
    cd $DEPLOY_DIR
    git fetch --depth 1 origin $BRANCH
    git reset --hard origin/$BRANCH
fi

# 部署
cd $DEPLOY_DIR
npm install --production
npm run migrate
pm2 restart app

3. 开发者工作流

bash
# 快速开始
git clone --depth 1 https://github.com/company/project.git
cd project

# 需要完整历史时再获取
git fetch --unshallow

# 或者按需获取
git fetch --depth=100

4. 处理子模块

bash
# 克隆时处理子模块
git clone --depth 1 --recursive https://github.com/user/repo.git

# 或分步处理
git clone --depth 1 https://github.com/user/repo.git
cd repo
git submodule update --init --depth 1

常见问题

Q: 浅层克隆后如何查看完整历史?

bash
# 转换为完整仓库
git fetch --unshallow

# 然后可以查看完整历史
git log --oneline

Q: 浅层克隆如何变基?

bash
# 需要先获取足够的历史
git fetch --depth=50

# 然后可以变基
git rebase HEAD~10

Q: 浅层克隆如何解决合并冲突?

bash
# 如果冲突涉及浅层外的历史
git fetch --unshallow

# 或者获取特定提交
git fetch origin <commit-hash>

# 然后解决冲突
git merge origin/feature

Q: 如何判断仓库是否是浅层克隆?

bash
# 方法一
git rev-parse --is-shallow-repository

# 方法二
test -f .git/shallow && echo "浅层克隆" || echo "完整克隆"

# 方法三
git config --get core.shallow

总结

操作命令说明
浅层克隆git clone --depth 1 <url>克隆最近 1 次提交
增加深度git fetch --depth=N增加历史深度
转换完整git fetch --unshallow转换为完整仓库
按日期克隆git clone --shallow-since="date"按日期限制历史

使用建议

  • CI/CD 构建使用浅层克隆
  • 部署时使用浅层克隆
  • 开发时按需获取完整历史
  • 大仓库优先考虑浅层克隆