我的Git存储库在根目录下有两个子目录:
/finisht
/static
当这是在SVN中时,/finisht在一个地方签出,而/static在其他地方签出了,如下所示:
svn co svn+ssh://admin@domain.example/home/admin/repos/finisht/static static
有没有办法用Git做到这一点?
我的Git存储库在根目录下有两个子目录:
/finisht
/static
当这是在SVN中时,/finisht在一个地方签出,而/static在其他地方签出了,如下所示:
svn co svn+ssh://admin@domain.example/home/admin/repos/finisht/static static
有没有办法用Git做到这一点?
当前回答
我为执行“稀疏签出”编写了.gitconfig[别名]。检查一下(没有双关语):
在Windows上运行cmd.exe
git config --global alias.sparse-checkout "!f(){ [ $# -eq 2 ] && L=${1##*/} L=${L%.git} || L=$2; mkdir -p \"$L/.git/info\" && cd \"$L\" && git init --template= && git remote add origin \"$1\" && git config core.sparseCheckout 1; [ $# -eq 2 ] && echo \"$2\" >> .git/info/sparse-checkout || { shift 2; for i; do echo $i >> .git/info/sparse-checkout; done }; git pull --depth 1 origin master;};f"
否则:
git config --global alias.sparse-checkout '!f(){ [ $# -eq 2 ] && L=${1##*/} L=${L%.git} || L=$2; mkdir -p "$L/.git/info" && cd "$L" && git init --template= && git remote add origin "$1" && git config core.sparseCheckout 1; [ $# -eq 2 ] && echo "$2" >> .git/info/sparse-checkout || { shift 2; for i; do echo $i >> .git/info/sparse-checkout; done }; git pull --depth 1 origin master;};f'
用法:
# Makes a directory ForStackExchange with Plug checked out
git sparse-checkout https://github.com/YenForYang/ForStackExchange Plug
# To do more than 1 directory, you have to specify the local directory:
git sparse-checkout https://github.com/YenForYang/ForStackExchange ForStackExchange Plug Folder
为了方便和存储,git-config命令被“缩小”了,但这里扩展了别名:
# Note the --template= is for disabling templates.
# Feel free to remove it if you don't have issues with them (like I did)
# `mkdir` makes the .git/info directory ahead of time, as I've found it missing sometimes for some reason
f(){
[ "$#" -eq 2 ] && L="${1##*/}" L=${L%.git} || L=$2;
mkdir -p "$L/.git/info"
&& cd "$L"
&& git init --template=
&& git remote add origin "$1"
&& git config core.sparseCheckout 1;
[ "$#" -eq 2 ]
&& echo "$2" >> .git/info/sparse-checkout
|| {
shift 2;
for i; do
echo $i >> .git/info/sparse-checkout;
done
};
git pull --depth 1 origin master;
};
f
其他回答
如果您实际上只对目录的最新修订文件感兴趣,Github允许您下载一个不包含历史记录的Zip文件形式的存储库。所以下载速度要快得多。
您可以结合稀疏检出和浅层克隆功能。浅层克隆会切断历史记录,稀疏签出只会提取与模式匹配的文件。
git init <repo>
cd <repo>
git remote add origin <url>
git config core.sparsecheckout true
echo "finisht/*" >> .git/info/sparse-checkout
git pull --depth=1 origin master
您需要最低1.9吉才能工作。仅使用2.2.0和2.2.2自行测试。
这样,您仍然可以进行推送,这在git存档中是不可能的。
编辑:从Git 2.19开始,这终于是可能的,从这个答案中可以看出。
考虑对这个答案投赞成票。
注意:在Git2.19中,只实现了客户端支持,服务器端支持仍然缺失,因此它只在克隆本地存储库时有效。还要注意,大型Git宿主(例如GitHub)实际上并不使用Git服务器,而是使用自己的实现,因此即使Git服务器中显示了支持,也不会自动表示它在Git宿主上运行。(OTOH,因为他们不使用Git服务器,所以在Git服务器出现之前,他们可以在自己的实现中更快地实现它。)
不,这在Git中是不可能的。
在Git中实现这样的东西将是一项巨大的努力,这意味着客户端存储库的完整性将无法再得到保证。如果您感兴趣,请在gitmailinglist上搜索有关“稀疏克隆”和“稀疏获取”的讨论。
一般来说,Git社区的共识是,如果您有几个目录总是独立检出,那么这是两个不同的项目,应该存在于两个不同存储库中。您可以使用Git子模块将它们粘在一起。
上面有很多好的想法和脚本。我情不自禁地将它们组合成一个bash脚本,并提供帮助和错误检查:
#!/bin/bash
function help {
printf "$1
Clones a specific directory from the master branch of a git repository.
Syntax:
$(basename $0) [--delrepo] repoUrl sourceDirectory [targetDirectory]
If targetDirectory is not specified it will be set to sourceDirectory.
Downloads a sourceDirectory from a Git repository into targetdirectory.
If targetDirectory is not specified, a directory named after `basename sourceDirectory`
will be created under the current directory.
If --delrepo is specified then the .git subdirectory in the clone will be removed after cloning.
Example 1:
Clone the tree/master/django/conf/app_template directory from the master branch of
git@github.com:django/django.git into ./app_template:
\$ $(basename $0) git@github.com:django/django.git django/conf/app_template
\$ ls app_template/django/conf/app_template/
__init__.py-tpl admin.py-tpl apps.py-tpl migrations models.py-tpl tests.py-tpl views.py-tpl
Example 2:
Clone the django/conf/app_template directory from the master branch of
https://github.com/django/django/tree/master/django/conf/app_template into ~/test:
\$ $(basename $0) git@github.com:django/django.git django/conf/app_template ~/test
\$ ls test/django/conf/app_template/
__init__.py-tpl admin.py-tpl apps.py-tpl migrations models.py-tpl tests.py-tpl views.py-tpl
"
exit 1
}
if [ -z "$1" ]; then help "Error: repoUrl was not specified.\n"; fi
if [ -z "$2" ]; then help "Error: sourceDirectory was not specified."; fi
if [ "$1" == --delrepo ]; then
DEL_REPO=true
shift
fi
REPO_URL="$1"
SOURCE_DIRECTORY="$2"
if [ "$3" ]; then
TARGET_DIRECTORY="$3"
else
TARGET_DIRECTORY="$(basename $2)"
fi
echo "Cloning into $TARGET_DIRECTORY"
mkdir -p "$TARGET_DIRECTORY"
cd "$TARGET_DIRECTORY"
git init
git remote add origin -f "$REPO_URL"
git config core.sparseCheckout true
echo "$SOURCE_DIRECTORY" > .git/info/sparse-checkout
git pull --depth=1 origin master
if [ "$DEL_REPO" ]; then rm -rf .git; fi
@Chronial的anwser不再适用于最近的版本,但它是一个有用的Anwsr,因为它提出了一个脚本。
考虑到我收集的信息以及我只想签出分支的子目录这一事实,我创建了以下shell函数。它只获取分支中提供的目录的最新版本的浅拷贝。
function git_sparse_clone_branch() (
rurl="$1" localdir="$2" branch="$3" && shift 3
git clone "$rurl" --branch "$branch" --no-checkout "$localdir" --depth 1 # limit history
cd "$localdir"
# git sparse-checkout init --cone # fetch only root file
# Loops over remaining args
for i; do
git sparse-checkout set "$i"
done
git checkout "$branch"
)
因此,示例使用:
git_sparse_clone_branch git@github.com:user/repo.git localpath branch-to-clone path1_to_fetch path2_to_fetch
在我的案例中,克隆“仅”为23MB,而完整克隆为385MB。
使用git版本2.36.1进行测试。