如何从 git 存储库克隆、获取或稀疏签出单个目录或目录列表?
How do I clone, fetch or sparse checkout a single directory or a list of directories from git repository?
如何从 git 存储库克隆、获取或稀疏检出单个文件或目录或文件或目录列表,避免下载整个历史记录或至少保持历史下载最少?
为了登陆这里的人的利益,这些是对其他类似问题的参考:
- How do I clone a subdirectory only of a Git repository?
- How to sparsely checkout only one single file from a git repository?
- Is it possible to do a sparse checkout without checking out the whole repository first?
很久以前就有人问过这些类似的问题,git 从那以后就不断演变,最终导致大量不同的答案,有的更好,有的更糟,这取决于所考虑的 git 版本.麻烦的是,上述这些问题中没有一个答案可以满足所有这些问题的所有要求,这意味着您必须阅读所有答案并在脑海中编写自己的答案,最终满足所有要求。
这里的这个问题扩展了前面提到的问题,比所有其他问题的总和提出了更灵活和严格的要求。所以,再一次:
如何从 git 存储库克隆、获取或稀疏检出单个文件或目录或文件或目录列表,避免下载整个历史记录或至少保持历史下载最少?
下面这个 bash
函数可以解决问题。
function git_sparse_checkout {
# git repository, e.g.: http://github.com/frgomes/bash-scripts
local url=
# directory where the repository will be downloaded, e.g.: ./build/sources
local dir=
# repository name, in general taken from the url, e.g.: bash-scripts
local prj=
# tag, e.g.: master
local tag=
[[ ( -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)/sources
prj=bash-scripts
tag=master
git_sparse_checkout $url $dir $prj $tag "user-install/*" sysadmin-install/install-emacs.sh
}
在上面的例子中,注意目录后面必须跟/*
并且必须在单引号或双引号之间。
更新:可以在以下位置找到改进版本:https://github.com/frgomes/bash-scripts/blob/master/bin/git_sparse_checkout
如果你只想要没有历史记录的文件,你可以使用 svn:
SUBDIR=foo
svn export https://github.com/repository.git/trunk/$SUBDIR
如何从 git 存储库克隆、获取或稀疏检出单个文件或目录或文件或目录列表,避免下载整个历史记录或至少保持历史下载最少?
为了登陆这里的人的利益,这些是对其他类似问题的参考:
- How do I clone a subdirectory only of a Git repository?
- How to sparsely checkout only one single file from a git repository?
- Is it possible to do a sparse checkout without checking out the whole repository first?
很久以前就有人问过这些类似的问题,git 从那以后就不断演变,最终导致大量不同的答案,有的更好,有的更糟,这取决于所考虑的 git 版本.麻烦的是,上述这些问题中没有一个答案可以满足所有这些问题的所有要求,这意味着您必须阅读所有答案并在脑海中编写自己的答案,最终满足所有要求。
这里的这个问题扩展了前面提到的问题,比所有其他问题的总和提出了更灵活和严格的要求。所以,再一次:
如何从 git 存储库克隆、获取或稀疏检出单个文件或目录或文件或目录列表,避免下载整个历史记录或至少保持历史下载最少?
下面这个 bash
函数可以解决问题。
function git_sparse_checkout {
# git repository, e.g.: http://github.com/frgomes/bash-scripts
local url=
# directory where the repository will be downloaded, e.g.: ./build/sources
local dir=
# repository name, in general taken from the url, e.g.: bash-scripts
local prj=
# tag, e.g.: master
local tag=
[[ ( -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)/sources
prj=bash-scripts
tag=master
git_sparse_checkout $url $dir $prj $tag "user-install/*" sysadmin-install/install-emacs.sh
}
在上面的例子中,注意目录后面必须跟/*
并且必须在单引号或双引号之间。
更新:可以在以下位置找到改进版本:https://github.com/frgomes/bash-scripts/blob/master/bin/git_sparse_checkout
如果你只想要没有历史记录的文件,你可以使用 svn:
SUBDIR=foo
svn export https://github.com/repository.git/trunk/$SUBDIR