Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何仅克隆Git存储库的子目录?_Git_Repository_Subdirectory_Git Clone_Sparse Checkout - Fatal编程技术网

如何仅克隆Git存储库的子目录?

如何仅克隆Git存储库的子目录?,git,repository,subdirectory,git-clone,sparse-checkout,Git,Repository,Subdirectory,Git Clone,Sparse Checkout,我有我的Git存储库,它在根目录下有两个子目录: /finisht /static 当它处于中时,/finisht在一个地方签出,而/static在其他地方签出,如下所示: svn co svn+ssh://admin@domain.com/home/admin/repos/finisht/static static 有没有办法用Git做到这一点?编辑:从Git2.19开始,这最终是可能的,如图所示 考虑投票表决这个答案 注意:在Git2.19中,只实现了客户端支持,而服务器端支持仍然缺失,

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

/finisht
/static
当它处于中时,/finisht在一个地方签出,而/static在其他地方签出,如下所示:

svn co svn+ssh://admin@domain.com/home/admin/repos/finisht/static static
有没有办法用Git做到这一点?

编辑:从Git2.19开始,这最终是可能的,如图所示

考虑投票表决这个答案

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

不,这在Git中是不可能的

在Git中实现类似的东西将是一项巨大的工作,这将意味着客户端存储库的完整性不再能够得到保证。如果您感兴趣,请在git邮件列表上搜索有关稀疏克隆和稀疏获取的讨论

一般来说,Git社区的共识是,如果您有多个始终独立签出的目录,那么这实际上是两个不同的项目,应该位于两个不同的存储库中。您可以使用.

编辑:从Git2.19开始,这最终是可能的,如图所示

考虑投票表决这个答案

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

不,这在Git中是不可能的

在Git中实现类似的东西将是一项巨大的工作,这将意味着客户端存储库的完整性不再能够得到保证。如果您感兴趣,请在git邮件列表上搜索有关稀疏克隆和稀疏获取的讨论


一般来说,Git社区的共识是,如果您有多个始终独立签出的目录,那么这实际上是两个不同的项目,应该位于两个不同的存储库中。您可以使用将它们粘合在一起。

如果您从未计划与从中克隆的存储库交互,则可以执行完整的git克隆,并使用git筛选器分支-子目录筛选器重写存储库。这样,至少会保留历史记录。

如果您从未计划与从中克隆的存储库交互,则可以执行完整的git克隆,并使用git筛选器分支-子目录筛选器重写存储库。这样,至少会保留历史记录。

Git1.7.0具有“稀疏签出”。看见 “core.sparseCheckout”在, 中的“稀疏签出”,以及 中的“跳过工作树位”


该接口不如SVN方便,例如,在初始克隆时无法进行稀疏签出,但现在可以使用构建更简单接口的基本功能。

Git 1.7.0具有“稀疏签出”。看见 “core.sparseCheckout”在, 中的“稀疏签出”,以及 中的“跳过工作树位”


界面没有SVN的方便,例如,在初始克隆时无法进行稀疏签出,但现在可以使用构建更简单界面的基本功能。

您尝试的操作称为稀疏签出,该功能已在2012年2月的git 1.7.0中添加。执行稀疏克隆的步骤如下所示:

mkdir <repo>
cd <repo>
git init
git remote add -f origin <url>
现在,您需要定义要实际签出的文件/文件夹。这是通过在.git/info/sparse checkout中列出它们来实现的,例如:

echo some/dir/>.git/info/sparse签出 回显另一个/子/树>>.git/info/sparse签出 最后但并非最不重要的一点是,使用远程服务器的状态更新您的空回购:

git pull origin master
现在,您将在文件系统中为某些/dir和另一个/sub/树签出文件,并且这些路径仍然存在,没有其他路径存在

你可能想看一看报纸,也许你应该读一下官方的

作为一项功能:

函数git\u sparse\u clone rurl=$1 localdir=$2&&shift 2 mkdir-p$localdir cd$localdir 初始化 git远程添加-f源代码$rurl git config core.sparseCheckout true 在剩余参数上循环 为了我;做 echo$i>>.git/info/sparse签出 完成 git拉源主机 用法:

git_spars e_克隆http://github.com/tj/n /本地/位置/垃圾箱 请注意,这仍然会从服务器下载整个存储库–只有签出的大小会减小。目前不可能只克隆一个目录。但是,如果不需要存储库的历史记录,至少可以通过创建浅层克隆来节省带宽。有关如何组合浅检出和稀疏检出的信息,请参见下文

自git 2.25.0 2020年1月起,git中添加了一个实验命令:

git稀疏签出初始化 等同于: git config core.sparseCheckout true git稀疏签出集A/B 等同于: 回声A/B>>.git/info/sparse签出 git稀疏签出列表 等同于: cat.git/info/sparse签出
您正在尝试的是所谓的稀疏签出,该功能是在2012年2月的git 1.7.0中添加的。执行稀疏克隆的步骤如下所示:

mkdir <repo>
cd <repo>
git init
git remote add -f origin <url>
现在,您需要定义要实际签出的文件/文件夹。这是通过在.git/info/sparse checkout中列出它们来实现的,例如:

echo some/dir/>.git/info/sparse签出 回显另一个/子/树>>.git/info/sparse签出 最后但并非最不重要的一点是,使用远程服务器的状态更新您的空回购:

git pull origin master
现在,您将在文件系统中为某些/dir和另一个/sub/树签出文件,并且这些路径仍然存在,没有其他路径存在

你可能想看一看报纸,也许你应该读一下官方的

作为一项功能:

函数git\u sparse\u clone rurl=$1 localdir=$2&&shift 2 mkdir-p$localdir cd$localdir 初始化 git远程添加-f源代码$rurl git config core.sparseCheckout true 在剩余参数上循环 为了我;做 echo$i>>.git/info/sparse签出 完成 git拉源主机 用法:

git_稀疏克隆http://github.com/tj/n /本地/位置/垃圾箱 请注意,这仍然会从服务器下载整个存储库–只有签出的大小会减小。目前不可能只克隆一个目录。但是,如果不需要存储库的历史记录,至少可以通过创建浅层克隆来节省带宽。有关如何组合浅检出和稀疏检出的信息,请参见下文

自git 2.25.0 2020年1月起,git中添加了一个实验命令:

git稀疏签出初始化 等同于: git config core.sparseCheckout true git稀疏签出集A/B 等同于: 回声A/B>>.git/info/sparse签出 git稀疏签出列表 等同于: cat.git/info/sparse签出 我只是为了

用法:

python get_git_sub_dir.py path/to/sub/dir <RECURSIVE>
我只是为了

用法:

python get_git_sub_dir.py path/to/sub/dir <RECURSIVE>
看起来简单得多:

git archive --remote=<repo_url> <branch> <path> | tar xvf -
看起来简单得多:

git archive --remote=<repo_url> <branch> <path> | tar xvf -
您可以将稀疏签出和浅克隆功能结合起来。浅层克隆会切断历史记录,稀疏签出只会提取与您的模式匹配的文件

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
您需要最低git 1.9才能正常工作。我自己只用2.2.0和2.2.2进行了测试

这样,您仍然可以推送,这在git archive中是不可能的。

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

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
您需要最低git 1.9才能正常工作。我自己只用2.2.0和2.2.2进行了测试


通过这种方式,您仍然可以推送,这在git archive中是不可能的。

仅使用git不可能克隆子目录,但下面是一些解决方法

滤波支路 您可能希望重写存储库,使其看起来好像trunk/public\u html/是其项目根目录,并使用“已尝试签出”分支放弃所有其他历史记录:

git filter-branch --subdirectory-filter trunk/public_html -- --all
注意,-用于将过滤器分支选项与修订选项分开,而-all用于重写所有分支和标记。包括原始提交时间或合并信息在内的所有信息都将被保留。此命令支持.git/info/grafts文件和refs/replace/namespace中的refs,因此如果定义了任何grafts或replacement refs,则运行此命令将使它们永久化

警告!对于所有对象,重写的历史将具有不同的对象名称,并且不会与原始分支收敛。您将无法在原始分支的顶部轻松推送和分发重写的分支。如果您不知道该命令的全部含义,请不要使用该命令,如果一次简单的提交就足以解决您的问题,请避免使用该命令

稀疏校验 下面是一些简单的步骤,这些步骤将稀疏地填充工作目录,因此您可以告诉Git工作目录中哪些文件夹或文件值得签出

像往常一样克隆存储库-无签出是可选的:

git clone --no-checkout git@foo/bar.git
cd bar
如果已经克隆了存储库,则可以跳过此步骤

提示:对于大型RePOS,考虑深度1只检查最新版本或/和单分支。 启用sparseCheckout选项:

指定用于稀疏签出的文件夹(末尾没有空格): 或者编辑.git/info/sparse签出

签出分支,例如主分支:

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

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


仅用Git克隆子目录是不可能的,但下面是一些解决方法

滤波支路 您可能希望重写存储库,使其看起来好像trunk/public\u html/是其项目根目录,并使用“已尝试签出”分支放弃所有其他历史记录:

git filter-branch --subdirectory-filter trunk/public_html -- --all
注意,-用于将过滤器分支选项与修订选项分开,而-all用于重写所有分支和标记。包括原始提交时间或合并信息在内的所有信息都将被保留。此命令支持.git/info/grafts文件和refs/replace/namespace中的refs,因此如果定义了任何grafts或replacement refs,则运行此命令将使它们永久化

警告!对于所有对象,重写的历史将具有不同的对象名称,并且不会与原始分支收敛。您将无法在原始分支的顶部轻松推送和分发重写的分支。如果您不知道该命令的全部含义,请不要使用该命令,如果一次简单的提交就足以解决您的问题,请避免使用该命令

稀疏校验 下面是一些简单的步骤,这些步骤将稀疏地填充工作目录,因此您可以告诉Git工作目录中哪些文件夹或文件值得签出

像往常一样克隆存储库-无签出是可选的:

git clone --no-checkout git@foo/bar.git
cd bar
如果已经克隆了存储库,则可以跳过此步骤

提示:对于大型RePOS,考虑深度1只检查最新版本或/和单分支。 启用sparseCheckout选项:

指定用于稀疏签出的文件夹(末尾没有空格):

echo "trunk/public_html/*"> .git/info/sparse-checkout
或者编辑.git/info/sparse签出

签出分支,例如主分支:

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

如果你有太多的目录级别或者过滤分支,你可以考虑符号链接。 对于只想从github下载文件/文件夹的其他用户,只需使用:

svn export <repo>/trunk/<folder>
是的,这里是svn。显然,在2016年,您仍然需要svn来下载一些github文件

礼节:

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

作为bash脚本:

git-download(){
    folder=${@/tree\/master/trunk}
    folder=${folder/blob\/master/trunk}
    svn export $folder
}
注 此方法下载文件夹,但不克隆/签出它。您不能将更改推回存储库。另一方面,与稀疏签出或浅签出相比,这会减少下载量。

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

svn export <repo>/trunk/<folder>
是的,这里是svn。显然,在2016年,您仍然需要svn来下载一些github文件

礼节:

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

作为bash脚本:

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

此方法下载文件夹,但不克隆/签出它。您不能将更改推回存储库。另一方面,与稀疏签出或浅层签出相比,这会减少下载量。

以下是我为单个子目录稀疏签出的用例编写的shell脚本

coSubDir.sh
下面是我为单个子目录稀疏签出的用例编写的shell脚本

coSubDir.sh git克隆-git 2.19中的过滤器现在可以在GitHub上运行,测试日期为2021-01-14,git 2.30.0

此选项是与远程协议的更新一起添加的,它确实可以防止从服务器下载对象

例如,仅克隆此最小测试存储库d1所需的对象:我可以执行以下操作:

git clone \
  --depth 1  \
  --filter=blob:none  \
  --sparse \
  https://github.com/cirosantilli/test-git-partial-clone \
;
cd test-git-partial-clone
git sparse-checkout set d1
这里有一个不那么简单和更现实的版本

该存储库包含:

包含10个10MB文件的大目录 一个小目录,包含1000个大小为一字节的文件 所有内容都是伪随机的,因此不可压缩

36.4 Mbps internet上的克隆次数:

完整:24秒 部分:瞬时 不幸的是,还需要稀疏签出部分。您也只能下载某些更容易理解的文件:

git clone \
  --depth 1  \
  --filter=blob:none  \
  --no-checkout \
  https://github.com/cirosantilli/test-git-partial-clone \
;
cd test-git-partial-clone
git checkout master -- di
但由于某种原因,这种方法无法使用,除非目录中的文件很少

分析最小存储库中的对象

clone命令仅获取:

有主枝尖的单曲 存储库的所有4个部分: 提交的顶级目录 三个目录d1、d2、master 然后,git sparse checkout set命令仅从服务器获取丢失的blob文件:

d1/a d1/b 更好的是,稍后GitHub可能会开始支持:

  --filter=blob:none \
  --filter=tree:0 \
where将防止对所有树对象进行不必要的克隆获取,并允许将其延迟到签出。但在我的2020-09-18测试中,失败的原因是:

fatal: invalid filter-spec 'combine:blob:none+tree:0'
大概是因为-filter=combi ne:Git2.24中添加的复合过滤器,由多重过滤器暗示,尚未实现

我观察到哪些对象是通过以下方式获取的:

git verify-pack -v .git/objects/pack/*.pack
正如在中提到的:它并没有给我一个超级清晰的指示每个对象到底是什么,但它确实说明了每个对象的类型commit、tree、blob,并且由于最小repo中的对象太少,我可以毫不含糊地推断出每个对象是什么

git rev list-objects-all确实为tree/blob生成了更清晰的路径输出,但不幸的是,当我运行它时,它会获取一些对象,这使得很难确定何时获取了什么,请告诉我是否有人有更好的命令

TODO发现GitHub发布时说他们开始支持它。从2020年1月17日起,已经提到-过滤器斑点:无

git稀疏校验

我认为该命令旨在管理一个设置文件,该文件表示我只关心这些子树,以便将来的命令只影响这些子树。但这有点难以确定,因为当前的文档有点。。。稀疏的-

它本身并不阻止抓取blob

如果这种理解是正确的,那么这将是对上述git clone-filter的一个很好的补充,因为如果您打算在部分克隆的repo中执行git操作,它将防止意外获取更多对象

当我在Git 2.25.1上试用时:

git clone \
  --depth 1 \
  --filter=blob:none \
  --no-checkout \
  https://github.com/cirosantilli/test-git-partial-clone \
;
cd test-git-partial-clone
git sparse-checkout init
它不起作用,因为init实际上获取了所有对象

然而,在Git2.28中,它没有按照需要获取对象。但如果我这样做了:

git sparse-checkout set d1
d1未被提取和签出,即使这明确表示它应该:使用免责声明:

请注意部分克隆功能是否可以普遍使用[1]

[1] :GitHub仍在对该功能进行内部评估,同时在包括本文中使用的示例在内的一些精选存储库上启用了该功能。随着功能的稳定和成熟,我们将随时向您通报其进展情况

所以是的,现在很难确定,部分原因是GitHub开源带来的乐趣。但是让我们注意一下

命令分解

服务器应配置为:

git config --local uploadpack.allowfilter 1
git config --local uploadpack.allowanysha1inwant 1
命令分解:

-filter=blob:none跳过所有blob,但仍然获取所有blob

-筛选器=树:0跳过不需要的树:

-深度1已暗示-单分支,另请参见:

文件://$path是克服git克隆协议骗局所必需的:

-filter=combine:FILTER1+FILTER2是一次使用多个过滤器的语法,尝试通过-filter由于某些原因失败:无法组合多个过滤器规格。这是在Git 2.24的E987DF5FE62B8B29BE4CDCDEB3704681ADA29E列表对象过滤器:实现复合过滤器中添加的

编辑:在Git 2.28上,我实验性地看到-filter=FILTER1-FILTER2也有相同的效果,因为GitHub没有实现combine:但是到2020-09-18,并且抱怨致命的:无效的过滤器规范“combine:blob:none+tree:0”。TODO在哪个版本中引入

-filter的格式记录在man git版本列表中

Git树上的文档:

在本地进行测试

以下脚本在本地重复生成存储库,进行本地克隆,并观察克隆的内容:

#!/usr/bin/env bash
set -eu

list-objects() (
  git rev-list --all --objects
  echo "master commit SHA: $(git log -1 --format="%H")"
  echo "mybranch commit SHA: $(git log -1 --format="%H")"
  git ls-tree master
  git ls-tree mybranch | grep mybranch
  git ls-tree master~ | grep root
)

# Reproducibility.
export GIT_COMMITTER_NAME='a'
export GIT_COMMITTER_EMAIL='a'
export GIT_AUTHOR_NAME='a'
export GIT_AUTHOR_EMAIL='a'
export GIT_COMMITTER_DATE='2000-01-01T00:00:00+0000'
export GIT_AUTHOR_DATE='2000-01-01T00:00:00+0000'

rm -rf server_repo local_repo
mkdir server_repo
cd server_repo

# Create repo.
git init --quiet
git config --local uploadpack.allowfilter 1
git config --local uploadpack.allowanysha1inwant 1

# First commit.
# Directories present in all branches.
mkdir d1 d2
printf 'd1/a' > ./d1/a
printf 'd1/b' > ./d1/b
printf 'd2/a' > ./d2/a
printf 'd2/b' > ./d2/b
# Present only in root.
mkdir 'root'
printf 'root' > ./root/root
git add .
git commit -m 'root' --quiet

# Second commit only on master.
git rm --quiet -r ./root
mkdir 'master'
printf 'master' > ./master/master
git add .
git commit -m 'master commit' --quiet

# Second commit only on mybranch.
git checkout -b mybranch --quiet master~
git rm --quiet -r ./root
mkdir 'mybranch'
printf 'mybranch' > ./mybranch/mybranch
git add .
git commit -m 'mybranch commit' --quiet

echo "# List and identify all objects"
list-objects
echo

# Restore master.
git checkout --quiet master
cd ..

# Clone. Don't checkout for now, only .git/ dir.
git clone --depth 1 --quiet --no-checkout --filter=blob:none "file://$(pwd)/server_repo" local_repo
cd local_repo

# List missing objects from master.
echo "# Missing objects after --no-checkout"
git rev-list --all --quiet --objects --missing=print
echo

echo "# Git checkout fails without internet"
mv ../server_repo ../server_repo.off
! git checkout master
echo

echo "# Git checkout fetches the missing directory from internet"
mv ../server_repo.off ../server_repo
git checkout master -- d1/
echo

echo "# Missing objects after checking out d1"
git rev-list --all --quiet --objects --missing=print

Git v2.19.0中的输出:

# List and identify all objects
c6fcdfaf2b1462f809aecdad83a186eeec00f9c1
fc5e97944480982cfc180a6d6634699921ee63ec
7251a83be9a03161acde7b71a8fda9be19f47128
62d67bce3c672fe2b9065f372726a11e57bade7e
b64bf435a3e54c5208a1b70b7bcb0fc627463a75 d1
308150e8fddde043f3dbbb8573abb6af1df96e63 d1/a
f70a17f51b7b30fec48a32e4f19ac15e261fd1a4 d1/b
84de03c312dc741d0f2a66df7b2f168d823e122a d2
0975df9b39e23c15f63db194df7f45c76528bccb d2/a
41484c13520fcbb6e7243a26fdb1fc9405c08520 d2/b
7d5230379e4652f1b1da7ed1e78e0b8253e03ba3 master
8b25206ff90e9432f6f1a8600f87a7bd695a24af master/master
ef29f15c9a7c5417944cc09711b6a9ee51b01d89
19f7a4ca4a038aff89d803f017f76d2b66063043 mybranch
1b671b190e293aa091239b8b5e8c149411d00523 mybranch/mybranch
c3760bb1a0ece87cdbaf9a563c77a45e30a4e30e
a0234da53ec608b54813b4271fbf00ba5318b99f root
93ca1422a8da0a9effc465eccbcb17e23015542d root/root
master commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec
mybranch commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec
040000 tree b64bf435a3e54c5208a1b70b7bcb0fc627463a75    d1
040000 tree 84de03c312dc741d0f2a66df7b2f168d823e122a    d2
040000 tree 7d5230379e4652f1b1da7ed1e78e0b8253e03ba3    master
040000 tree 19f7a4ca4a038aff89d803f017f76d2b66063043    mybranch
040000 tree a0234da53ec608b54813b4271fbf00ba5318b99f    root

# Missing objects after --no-checkout
?f70a17f51b7b30fec48a32e4f19ac15e261fd1a4
?8b25206ff90e9432f6f1a8600f87a7bd695a24af
?41484c13520fcbb6e7243a26fdb1fc9405c08520
?0975df9b39e23c15f63db194df7f45c76528bccb
?308150e8fddde043f3dbbb8573abb6af1df96e63

# Git checkout fails without internet
fatal: '/home/ciro/bak/git/test-git-web-interface/other-test-repos/partial-clone.tmp/server_repo' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

# Git checkout fetches the missing directory from internet
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done.
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done.

# Missing objects after checking out d1
?8b25206ff90e9432f6f1a8600f87a7bd695a24af
?41484c13520fcbb6e7243a26fdb1fc9405c08520
?0975df9b39e23c15f63db194df7f45c76528bccb
结论:d1/以外的所有斑点均缺失。例如,0975df9b39e23c15f63db194df7f45c76528bccb,即d2/b在签出d1/a后不存在

请注意,root/root和mybranch/mybranch也丢失了,但是-depth 1从丢失的文件列表中隐藏了它们。如果删除-depth 1,则它们将显示在丢失文件的列表中

我有一个梦想

这个特性可能会彻底改变Git

想象一下,企业的所有代码库都没有

想象一下

想象一下,如果GitHub允许类似的星星和权限,那么您可以在一次回购下存储所有个人资料

想象一下:只需请求一个树SHA和一个,首先查看您的服务器,然后再靠近您企业的镜像/缓存,最终在GitHub上运行。

git克隆-git 2.19中的过滤器现在可以在GitHub上运行,测试日期为2021-01-14,git 2.30.0

此选项是与远程协议的更新一起添加的,它确实可以防止从服务器下载对象

例如,仅克隆此最小测试存储库d1所需的对象:我可以执行以下操作:

git clone \
  --depth 1  \
  --filter=blob:none  \
  --sparse \
  https://github.com/cirosantilli/test-git-partial-clone \
;
cd test-git-partial-clone
git sparse-checkout set d1
这里有一个不那么简单和更现实的版本

该存储库包含:

包含10个10MB文件的大目录 一个小目录,包含1000个大小为一字节的文件 所有内容都是伪随机的,因此不可压缩

36.4 Mbps internet上的克隆次数:

完整:24秒 部分:瞬时 不幸的是,还需要稀疏签出部分。您也只能下载某些更容易理解的文件:

git clone \
  --depth 1  \
  --filter=blob:none  \
  --no-checkout \
  https://github.com/cirosantilli/test-git-partial-clone \
;
cd test-git-partial-clone
git checkout master -- di
但是由于某种原因,这种方法无法使用,除非 目录中只有很少的文件

分析最小存储库中的对象

clone命令仅获取:

有主枝尖的单曲 存储库的所有4个部分: 提交的顶级目录 三个目录d1、d2、master 然后,git sparse checkout set命令仅从服务器获取丢失的blob文件:

d1/a d1/b 更好的是,稍后GitHub可能会开始支持:

  --filter=blob:none \
  --filter=tree:0 \
where将防止对所有树对象进行不必要的克隆获取,并允许将其延迟到签出。但在我的2020-09-18测试中,失败的原因是:

fatal: invalid filter-spec 'combine:blob:none+tree:0'
大概是因为Git2.24中添加的-filter=combine:composite过滤器(由multiple-filter暗示)尚未实现

我观察到哪些对象是通过以下方式获取的:

git verify-pack -v .git/objects/pack/*.pack
正如在中提到的:它并没有给我一个超级清晰的指示每个对象到底是什么,但它确实说明了每个对象的类型commit、tree、blob,并且由于最小repo中的对象太少,我可以毫不含糊地推断出每个对象是什么

git rev list-objects-all确实为tree/blob生成了更清晰的路径输出,但不幸的是,当我运行它时,它会获取一些对象,这使得很难确定何时获取了什么,请告诉我是否有人有更好的命令

TODO发现GitHub发布时说他们开始支持它。从2020年1月17日起,已经提到-过滤器斑点:无

git稀疏校验

我认为该命令旨在管理一个设置文件,该文件表示我只关心这些子树,以便将来的命令只影响这些子树。但这有点难以确定,因为当前的文档有点。。。稀疏的-

它本身并不阻止抓取blob

如果这种理解是正确的,那么这将是对上述git clone-filter的一个很好的补充,因为如果您打算在部分克隆的repo中执行git操作,它将防止意外获取更多对象

当我在Git 2.25.1上试用时:

git clone \
  --depth 1 \
  --filter=blob:none \
  --no-checkout \
  https://github.com/cirosantilli/test-git-partial-clone \
;
cd test-git-partial-clone
git sparse-checkout init
它不起作用,因为init实际上获取了所有对象

然而,在Git2.28中,它没有按照需要获取对象。但如果我这样做了:

git sparse-checkout set d1
d1未被提取和签出,即使这明确表示它应该:使用免责声明:

请注意部分克隆功能是否可以普遍使用[1]

[1] :GitHub仍在对该功能进行内部评估,同时在包括本文中使用的示例在内的一些精选存储库上启用了该功能。随着功能的稳定和成熟,我们将随时向您通报其进展情况

所以是的,现在很难确定,部分原因是GitHub开源带来的乐趣。但是让我们注意一下

命令分解

服务器应配置为:

git config --local uploadpack.allowfilter 1
git config --local uploadpack.allowanysha1inwant 1
命令分解:

-filter=blob:none跳过所有blob,但仍然获取所有blob

-筛选器=树:0跳过不需要的树:

-深度1已暗示-单分支,另请参见:

文件://$path是克服git克隆协议骗局所必需的:

-filter=combine:FILTER1+FILTER2是一次使用多个过滤器的语法,尝试通过-filter由于某些原因失败:无法组合多个过滤器规格。这是在Git 2.24的E987DF5FE62B8B29BE4CDCDEB3704681ADA29E列表对象过滤器:实现复合过滤器中添加的

编辑:在Git 2.28上,我实验性地看到-filter=FILTER1-FILTER2也有相同的效果,因为GitHub没有实现combine:但是到2020-09-18,并且抱怨致命的:无效的过滤器规范“combine:blob:none+tree:0”。TODO在哪个版本中引入

-filter的格式记录在man git版本列表中

Git树上的文档:

在本地进行测试

以下脚本在本地重复生成存储库,进行本地克隆,并观察克隆的内容:

#!/usr/bin/env bash
set -eu

list-objects() (
  git rev-list --all --objects
  echo "master commit SHA: $(git log -1 --format="%H")"
  echo "mybranch commit SHA: $(git log -1 --format="%H")"
  git ls-tree master
  git ls-tree mybranch | grep mybranch
  git ls-tree master~ | grep root
)

# Reproducibility.
export GIT_COMMITTER_NAME='a'
export GIT_COMMITTER_EMAIL='a'
export GIT_AUTHOR_NAME='a'
export GIT_AUTHOR_EMAIL='a'
export GIT_COMMITTER_DATE='2000-01-01T00:00:00+0000'
export GIT_AUTHOR_DATE='2000-01-01T00:00:00+0000'

rm -rf server_repo local_repo
mkdir server_repo
cd server_repo

# Create repo.
git init --quiet
git config --local uploadpack.allowfilter 1
git config --local uploadpack.allowanysha1inwant 1

# First commit.
# Directories present in all branches.
mkdir d1 d2
printf 'd1/a' > ./d1/a
printf 'd1/b' > ./d1/b
printf 'd2/a' > ./d2/a
printf 'd2/b' > ./d2/b
# Present only in root.
mkdir 'root'
printf 'root' > ./root/root
git add .
git commit -m 'root' --quiet

# Second commit only on master.
git rm --quiet -r ./root
mkdir 'master'
printf 'master' > ./master/master
git add .
git commit -m 'master commit' --quiet

# Second commit only on mybranch.
git checkout -b mybranch --quiet master~
git rm --quiet -r ./root
mkdir 'mybranch'
printf 'mybranch' > ./mybranch/mybranch
git add .
git commit -m 'mybranch commit' --quiet

echo "# List and identify all objects"
list-objects
echo

# Restore master.
git checkout --quiet master
cd ..

# Clone. Don't checkout for now, only .git/ dir.
git clone --depth 1 --quiet --no-checkout --filter=blob:none "file://$(pwd)/server_repo" local_repo
cd local_repo

# List missing objects from master.
echo "# Missing objects after --no-checkout"
git rev-list --all --quiet --objects --missing=print
echo

echo "# Git checkout fails without internet"
mv ../server_repo ../server_repo.off
! git checkout master
echo

echo "# Git checkout fetches the missing directory from internet"
mv ../server_repo.off ../server_repo
git checkout master -- d1/
echo

echo "# Missing objects after checking out d1"
git rev-list --all --quiet --objects --missing=print

Git v2.19.0中的输出:

# List and identify all objects
c6fcdfaf2b1462f809aecdad83a186eeec00f9c1
fc5e97944480982cfc180a6d6634699921ee63ec
7251a83be9a03161acde7b71a8fda9be19f47128
62d67bce3c672fe2b9065f372726a11e57bade7e
b64bf435a3e54c5208a1b70b7bcb0fc627463a75 d1
308150e8fddde043f3dbbb8573abb6af1df96e63 d1/a
f70a17f51b7b30fec48a32e4f19ac15e261fd1a4 d1/b
84de03c312dc741d0f2a66df7b2f168d823e122a d2
0975df9b39e23c15f63db194df7f45c76528bccb d2/a
41484c13520fcbb6e7243a26fdb1fc9405c08520 d2/b
7d5230379e4652f1b1da7ed1e78e0b8253e03ba3 master
8b25206ff90e9432f6f1a8600f87a7bd695a24af master/master
ef29f15c9a7c5417944cc09711b6a9ee51b01d89
19f7a4ca4a038aff89d803f017f76d2b66063043 mybranch
1b671b190e293aa091239b8b5e8c149411d00523 mybranch/mybranch
c3760bb1a0ece87cdbaf9a563c77a45e30a4e30e
a0234da53ec608b54813b4271fbf00ba5318b99f root
93ca1422a8da0a9effc465eccbcb17e23015542d root/root
master commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec
mybranch commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec
040000 tree b64bf435a3e54c5208a1b70b7bcb0fc627463a75    d1
040000 tree 84de03c312dc741d0f2a66df7b2f168d823e122a    d2
040000 tree 7d5230379e4652f1b1da7ed1e78e0b8253e03ba3    master
040000 tree 19f7a4ca4a038aff89d803f017f76d2b66063043    mybranch
040000 tree a0234da53ec608b54813b4271fbf00ba5318b99f    root

# Missing objects after --no-checkout
?f70a17f51b7b30fec48a32e4f19ac15e261fd1a4
?8b25206ff90e9432f6f1a8600f87a7bd695a24af
?41484c13520fcbb6e7243a26fdb1fc9405c08520
?0975df9b39e23c15f63db194df7f45c76528bccb
?308150e8fddde043f3dbbb8573abb6af1df96e63

# Git checkout fails without internet
fatal: '/home/ciro/bak/git/test-git-web-interface/other-test-repos/partial-clone.tmp/server_repo' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

# Git checkout fetches the missing directory from internet
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done.
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done.

# Missing objects after checking out d1
?8b25206ff90e9432f6f1a8600f87a7bd695a24af
?41484c13520fcbb6e7243a26fdb1fc9405c08520
?0975df9b39e23c15f63db194df7f45c76528bccb
结论:d1/以外的所有斑点均缺失。例如,0975df9b39e23c15f63db194df7f45c76528bccb,即d2/b在签出d1/a后不存在

请注意,root/root和mybranch/mybranch也丢失了,但是-depth 1从丢失的文件列表中隐藏了它们。如果删除-depth 1,则它们将显示在丢失文件的列表中

我有一个梦想

这个特性可能会彻底改变Git

想象一下,企业的所有代码库都没有

想象一下

想象一下,如果GitHub允许类似的星星和权限,那么您可以在一次回购下存储所有个人资料


想象一下:只需请求一个树SHA和一个,首先查看您的服务器,然后再靠近您企业的镜像/缓存,最后到达GitHub。

这将克隆一个特定文件夹并删除所有与之无关的历史记录

git clone --single-branch -b {branch} git@github.com:{user}/{repo}.git
git filter-branch --subdirectory-filter {path/to/folder} HEAD
git remote remove origin
git remote add origin git@github.com:{user}/{new-repo}.git
git push -u origin master

这将克隆特定文件夹并删除与之无关的所有历史记录

git clone --single-branch -b {branch} git@github.com:{user}/{repo}.git
git filter-branch --subdirectory-filter {path/to/folder} HEAD
git remote remove origin
git remote add origin git@github.com:{user}/{new-repo}.git
git push -u origin master
我为它编写了一个.gitconfig[alias] 执行稀疏签出。看看吧,没有双关语:

在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命令被“缩小”,但下面是扩展的别名:

注意,-template=用于禁用模板。 如果你没有像我一样与他们有问题,请随意删除它 `mkdir`提前生成.git/info目录,因为我发现它有时会因为某种原因而丢失 f{ [$-eq 2]&&L=${1*/}L=${1%.git}|L=$2; mkdir-p$L/.git/info &&cd$L &&git初始化模板= &&git远程添加源代码$1 &&git config core.sparseCheckout 1; [$-等式2] &&echo$2>>.git/info/sparse签出 || { 第二班; 对我来说,是的 echo$i>>.git/info/sparse checkout; 完成 }; git pull-depth 1原始主机; }; F 我编写了一个.gitconfig[alias]来执行稀疏签出。看看吧,没有双关语:

在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命令被“缩小”,但下面是扩展的别名:

注意,-template=用于禁用模板。 如果你没有像我一样与他们有问题,请随意删除它 `mkdir`提前生成.git/info目录,因为我发现它有时会因为某种原因而丢失 f{ [$-eq 2]&&L=${1*/}L=${1%.git}|L=$2; mkdir-p$L/.git/info &&cd$L &&git初始化模板= &&git远程添加源代码$1 &&git config core.sparseCheckout 1; [$-等式2] &&echo$2>>.git/info/sparse签出 || { 第二班; 对我来说,是的 echo$i>>.git/info/sparse checkout; 完成 }; git pull-depth 1原始主机; }; F
使用Linux?并且只想要易于访问和清洁的工作树?不干扰机器上的其他代码。试试符号链接

试验


使用Linux?并且只想要易于访问和清洁的工作树?不干扰机器上的其他代码。试试符号链接

试验


虽然我讨厌在处理git回购协议时不得不使用svn:/但我一直都在使用它

函数git-scp URL=$1&&shift 1 svn导出${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/

虽然我讨厌在处理git回购协议时不得不使用svn:/但我一直都在使用它

函数git-scp URL=$1&&shift 1 svn导出${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/

如果您实际上对目录的最新版本文件不感兴趣,Github允许您以Zip文件的形式下载存储库,该文件不包含历史记录。因此下载速度要快得多。

如果您实际上对目录的最新版本文件感兴趣,Github允许您将存储库作为Zip文件下载,而Zip文件不包含历史记录。因此下载速度要快得多。

为了澄清这里的一些重要答案,许多答案中概述的步骤假设您已经在某个地方有了远程存储库

给定:现有的git存储库,例如。git@github.com:某些user/full-repo.git,其中包含一个或多个您希望独立于repo其余部分提取的目录,例如名为app1和app2的目录

假设您拥有如上所述的git存储库

然后:您可以运行以下步骤,仅从较大的回购中提取特定目录:

mkdir app1
cd app1
git init
git remote add origin git@github.com:some-user/full-repo.git
git config core.sparsecheckout true
echo "app1/" >> .git/info/sparse-checkout
git pull origin master
我曾错误地认为必须在原始存储库上设置稀疏签出选项,但事实并非如此:在从远程提取之前,您可以在本地定义所需的目录。远程回购不知道也不关心您只想跟踪回购的一部分


希望此澄清对其他人有所帮助。

为了澄清这里的一些重要答案,许多答案中概述的步骤假设您已经在某个地方拥有远程存储库

给定:现有的git存储库,例如。git@github.com:某些user/full-repo.git,其中包含一个或多个您希望独立于repo其余部分提取的目录,例如名为app1和app2的目录

假设您拥有如上所述的git存储库

然后:您可以运行以下步骤,仅从较大的回购中提取特定目录:

mkdir app1
cd app1
git init
git remote add origin git@github.com:some-user/full-repo.git
git config core.sparsecheckout true
echo "app1/" >> .git/info/sparse-checkout
git pull origin master
我曾错误地认为必须在原始存储库上设置稀疏签出选项,但事实并非如此:在从远程提取之前,您可以在本地定义所需的目录。远程回购不知道也不关心您只想跟踪回购的一部分


希望这一澄清能帮助其他人。

所以我尝试了这方面的一切,但没有任何效果。。。事实证明,Git的2.24版是 在回答这个问题时使用cpanel,您不需要这样做

echo "wpm/*" >> .git/info/sparse-checkout
您所需要的只是文件夹名

wpm/*
简言之,你要这样做

git config core.sparsecheckout true
然后编辑.git/info/sparse签出 每行添加一个文件夹名称,并在末尾添加/*以获取子文件夹和文件

wpm/*
保存并运行checkout命令

git checkout master
结果是我的回购中的预期文件夹,而不是其他文件夹
向上投票,如果这对你有用的话

所以我尝试了这方面的一切,但没有任何效果。。。事实证明,在Git的2.24版上,也就是回答这个问题时cpanel附带的版本,您不需要这样做

echo "wpm/*" >> .git/info/sparse-checkout
您所需要的只是文件夹名

wpm/*
简言之,你要这样做

git config core.sparsecheckout true
然后编辑.git/info/sparse签出 每行添加一个文件夹名称,并在末尾添加/*以获取子文件夹和文件

wpm/*
保存并运行checkout命令

git checkout master
结果是我的回购中的预期文件夹,而不是其他文件夹
如果这对你有用,请向上投票。

上面有很多好主意和脚本。我情不自禁地将它们结合到一个带有帮助和错误检查的bash脚本中:

!/bin/bash 功能帮助{ 打印F$1 从git存储库的主分支克隆特定目录。 语法: $basename$0[-delrepo]repoUrl源目录[targetDirectory] 如果未指定targetDirectory,则会将其设置为sourceDirectory。 将sourceDirectory从Git存储库下载到targetdirectory中。 如果未指定targetDirectory,则使用以`basename sourceDirectory'命名的目录` 将在当前目录下创建。 如果指定了-delrepo,则克隆后将删除克隆中的.git子目录。 例1: 从的主分支克隆树/master/django/conf/app_template目录 git@github.com:django/django.git进入./app_模板: \$$basename$0git@github.com:django/django.git django/conf/app_template \$ls app_template/django/conf/app_template/ __init_uupy.tpl admin.py-tpl apps.py-tpl migrations models.py-tpl tests.py-tpl views.py-tpl 例2: 从的主分支克隆django/conf/app_模板目录 https://github.com/django/django/tree/master/django/conf/app_template 进入~/测试: \$$basename$0git@github.com:django/django.git django/conf/app_template~/test \$ls test/django/conf/app_模板/ __init_uupy.tpl admin.py-tpl apps.py-tpl migrations models.py-tpl tests.py-tpl views.py-tpl 出口1 } 如果[-z$1];然后出现帮助错误:未指定repoUrl。\n;fi 如果[-z$2];然后出现帮助错误:未指定sourceDirectory。;fi 如果[$1==-delrepo];然后 DEL_REPO=真 转移 fi REPO_URL=$1 SOURCE_目录=$2 若[$3];然后 目标目录=$3 其他的 TARGET_DIRECTORY=$basename$2 fi 将克隆回显到$TARGET\u目录中 mkdir-p$TARGET\u目录 cd$TARGET\u目录 初始化 git远程添加源-f$REPO_URL git config core.sparseCheckout true echo$SOURCE\u DIRECTORY>.git/info/sparse签出 git pull-深度=1原点主控 如果[$DEL_REPO];然后rm-rf.git;fi
上面有很多好主意和剧本。我情不自禁地将它们结合到一个带有帮助和错误检查的bash脚本中:

!/bin/bash 功能帮助{ 打印F$1 从git存储库的主分支克隆特定目录。 语法: $basename$0[-delrepo]repoUrl源目录[targetDirectory] 如果未指定targetDirectory,则会将其设置为sourceDirectory。 将sourceDirectory从Git存储库下载到targetdirectory中。 如果未指定targetDirectory,则使用以`basename sourceDirectory'命名的目录` 将在当前目录下创建。 如果指定了-delrepo,则克隆后将删除克隆中的.git子目录。 例1: 从的主分支克隆树/master/django/conf/app_template目录 git@github.com:django/django.git进入./app_模板: \$$basename$0git@github.com:django/django.git django/conf/app_template \$ls app_template/django/conf/app_template/ __init_uupy.tpl admin.py-tpl apps.py-tpl migrations models.py-tpl tests.py-tpl views.py-tpl 例2: 从的主分支克隆django/conf/app_模板目录 https://github.com/django/django/tree/master/django/conf/app_template 进入~/测试: \$$basename$0git@github.com:django/django.git django/conf/app_template~/test \$ls test/django/conf/app_模板/ __init_uupy.tpl admin.py-tpl apps.py-tpl migrations models.py-tpl tests.py-tpl views.py-tpl 出口1 } 如果[-z$1];然后出现帮助错误:未指定repoUrl。\n;fi 如果[-z$2];然后出现帮助错误:未指定sourceDirectory。;fi 如果[$1==-delrepo];然后 DEL_REPO=真 转移 fi REPO_URL=$1 SOURCE_目录=$2 若[$3];然后 目标目录=$3 其他的 TARGET_DIRECTORY=$basename$2 fi 将克隆回显到$TARGET\u目录中 mkdir-p$TARGET\u目录 cd$TARGET\u目录 初始化 git远程添加源-f$REPO_URL git config core.sparseCheckout true echo$SOURCE\u DIRECTORY>.git/info/sparse签出 git pull-深度=1原点主控 我 f[$DEL_REPO];然后rm-rf.git;fi
这里有很多很好的回复,但我想补充一点,在Windows Server 2016上使用目录名周围的引号对我来说是失败的。这些文件根本没有被下载

而不是

"mydir/myfolder"
我不得不使用

mydir/myfolder
此外,如果您只想下载所有子目录,只需使用

git sparse-checkout set *

这里有很多很好的回复,但我想补充一点,在Windows Server 2016上使用目录名周围的引号对我来说是失败的。这些文件根本没有被下载

而不是

"mydir/myfolder"
我不得不使用

mydir/myfolder
此外,如果您只想下载所有子目录,只需使用

git sparse-checkout set *

根据场景的不同,您可能希望使用git子树而不是git子模块。请参阅@StijndeWitt:git读取树期间发生稀疏签出,这在get fetch之后很长一段时间。问题不是只签出一个子目录,而是只克隆一个子目录。我不知道稀疏签出怎么可能做到这一点,因为git read tree是在克隆完成后运行的。你想让我删除这个存根而不是这个存根,这样Chronial就可以浮到顶部了吗?您不能自己删除它,因为它已被接受,但版主可以。你会保留你从中赢得的声誉,因为它太古老了。我遇到此问题是因为有人将其标记为“仅链接”:-@CodyGray:Chronial answer仍然克隆整个存储库,而不仅仅是一个子目录。最后一段甚至明确指出了这一点。在Git中不可能只克隆子目录。网络协议不支持它,存储格式不支持它。这个问题的每个答案都会克隆整个存储库。这个问题是一个简单的是/否问题,答案是两个字符:否。如果有,我的答案不必要的长,而不是短。@JörgWMittag:似乎与您相矛盾。根据场景,您可能希望使用git子树而不是git子模块。请参阅@StijndeWitt:git读取树期间发生稀疏签出,这在get fetch之后很长一段时间。问题不是只签出一个子目录,而是只克隆一个子目录。我不知道稀疏签出怎么可能做到这一点,因为git read tree是在克隆完成后运行的。你想让我删除这个存根而不是这个存根,这样Chronial就可以浮到顶部了吗?您不能自己删除它,因为它已被接受,但版主可以。你会保留你从中赢得的声誉,因为它太古老了。我遇到此问题是因为有人将其标记为“仅链接”:-@CodyGray:Chronial answer仍然克隆整个存储库,而不仅仅是一个子目录。最后一段甚至明确指出了这一点。在Git中不可能只克隆子目录。网络协议不支持它,存储格式不支持它。这个问题的每个答案都会克隆整个存储库。这个问题是一个简单的“是/否”问题,答案是两个字符:否。如果有的话,我的答案是不必要的长,而不是短。@JörgWMittag:似乎与你相矛盾。在苹果上,'-f'周长不起作用。只需执行git remote add origin而不使用-fIt是一项改进,但仍需要下载并在origin中存储远程存储库的完整副本,如果一个人只对代码库的一部分感兴趣,或者有文档子文件夹(如我的案例中的文档子文件夹),那么他到底想避免哪一个呢?有没有一种方法可以将所需的目录内容而不是目录本身克隆到我的存储库中?例如,我想克隆的内容https://github.com/Umkus/nginx-boilerplate/tree/master/src 直接进入/等/nginx@Chronial,@ErikE:你们都是对的/错的:P git remote add命令并不意味着获取,但这里使用的git remote add-f却意味着获取!这就是-f的意思。使用这个和-depth=1,我克隆了338MB的Chromium开发工具,而不是4.9GB的完整闪烁源代码+历史记录。太好了。在苹果上,'-f'周长不起作用。只需执行git remote add origin而不使用-fIt是一项改进,但仍需要下载并在origin中存储远程存储库的完整副本,如果一个人只对代码库的一部分感兴趣,或者有文档子文件夹(如我的案例中的文档子文件夹),那么他到底想避免哪一个呢?有没有一种方法可以将所需的目录内容而不是目录本身克隆到我的存储库中?例如,我想克隆的内容https://github.com/Umkus/nginx-boilerplate/tree/master/src 直接进入/等/nginx@Chronial,@ErikE:你们都是对的/错的:P git remote add命令并不意味着获取,但这里使用的git remote add-f却意味着获取!这就是-f的意思。使用这个和-depth=1,我克隆了338MB的Chromium开发工具,而不是4.9GB的完整闪烁源代码+历史记录。很好。对于2014年的用户来说,git clone最简单的命令是什么??我用过。如果有更简单的内容,请为那些试图克隆存储库内容而不是creatin的人提供评论

对于根文件夹,这是一个非常简单的解决方案:@JoachimBreitner:这个问题是关于在Git中检出子目录的,这很容易,而这个问题是关于在Git中克隆子目录的,这是不可能的。@NickSergeant:从3周前发布的Git 2.19开始,这终于有可能了,从这个答案中可以看出:现在就接受这个。注意:在Git2.19中,只实现了客户端支持,而服务器端支持仍然缺失,因此它只在克隆本地存储库时起作用。还要注意的是,大型Git主机(例如GitHub)实际上并不使用Git服务器,而是使用自己的实现,因此即使支持出现在Git服务器上,也并不自动意味着它可以在Git主机上工作。对于2014年的用户来说,git克隆最简单的命令是什么??我用过。如果有更简单的问题,请评论对于那些试图克隆存储库内容而不创建根文件夹的人,这是一个非常简单的解决方案:@JoachimBreitner:这个问题是关于在Git中签出子目录的,这很简单,而这个问题是关于Git中的克隆子目录,这是不可能的。@ NICSReGeNANT:如Git 2.19,3周前发布的,这是最后可能的,如在这个答案中可以看到的:考虑现在接受一个。注意:在Git2.19中,只实现了客户端支持,而服务器端支持仍然缺失,因此它只在克隆本地存储库时起作用。还要注意的是,大型Git主机(例如GitHub)实际上并不使用Git服务器,而是使用自己的实现,因此即使支持出现在Git服务器上,也并不自动意味着它可以在Git主机上工作。OTOH,他们可以更快地实现它。仅供参考,这仅适用于GitHub。显然,这是用于下载目录,而不是克隆包含所有元数据的repo片段。。。对吗?您应该在这里而不是其他地方包含代码。urllib2.HTTPError:HTTP错误403:速率限制超出了Dfyi,这仅适用于GitHub。显然,这是用于下载目录,而不是克隆包含所有元数据的repo片段。。。对吗?您应该在这里而不是在其他地方包含代码。urllib2.HTTPError:HTTP错误403:超出速率限制在github上执行此操作时,我得到致命的:协议不支持的操作。意外的命令流结束协议错误可能是由于repo url中的HTTPS或:导致的。这也可能是因为缺少ssh密钥。如果您正在使用github,则可以使用svn export INSTEADWIHT github->Invalid命令“git upload archive”xxx/yyy.git无法工作。您似乎正在使用ssh克隆git://URL。确保未设置core.gitProxy配置选项和GIT_PROXY_命令环境变量。致命:远程端意外挂起GitHub无法正常工作的原因:我们不支持使用git archive直接从GitHub提取归档。您可以在本地克隆repo并运行git归档,或者单击repo页面上的下载ZIP按钮。当我在github上执行此操作时,我得到了致命的:协议不支持的操作。意外的命令流结束协议错误可能是由于repo url中的HTTPS或:导致的。这也可能是因为缺少ssh密钥。如果您正在使用github,则可以使用svn export INSTEADWIHT github->Invalid命令“git upload archive”xxx/yyy.git无法工作。您似乎正在使用ssh克隆git://URL。确保未设置core.gitProxy配置选项和GIT_PROXY_命令环境变量。致命:远程端意外挂起GitHub无法正常工作的原因:我们不支持使用git archive直接从GitHub提取归档。您可以在本地克隆repo并运行git归档,或者单击repo页面上的下载ZIP按钮。对于不知道该命令的人来说,它是git filter branch-subdirectory filter。这种方法的优点是,您选择的子目录将成为新存储库的根目录,这恰好正是我想要的。这是最好、最简单的使用方法。下面是一个使用子目录filter git clone的一步命令https://github.com/your/repo_xx.git &&cd repo_xx&&git filter branch-子目录filter repo_xx_子目录对于不知道该命令的人,git filter branch-subdirectory filter这种方法的优点是,您选择的子目录将成为新存储库的根目录,这恰好是我想要的。这是最好、最简单的使用方法。下面是一个使用子目录filter git clone的一步命令https://github.com/your/repo_xx.git &&cd repo_xx&&git filter branch-subdirectory filter repo_xx_subrth这很有用,可能是最好的答案,但它仍然克隆了您不关心的内容,如果它位于您拉取的分支上,即使它没有显示在结帐单上。你的git版本是什么?根据git的帮助,深度选项是否可用

在Windows上,当最后一个命令不是git pull-depth=1 origin master,而是git pull-depth=1 origin时,able?对我不起作用,倒数第二行需要省略引号,否则拉动失败。这仍然会下载所有数据!使用svn找到了这个解决方案:这很有用,可能是最好的答案,但它仍然克隆了您不关心的内容,如果它位于您拉的分支上,即使它没有显示在签出中。您的git版本是什么?根据git帮助,深度选项可用吗?如果最后一个命令不是git pull-depth=1 origin master,而是Windows上的git pull-depth=1 origin master,则对我不起作用,倒数第二行需要省略引号,否则pull失败。这仍然会下载所有数据!找到此解决方案,使用svn:Filter branch是否仍允许您提取?@sam:no。Filter branch将重写父提交,以便它们具有不同的SHA1 ID,因此您的筛选树与远程树没有共同的提交。git pull不知道从何处尝试合并。对于我的情况,这种方法是最令人满意的答案。Filter branch是否仍然允许您进行合并?@sam:否。Filter branch将重写父提交,以便它们具有不同的SHA1 ID,因此您的筛选树与远程树没有共同的提交。git pull不知道从何处尝试合并。这种方法是对我的案例最满意的答案。唯一一个使用github对我有效的版本。git命令签出了>10k个文件,svn只导出我想要的700个文件。谢谢我试过用这个https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/trunk/udacity 但是得到了svn:E170000:URL'https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/trunk/udacity'不存在错误:@zthomas.nc您需要删除udacity前面的'trunk',并将/tree/master/替换为/trunk/。这个命令对我很有效!我只是想从回购协议中获取一份文件副本,以便在本地修改它。好老SVN来营救!它可以工作,但似乎很慢。开始时需要一点时间,然后文件会以相对缓慢的版本滚动,这一版本在github中对我有效。git命令签出了>10k个文件,svn只导出我想要的700个文件。谢谢我试过用这个https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/trunk/udacity 但是得到了svn:E170000:URL'https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/trunk/udacity'不存在错误:@zthomas.nc您需要删除udacity前面的'trunk',并将/tree/master/替换为/trunk/。这个命令对我很有效!我只是想从回购协议中获取一份文件副本,以便在本地修改它。好老SVN来营救!它可以工作,但似乎很慢。启动需要一点时间,然后文件通过相对较慢的同步脚本滚动,唯一需要修复的是符号链接,应该是ln-s./.$localRepo/$subDir$localRepo而不是ln-s./.$localRepo$subDir$localRepoNice脚本,唯一需要修复的是符号链接,应该是ln-s./.$localRepo/$subDir$localRepo,而不是ln-s./.$localRepo$subDir$localRepo不幸的是,macOS git版本没有运气。致命:无效的筛选器规范'combine:blob:none+tree:0'谢谢!也许它可以与较新的版本一起使用。如果在Windows 10上使用GIT 2.24.1尝试它,会导致无法读取..+的sha1文件取消文件xxx的链接失败。。在Linux上作为同一版本的魔咒使用。@Ciro Santilli此操作仍然失败,无法读取的sha1文件。。。在git版本2.26.1.windows.1中。我打开了一个bug报告:@CiroSantilli郝海东冠状病六四事件法轮功 some/path是一个目录和git checkout master-some/path只正确克隆该目录及其子目录中的文件-但它会一个接一个地执行此操作,并显示如下消息:remote:enuming objects:1,done。远程:计数对象:100%1/1,完成。远程:总计1增量0,重复使用1增量0,包重复使用0接收对象:100%1/1,51字节| 51.00 KiB/s,完成。这4行代码对目录及其子目录中的90个文件中的每一个都重复,这在git版本2.24.3 Apple git上-128@CiroSantilli新疆棉花特朗普班巴德-你已经找到了解决方案!只需删除-锥线,它会很好地工作。在测试存储库中,尝试在顶层创建其他文件。如果您按照指示操作,那么您还将获得该文件的副本以及所需的目录。删除'git sparse checkout init-cone',但按照所有其他说明操作,就可以得到所需的目录树。我不太确定在什么情况下你会想使用-cone!不幸的是,macOS git版本没有什么好运气。致命:无效的筛选器规范'combine:blob:none+tree:0'谢谢!也许它可以与较新的版本一起使用。如果在Windows 10上使用GIT 2.24.1尝试它,会导致无法读取..+的sha1文件取消文件xxx fai的链接
带路。。在Linux上作为同一版本的魔咒使用。@Ciro Santilli此操作仍然失败,无法读取的sha1文件。。。在git版本2.26.1.windows.1中。我打开了一个bug报告:@CiroSantilli郝海东冠状病六四事件法轮功 some/path是一个目录和git checkout master-some/path只正确克隆该目录及其子目录中的文件-但它会一个接一个地执行此操作,并显示如下消息:remote:enuming objects:1,done。远程:计数对象:100%1/1,完成。远程:总计1增量0,重复使用1增量0,包重复使用0接收对象:100%1/1,51字节| 51.00 KiB/s,完成。这4行代码对目录及其子目录中的90个文件中的每一个都重复,这在git版本2.24.3 Apple git上-128@CiroSantilli新疆棉花特朗普班巴德-你已经找到了解决方案!只需删除-锥线,它会很好地工作。在测试存储库中,尝试在顶层创建其他文件。如果您按照指示操作,那么您还将获得该文件的副本以及所需的目录。删除'git sparse checkout init-cone',但按照所有其他说明操作,就可以得到所需的目录树。我不太确定在什么情况下你会想使用-cone!为什么这样做:L=${1*/}L=${L%.git}?空间是一个操作符吗?你应该提到这是为git<2.25.0 2020年1月,其中包括它自己版本的git sparse-checkout。为什么这样做:L=${1*/}L=${L%.git}?space是一个运营商吗?你应该提到这是针对git<2.25.0 2020年1月的,它包括自己版本的git sparse-checkout。这里是dragons。您会收到警告:git filter分支有大量的gotchas生成了扭曲的历史重写。。。那么,我们有一个相当长的警告列表。这里是龙。您会收到警告:git filter分支有大量的gotchas生成了扭曲的历史重写。。。然后,有一个相当长的警告列表。这有点晚了,但如果我需要app1中的所有内容,而不是app1目录,我该怎么办?这看起来更像是一个装饰性的问题,尽管你似乎没有完全的自由来逃避原回购协议的结构。也许你可以使用符号链接?这有点晚了,但如果我需要app1中的所有内容,而不是app1目录,我该怎么办?这看起来更像是一个装饰性的问题,尽管你似乎没有完全的自由来逃避原始回购协议的结构。也许你可以使用符号链接?