How do I clone, fetch or sparse checkout a single directory or a list of directories from git repository?

流过昼夜 提交于 2020-02-15 06:42:04

问题


How do I clone, fetch or sparse checkout a single file or directory or a list of files or directories from a git repository avoiding downloading the entire history or at least keeping history download at minimum?

For the benefit of people landing here, these are references to other similar questions:

  • How do I clone a subdirectory only of a Git repository?
  • How to sparsely checkout only one single file from a git repository?

These similar questions were asked some 10 years ago and git evolved ever since, which ended up causing a flood of different answers, some better, some worse, depending on the version of git being considered, but none of them attending all requirements from these other questions combined.

This question here expands on previous questions mentioned, imposing more stringent requirements than other questions combined.


回答1:


This bash function below does the trick.

function git_sparse_checkout {
    # git repository, e.g.: http://github.com/frgomes/bash-scripts
    local url=$1
    # directory where the repository will be downloaded, e.g.: ./build/sources
    local dir=$2
    # repository name, in general taken from the url, e.g.: bash-scripts
    local prj=$3
    # tag, e.g.: master
    local tag=$4
    [[ ( -z "$url" ) || ( -z "$dir" ) || ( -z "$prj" ) || ( -z "$tag" ) ]] && \
        echo "ERROR: git_sparse_checkout: invalid arguments" && \
        return 1
    shift; shift; shift; shift

    # Note: any remaining arguments after these above are considered as a
    # list of files or directories to be downloaded.

    mkdir -p ${dir}
    if [ ! -d ${dir}/${prj} ] ;then
        mkdir -p ${dir}/${prj}
        pushd ${dir}/${prj}
        git init
        git config core.sparseCheckout true
        for path in $* ;do
            echo "${path}" >> .git/info/sparse-checkout
        done
        git remote add origin ${url}
        git fetch --depth=1 origin ${tag}
        git checkout ${tag}
        popd
    fi
}

This is an example of how to use it:

function example_download_scripts {
  url=http://github.com/frgomes/bash-scripts
  dir=$(pwd)/build/sources
  prj=bash-scripts
  tag=master
  git_sparse_checkout $url $dir $prj $tag "user-install/*" sysadmin-install/install-emacs.sh
}

In the example above, notice that a directory must be followed by /* and must be between single quotes or double quotes.



来源:https://stackoverflow.com/questions/60190759/how-do-i-clone-fetch-or-sparse-checkout-a-single-directory-or-a-list-of-directo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!