Appearance
浅层克隆
概述
浅层克隆(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 buildyaml
# 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 app3. 开发者工作流
bash
# 快速开始
git clone --depth 1 https://github.com/company/project.git
cd project
# 需要完整历史时再获取
git fetch --unshallow
# 或者按需获取
git fetch --depth=1004. 处理子模块
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 --onelineQ: 浅层克隆如何变基?
bash
# 需要先获取足够的历史
git fetch --depth=50
# 然后可以变基
git rebase HEAD~10Q: 浅层克隆如何解决合并冲突?
bash
# 如果冲突涉及浅层外的历史
git fetch --unshallow
# 或者获取特定提交
git fetch origin <commit-hash>
# 然后解决冲突
git merge origin/featureQ: 如何判断仓库是否是浅层克隆?
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 构建使用浅层克隆
- 部署时使用浅层克隆
- 开发时按需获取完整历史
- 大仓库优先考虑浅层克隆
