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

/finisht
/static

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

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

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


当前回答

@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 2.19开始,这终于是可能的,从这个答案中可以看出。

考虑对这个答案投赞成票。

注意:在Git2.19中,只实现了客户端支持,服务器端支持仍然缺失,因此它只在克隆本地存储库时有效。还要注意,大型Git宿主(例如GitHub)实际上并不使用Git服务器,而是使用自己的实现,因此即使Git服务器中显示了支持,也不会自动表示它在Git宿主上运行。(OTOH,因为他们不使用Git服务器,所以在Git服务器出现之前,他们可以在自己的实现中更快地实现它。)


不,这在Git中是不可能的。

在Git中实现这样的东西将是一项巨大的努力,这意味着客户端存储库的完整性将无法再得到保证。如果您感兴趣,请在gitmailinglist上搜索有关“稀疏克隆”和“稀疏获取”的讨论。

一般来说,Git社区的共识是,如果您有几个目录总是独立检出,那么这是两个不同的项目,应该存在于两个不同存储库中。您可以使用Git子模块将它们粘在一起。

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

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

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

上面有很多好的想法和脚本。我情不自禁地将它们组合成一个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

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

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

你只需要文件夹名

wpm/*

总之,你要这样做

git config core.sparsecheckout true

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

wpm/*

保存并运行checkout命令

git checkout master

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

对于其他只想从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
}

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