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

/finisht
/static

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

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

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


当前回答

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%

其他回答

所以我尝试了这一切,但没有任何效果。。。事实证明,在Git的2.24版本(在回答这个问题时随cpanel提供的版本)上,您不需要这样做

echo "wpm/*" >> .git/info/sparse-checkout

你只需要文件夹名

wpm/*

总之,你要这样做

git config core.sparsecheckout true

然后编辑.git/info/spease签出并在末尾添加带有/*的文件夹名称(每行一个)以获取子文件夹和文件

wpm/*

保存并运行checkout命令

git checkout master

结果是我的存储库中的预期文件夹,没有其他内容如果这对你有用,请投票

git init <repo>
cd <repo>
git remote add origin <url>
git config core.sparsecheckout true
echo "<path you want to clone>/*" >> .git/info/sparse-checkout
git pull --depth=1 origin <branch you want to fetch>

仅从此回购中克隆Jetsurvey文件夹的示例

git init MyFolder
cd MyFolder 
git remote add origin git@github.com:android/compose-samples.git
git config core.sparsecheckout true
echo "Jetsurvey/*" >> .git/info/sparse-checkout
git pull --depth=1 origin main

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

@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进行测试。

如果您从未计划与从中克隆的存储库交互,则可以执行完整的git克隆并使用

git filter-branch --subdirectory-filter <subdirectory>

这样,至少历史会被保存下来。