我的Git存储库在根目录下有两个子目录:

/finisht
/static

当这是在SVN中时,/finisht在一个地方签出,而/static在其他地方签出了,如下所示:

svn co svn+ssh://admin@domain.example/home/admin/repos/finisht/static static

有没有办法用Git做到这一点?


当前回答

仅使用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稀疏签出。签出分支(例如主分支):切换到主分支

现在,您应该在当前目录中选择了文件夹。

如果有太多级别的目录或过滤分支,可以考虑使用符号链接。


其他回答

对于其他只想从github下载文件/文件夹的用户,只需使用:

svn export <repo>/trunk/<folder>

e.g.

svn export https://github.com/lodash/lodash.com/trunk/docs

(是的,这里是svn。显然在2016年,您仍然需要svn来下载一些github文件)

提供:从GitHub repo下载单个文件夹或目录

重要信息-请确保更新github URL并将/tree/master/替换为'trunk/'。

作为bash脚本:

git-download(){
    folder=${@/tree\/master/trunk}
    folder=${folder/blob\/master/trunk}
    svn export $folder
}

笔记此方法下载文件夹,但不克隆/签出它。您不能将更改推回到存储库。另一方面,与稀疏签出或浅签出相比,这导致下载量较小。

我不知道是否有人成功拉取了特定目录,这是我的经验:gitclone--filter=blob:none--singlebranch<repo>,下载对象时立即取消,输入repo,然后gitcheckoutorigin/master<dir>,忽略错误(sha1),输入dir,对每个子目录重复签出(使用新的dir)。我设法以这种方式快速获取源文件

对于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 "$@"

您可以结合稀疏检出和浅层克隆功能。浅层克隆会切断历史记录,稀疏签出只会提取与模式匹配的文件。

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存档中是不可能的。

您仍然可以使用svn:

svn export https://admin@domain.example/home/admin/repos/finisht/static static --force

到“gitclone”子目录,然后到“gitpull”子目录。

(并非旨在提交和推送。)