git的稀疏检出初探

2,408 阅读3分钟

何谓稀疏检出

稀疏检出(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 

参考资料

git-sparse-checkout-sample

Bring your monorepo down to size with sparse-checkout

部分克隆-git文档

稀疏导出-git文档