何谓稀疏检出
稀疏检出(git-sparse-checkout ),是git大仓库的性能优化手段之一,除了之前讲的git LFS大文件存储,还可以进行稀疏检出,只检出仓库中的一部分资源,来提高效率。而此特性是在git的2.25版本开始启用,本文主要为应用角度来解释此特性,一些更为细节和深入的内容在参考资料中可以查阅。
如何使用稀疏检出
'git sparse-checkout <subcommand> [<options>]'
设置稀疏检出模式
首先非checkout方式克隆项目,然后cd到项目目录
git clone --no-checkout git地址
启用稀疏检出模式
git sparse-checkout init --cone
在此特性之前,有其他的hack手段来启用,如使用echo "examples/*" >> .git/info/sparse-checkout等方式来使用稀疏检出,但是这种方式首先
是非官方的特性,并且操作了底层的.git目录,易用性也较差,而init --cone则是在git底层中封装这些操作git底层对象的命令,更为安全和易用。
设置稀疏检出的内容
根据要检出的内容来设置,如一个使用monorepo管理的项目,包含了front_end,database等,而前端开发人员只需要在front_end下进行开发调试,因此可以设置front_end作为检出的内容,其他目录不检出,如果想同时检出多个目录,也可以设置,如下
git sparse-checkout set front_end(要检出的目录,可以填写多个,使用空格隔开)
设置后的目录,可以通过以下命令进行查看
git sparse-checkout list
拉取以及修改提交代码
在前面设置成功之后,后续的checkout,add,commit等操作跟之前的使用的git操作是一致的
稀疏检出和部分克隆
“部分克隆”(Partial Clone)功能也是是对 Git 的性能优化,它允许 Git 在没有存储库的完整副本的情况下运行。这项工作的目标是让 Git 更好地处理非常大的存储库。
因为在一般的git clone的过程中,会下载所有的内容和历史记录,但是很多情况下,我们并不需要这些历史记录或者blob对象,因此部分克隆可以做到只克隆部分内容,但是部分克隆需要git server支持,github是默认支持此配置,但是一些内网下的gitlab,有可能不支持此特性。
如下,不检出blob对象
git clone --filter=blob:none --no-checkout https://github.com/derrickstolee/sparse-checkout-example
而稀疏检出和部分克隆是相辅相成的,作用于不同的层次。稀疏检出依然会下载所有的git底层对象,而部分克隆则可以根据--filter的配置来按需下载git底层对象,因此一般我们都是采用两者结合的方式。
monorepo应用
现代很多项目都使用了monorepo方式来管理,这会导致仓库越来越大,因此使用稀疏检出模式,可以提高git操作的效率。具体的使用方式和上述的相同, 这里就不赘述了。
自定义检出脚本
简便使用稀疏检出的shell脚本 使用方式 ./xxxx.sh git路径 要检出的路径
#!/bin/bash
GIT_REPO=${1}
DEST_PATH=${2}
GIT_LIB_NAME=''
function checkGitVersion {
git_version=$(git --version)
version=`echo $git_version | awk '{print $3}'`
echo $version
# 判断version,如果大于2.25.0则支持稀疏检出特性,否则抛出错误
if [ '$version' '>' '2.25.0' ]; then
return 1
else
return 1
echo git的版本${version}过低 请升级到2.27.0及以上版本
exit
fi
}
function generateName {
GIT_LIB_NAME=`echo ${GIT_REPO} | awk -F/ '{print $2}' | awk -F. '{print $1}'`
return 1
}
function main {
# 检测git版本
checkGitVersion
# 获取文件名
generateName
# 清理文件目录后进入克隆项目
rm -rf ${GIT_LIB_NAME}/
# 开启稀疏检查特性
git clone --filter=blob:none --no-checkout ${GIT_REPO} ${GIT_LIB_NAME}
wait
echo 克隆完成 进入要检测的文件路径进行checkout
# cd进去要克隆的子路径,进行checkout
cd ${GIT_LIB_NAME}
git sparse-checkout init --cone
git sparse-checkout set ${DEST_PATH}
git checkout main
wait
echo 完成项目导入
}
main