Как клонировать, извлекать или разреженно проверять отдельный каталог или список каталогов из репозитория git?

Как клонировать, извлекать или разреженно проверять один файл или каталог или список файлов или каталогов из репозитория git, избегая загрузки всей истории или, по крайней мере, сохраняя загрузку истории как минимум?

Для удобства людей, попадающих сюда, это ссылки на другие похожие вопросы:

Эти похожие вопросы были заданы около 10 лет назад, и с тех пор git развивался, что в конечном итоге привело к потоку разных ответов, некоторые лучше, некоторые хуже, в зависимости от рассматриваемой версии git. Проблема в том, что ни один ответ из этих вышеупомянутых вопросов не соответствует всем требованиям из этих вопросов вместе взятых, а это означает, что вы должны прочитать все ответы и составить в своей голове свой собственный ответ, который в конечном итоге соответствует всем требованиям.

Этот вопрос здесь расширяет ранее упомянутые вопросы, налагая более гибкие и строгие требования, чем другие вопросы вместе взятые.

2 ответа

Решение

Этот bash функция ниже делает свое дело.

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
        local path="" # local scope
        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
}

Это пример того, как его использовать:

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
}

В приведенном выше примере обратите внимание, что за каталогом должен следовать /* и должен быть заключен в одинарные или двойные кавычки.

Если вам нужны только файлы без истории, вы можете использовать svn:

      SUBDIR=foo
svn export https://github.com/repository.git/trunk/$SUBDIR
Другие вопросы по тегам