我的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做到这一点?
当前回答
对于macOS用户
对于zsh用户(特别是macOS用户)使用ssh克隆Repos,我只需要根据@Ciro Santilli的回答创建一个zsh命令:
要求:git的版本很重要。由于--sparse选项,它在2.25.1上不起作用。尝试将git升级到最新版本。(例如测试2.36.1)
示例用法:
git clone git@github.com:google-research/google-research.git etcmodel
代码:
function gitclone {
readonly repo_root=${1?Usage: gitclone repo.git sub_dir}
readonly repo_sub=${2?Usage: gitclone repo.git sub_dir}
echo "-- Cloning $repo_root/$repo_sub"
git clone \
--depth 1 \
--filter=tree:0 \
--sparse \
$repo_root \
;
repo_folder=${repo_root#*/}
repo_folder=${repo_folder%.*}
cd $repo_folder
git sparse-checkout set $repo_sub
cd -
}
gitclone "$@"
其他回答
下面是我为单个子目录稀疏签出用例编写的shell脚本
co子目录.sh
localRepo=$1
remoteRepo=$2
subDir=$3
# Create local repository for subdirectory checkout, make it hidden to avoid having to drill down to the subfolder
mkdir ./.$localRepo
cd ./.$localRepo
git init
git remote add -f origin $remoteRepo
git config core.sparseCheckout true
# Add the subdirectory of interest to the sparse checkout.
echo $subDir >> .git/info/sparse-checkout
git pull origin master
# Create convenience symlink to the subdirectory of interest
cd ..
ln -s ./.$localRepo/$subDir $localRepo
我为执行“稀疏签出”编写了.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
仅使用Git是不可能克隆子目录的,但以下是一些解决方法。
过滤器分支
您可能希望重写存储库,使其看起来像trunk/public_html/是它的项目根,并放弃所有其他历史记录(使用过滤器分支),尝试已经签出的分支:
git filter-branch --subdirectory-filter trunk/public_html -- --all
注意:--将筛选器分支选项与修订选项分开,--all用于重写所有分支和标记。将保留所有信息,包括原始提交时间或合并信息。此命令接受refs/replace/namespace中的.git/info/places文件和ref,因此如果定义了任何移植或替换ref,运行此命令将使其永久化。
警告重写的历史将对所有对象具有不同的对象名称,并且不会与原始分支汇合。您将无法在原始分支的顶部轻松推送和分发重写的分支。如果您不知道完整的含义,请不要使用此命令,如果一次简单的提交就足以解决您的问题,请避免使用它。
稀疏校验
以下是稀疏签出方法的简单步骤,它将稀疏地填充工作目录,因此您可以告诉Git工作目录中的哪个文件夹或文件值得签出。
照常克隆存储库(--不选择签出):gitclone--不签出git@foo/巴.吉特cd条如果已经克隆了存储库,则可以跳过此步骤。提示:对于大型回购,请考虑浅层克隆(--depth 1)以仅签出最新版本或/和--仅签出单个分支。启用spareCheckout选项:git-config-core.sparseCheckout true指定用于稀疏签出的文件夹(末尾没有空格):echo“trunk/public_html/*”>.git/info/s稀疏签出或edit.git/info/s稀疏签出。签出分支(例如主分支):切换到主分支
现在,您应该在当前目录中选择了文件夹。
如果有太多级别的目录或过滤分支,可以考虑使用符号链接。
(扩展此答案)
克隆特定标记中的子目录
如果要克隆特定标记的特定子目录,可以执行以下步骤。
我在cxf-3.5.4标签中克隆了cxf github repo的发行版/src/main/release/samples/子目录。
注意:如果您尝试仅克隆上述回购,您将看到它非常大。下面的命令仅克隆所需的内容。
git clone --depth 1 --filter=blob:none --sparse https://github.com/apache/cxf
cd cxf/
git sparse-checkout set distribution/src/main/release/samples/
git fetch --depth 1 origin cxf-3.5.4
# This is the hash on which the tag points, however using the tag does not work.
git switch --detach 3ef4fde
克隆特定分支中的子目录
我在2.6.x-fixes分支中克隆了cxf github repo的发行版/src/main/release/samples/子目录。
git clone --depth 1 --filter=blob:none --sparse https://github.com/apache/cxf --branch 2.6.x-fixes
cd cxf/
git sparse-checkout set distribution/src/main/release/samples/
2022答案
我不知道为什么这个问题有这么多复杂的答案。通过将repo稀疏克隆到所需的文件夹,可以轻松地完成此操作。
导航到要克隆子目录的文件夹。打开cmd并运行以下命令。git clone--filter=blob:none--稀疏%您的git repo url%git稀疏签出添加要克隆的%子目录%cd%您的子目录%
瞧!现在,您只克隆了所需的子目录!
解释-这些命令到底在做什么?
git clone--filter=blob:none--稀疏%您的git repo url%
在上述命令中,
--filter=blob:none=>告诉git您只想克隆元数据文件。通过这种方式,git从远程收集基本的分支详细信息和其他元数据,这将确保您将来从源站顺利签出。--稀疏=>告诉git这是一个稀疏克隆。在这种情况下,Git将只签出根目录。
现在,git被告知元数据,并准备签出您要使用的任何子目录/文件。
git sparse-checkout add gui-workspace ==> Checkout folder
git sparse-checkout add gui-workspace/assets/logo.png ==> Checkout a file
稀疏克隆在具有多个子目录的大型存储库中特别有用,而您并不总是在处理所有子目录。在大型存储库上执行稀疏克隆时,可以节省大量时间和带宽。
此外,现在,在这个部分克隆的repo中,您可以像往常一样继续结账和工作。所有这些命令都能完美工作。
git switch -c %new-branch-name% origin/%parent-branch-name% (or) git checkout -b %new-branch-name% origin/%parent-branch-name%
git commit -m "Initial changes in sparse clone branch"
git push origin %new-branch-name%