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

/finisht
/static

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

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

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


当前回答

虽然我讨厌在处理git repos时使用svn:/我一直使用这个;

function git-scp() (
  URL="$1" && shift 1
  svn export ${URL/blob\/master/trunk}
)

这允许您无需修改即可从github url中复制。用法

--- /tmp » git-scp https://github.com/dgraph-io/dgraph/blob/master/contrib/config/kubernetes/helm                                                                                                                  1 ↵
A    helm
A    helm/Chart.yaml
A    helm/README.md
A    helm/values.yaml
Exported revision 6367.

--- /tmp » ls | grep helm
Permissions Size User    Date Modified    Name
drwxr-xr-x     - anthony 2020-01-07 15:53 helm/

其他回答

您正在尝试做的是所谓的稀疏签出,这一功能是在Git1.7.0(2012年2月)中添加的。执行稀疏克隆的步骤如下:

mkdir <repo>
cd <repo>
git init
git remote add -f origin <url>

这将使用远程设备创建一个空的存储库,并获取所有对象,但不会检出它们。然后执行以下操作:

git config core.sparseCheckout true

现在,您需要定义要实际检出的文件/文件夹。这是通过在.git/info/spease checkout中列出它们来完成的,例如:

echo "some/dir/" >> .git/info/sparse-checkout
echo "another/sub/tree" >> .git/info/sparse-checkout

最后但同样重要的是,使用远程状态更新空回购:

git pull origin master

现在,文件系统上的一些/dir和另一个/sub/tree的文件将被“检出”(这些路径仍然存在),而没有其他路径。

您可能想看一下扩展教程,可能应该阅读有关稀疏签出和读取树的官方文档。

作为一项功能:

function git_sparse_clone() (
  rurl="$1" localdir="$2" && shift 2

  mkdir -p "$localdir"
  cd "$localdir"

  git init
  git remote add -f origin "$rurl"

  git config core.sparseCheckout true

  # Loops over remaining args
  for i; do
    echo "$i" >> .git/info/sparse-checkout
  done

  git pull origin master
)

用法:

git_sparse_clone "http://github.com/tj/n" "./local/location" "/bin"

请注意,这仍然会从服务器下载整个存储库–只有签出的大小减小了。目前,仅克隆一个目录是不可能的。但如果您不需要存储库的历史记录,至少可以通过创建浅层克隆来节省带宽。有关如何结合浅层克隆和稀疏检出的信息,请参阅下面的udondan答案。


截至Git 2.25.0(2020年1月),Git中添加了一个实验性稀疏校验命令:

git sparse-checkout init
# same as:
# git config core.sparseCheckout true

git sparse-checkout set "A/B"
# same as:
# echo "A/B" >> .git/info/sparse-checkout

git sparse-checkout list
# same as:
# cat .git/info/sparse-checkout

如果您实际上只对目录的最新修订文件感兴趣,Github允许您下载一个不包含历史记录的Zip文件形式的存储库。所以下载速度要快得多。

使用Linux?并且只想要容易访问和清理工作树?而不必麻烦机器上的其他代码。尝试符号链接!

git clone https://github.com:{user}/{repo}.git ~/my-project
ln -s ~/my-project/my-subfolder ~/Desktop/my-subfolder

测验

cd ~/Desktop/my-subfolder
git status

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

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%