如何从GitHub上托管的远程Git存储库中仅下载特定文件夹或目录?
假设示例GitHub存储库位于此处:
git@github.com:foobar/Test.git
其目录结构:
Test/
├── foo/
│ ├── a.py
│ └── b.py
└── bar/
├── c.py
└── d.py
我只想下载foo文件夹,而不克隆整个Test项目。
如何从GitHub上托管的远程Git存储库中仅下载特定文件夹或目录?
假设示例GitHub存储库位于此处:
git@github.com:foobar/Test.git
其目录结构:
Test/
├── foo/
│ ├── a.py
│ └── b.py
└── bar/
├── c.py
└── d.py
我只想下载foo文件夹,而不克隆整个Test项目。
Answers:
2016年9月更新:社区创建了一些工具可以为您做到这一点:
Git不支持此功能,但是Github通过SVN支持。如果您使用subversion签出代码,Github实际上将在后端将仓库从git转换为subversion,然后提供所请求的目录。
使用此功能下载特定文件夹的方法如下。我将以流行的javascript库lodash
为例。
修改要颠覆的URL。替换tree/master
为trunk
。
https://github.com/lodash/lodash/tree/master/test
➜
https://github.com/lodash/lodash/trunk/test
下载资料夹。转到命令行并使用SVN抓取文件夹。
svn checkout https://github.com/lodash/lodash/trunk/test
您可能不会立即看到任何活动,因为Github最多需要30秒来转换较大的存储库,因此请耐心等待。
完整的URL格式说明:
- 如果您有兴趣
master
分支,请trunk
改用。所以完整的路径是trunk/foldername
- 如果您对
foo
分支感兴趣,请使用branches/foo
改用。完整的路径看起来像branches/foo/foldername
- 提示:您可以根据
svn ls
需要在下载之前查看可用的标签和分支
就这样!Github还支持更多的Subversion功能,包括对提交和推送更改的支持。
tree/master
为trunk
,您就可以获取特定的文件夹。
tree/master
为trunk
。此信息应在答案中添加。
svn export
,因为我不想使用Subversion工作副本。然后,将生成的文件夹添加到Git中。(我不知何故丢失了我的目录树的很大一部分,所以我从分叉的存储库中导出了。)
branch
路径更改为branches
,我认为是正确的;如果不是,请继续将其更改。
用法:
获取令牌:
http://kinolien.github.io/gitzip,使用GitHub API和JSZip,FileSaver.js库。
步骤1:在右上角的字段中输入github网址。
步骤2:按Enter键或单击“下载”以直接下载zip或单击“搜索”以查看子文件夹和文件的列表。
步骤3:点击“下载Zip文件”或“获取文件”按钮以获取文件。
在大多数情况下,它都可以正常工作,但由于Github Trees API的限制,该文件夹包含1,000个以上的文件。(参考Github API#Contents)
如果您拥有GitHub帐户并在此站点中使用“获取令牌”链接,它还可以支持私有/公共存储库并升级速率限制。
现在,您可以从DownGit 直接为任何GitHub公共目录或文件(特别是大文件)直接下载或创建下载链接!这是一个简单的演示-
您还可以配置下载文件的属性详细用法。
downloaded 25 of 25 files
当我尝试从此URL下载时,此消息挂起: github.com/dssg/hitchhikers-guide/tree/master/curriculum/…–
如果有svn
,可以使用svn export
以下方法:
svn export https://github.com/foobar/Test.git/trunk/foo
注意URL格式:
https://github.com/
/trunk
附加在末尾在运行之前svn export
,最好先使用以下命令验证目录的内容:
svn ls https://github.com/foobar/Test.git/trunk/foo
.git
扩展名。您可以使用完整的项目链接,并先使用,svn ls
后跟项目完整路径。范例:svn ls https://github.com/RobTillaart/Arduino.git
。要仅导出一个文件夹,只需添加/trunk
后跟所需的路径,例如svn export https://github.com/RobTillaart/Arduino.git/trunk/libraries/DHTlib
。保持项目路径完整无缺。
https://github.com/miguelgrinberg/python-socketio/tree/master/examples/wsgi
,请运行svn export https://github.com/miguelgrinberg/python-socketio.git/trunk/examples/wsgi
。wsgi
将在当前工作目录下创建一个名为的目录。只有源文件,没有别的。否.git
,没有与Subversion相关的文件。
如果要下载文件,而不是用历史记录克隆存储库,则可以使用进行git-archive
。
git-archive
制作git存储库的压缩zip或tar存档。一些使它特别的东西:
.git/
文件夹或运行它的存储库中的任何未跟踪文件。docs/usage
从与ssh连接的远程仓库中创建目录存档的示例:
# in terminal
$ git archive --format tar --remote ssh://server.org/path/to/git HEAD docs/usage > /tmp/usage_docs.tar
git archive --format tar
格式不是tar.gz,而是tar。
我创建了一个名为GitHubFolderDownloader的开源项目。它使您可以下载存储库的单个文件夹,而无需克隆或下载整个存储库。
其他答案没什么问题,但我只是想与那些第一次在此过程中徘徊的人分享逐步说明。
〜要打开终端,只需单击聚光灯并键入终端,然后按Enter
顺便说一句-如果您使用Windows或其他平台,则可以在http://subversion.apache.org上找到Subversion(svn)的二进制下载。
〜如果要检出文件夹而不是简单地下载文件夹,请尝试使用svn帮助(tldr:将输出替换为checkout)
更新资料
关于恢复中断的下载/签出的评论。我会先尝试跑步,svn cleanup
然后再尝试svn update
。请在SO中搜索其他选项。
无论是谁正在处理特定文件夹,他都需要克隆该特定文件夹本身,为此,请使用稀疏签出执行以下步骤。
创建一个目录。
初始化一个Git仓库。(git init
)
启用稀疏签出。(git config core.sparsecheckout true
)
告诉Git您想要的目录(echo 2015 / brand / May(指您要使用的文件夹)>> .git/info/sparse-checkout
)
添加遥控器(git remote add -f origin https://jafartke.com/mkt-imdev/DVM.git
)
提取文件(git pull origin master
)
你不能; 与Subversion不同,在Subversion中每个子目录都可以单独检出,Git在整个存储库的基础上运行。
对于需要更细粒度访问的项目,可以使用子模块-每个子模块都是一个单独的Git项目,因此可以单独克隆。
可以想象,一个Git前端(例如GitHub的Web界面或gitweb)可以选择提供一个接口以供您提取给定的文件夹,但是据我所知,它们都没有这样做(尽管它们确实允许您下载单个文件) ,因此,如果文件夹中没有太多文件,则可以选择)
编辑 -GitHub实际上提供了通过SVN的访问,这将允许您执行此操作(根据评论)。有关如何执行此操作的最新说明,请参见https://github.com/blog/1438-improved-svn-here-to-stay-old-svn-going-away
如果您确实只想“下载”该文件夹而不是“克隆”该文件夹(以进行开发),那么最简单的方法就是简单地获取该存储库的最新版本(以及其中的一个文件夹/文件)的副本,无需克隆整个repo甚至无需首先安装git,只需通过转到GitHub上所需的存储库/ fork / branch / commit,即可下载zip归档文件(适用于任何repo,fork,branch,commit等)。 (例如,http(s)://github.com/<user>/<repo>/commit/<Sha1>
获取特定提交后的文件副本),然后选择Downloads
右上角附近的按钮。
这种存档格式不包含任何git-repo魔术,仅包含被跟踪的文件本身(如果被跟踪,则可能包含几个.gitignore文件,但是您可以忽略那些:p)-这意味着如果代码更改并且您想要保持最重要的位置,您将必须手动重新下载它,这也意味着您将无法将其用作git存储库...
不确定在这种情况下这是否就是您要寻找的内容(再次是“下载” /视图与“克隆” /开发),但是它仍然很有用...
tar.gz
以下位置下载的通用URL :https://github.com/${owner}/${repo}/archive/${hash}.tar.gz
有多种处理方法,具体取决于您要手动还是以编程方式进行。
下面总结了四个选项。对于那些希望获得更实际操作说明的人,我整理了一个YouTube视频:从GitHub下载单个文件和文件夹。
此外,对于需要从GitHub下载单个文件(而不是文件夹)的文件,我在StackOverflow上发布了类似的答案。
1. GitHub用户界面
2.第三方工具
https://github.com/babel/babel-eslint/tree/master/lib
),然后按“下载”按钮。3.颠覆
svn export https://github.com/babel/babel-eslint/trunk/lib
,然后按Enter。4. GitHub API
https://api.github.com/repos/:owner/:repo/contents/:path
。替换占位符后,示例端点为:https://api.github.com/repos/babel/babel-eslint/contents/lib
。这将为您提供该文件夹中存在的所有内容的JSON数据。数据具有您所需的一切,包括内容是否是文件夹或文件,下载URL(如果是文件)以及API端点(如果是文件夹)(以便您可以获取该文件夹的数据)。使用此数据,脚本可以递归地遍历目标文件夹中的所有内容,为嵌套文件夹创建文件夹,并下载每个文件夹的所有文件。查看DownGit的代码以获取灵感。另一个具体示例:
就像我想从网址下载“ iOS Pro Geo”文件夹
https://github.com/alokc83/APRESS-Books-Source-Code-/ tree / master /%20Pro%20iOS%20Geo
我可以通过
svn checkout https://github.com/alokc83/APRESS-Books-Source-Code-/trunk/%20Pro%20iOS%20Geo
注意路径中的树干
编辑:(根据Tommie C的评论)
是的,使用export 而不是checkout可以得到干净的副本,而无需额外的git存储库文件。
svn export https://github.com/alokc83/APRESS-Books-Source-Code-/trunk/%20Pro%20iOS%20Geo
编辑:如果树/母版不在URL中,则将其分叉,它将在分叉URL中。
有一个名为Python3的pip包githubdl
可以执行此操作*:
export GIT_TOKEN=1234567890123456789012345678901234567890123
pip install githubdl
githubdl -u http://github.com/foobar/test -d foo
项目页面在这里
*免责声明:我写了这个程序包。
这是SVN比Git更好的少数几个地方之一。
最后,我们倾向于以下三种选择:
如果您对Unix命令感到满意,则不需要特殊的依赖项或Web应用程序。您可以将压缩包下载为tarball,仅解压缩所需的文件。
示例(来自fontawesome子目录中的woff2文件):
curl -L https://api.github.com/repos/FortAwesome/Font-Awesome/tarball | tar xz --wildcards "*/web-fonts-with-css/webfonts/*.woff2" --strip-components=3
*/
)的开头部分以匹配任何目录。Github使用名称中的commit ref创建了一个包装器目录,因此无法知道。--strip-components
的斜杠(/
)数量相同。这将下载整个tarball。如果必须避免这种情况,或者如果您想对GitHub服务器友好,请使用其他答案中提到的SVN方法。
您可以简单下载目录树:
git archive --remote git@github.com:foobar/Test.git HEAD:foo | tar xf -
但是,如果您打算将其签出,并且能够进行提交并将其推回原位,那么您就不能这样做。
在我的情况下,所有答案都无济于事。如果您正在为Windows开发,则可能没有svn。在许多情况下,不能指望用户安装Git或由于其他原因而不想下载整个存储库。回答了这个问题的一些人,例如Willem van Ketwich和Aztack,为完成这项任务提供了工具。但是,如果该工具不是针对您使用的语言编写的,或者您不想安装第三方库,则这些工具将无效。
但是,有一种更简单的方法。GitHub有一个API,可让您使用GET请求下载单个文件或整个目录的内容。您可以使用https://api.github.com/repos/:owner/:repo_name/contents/:path
返回的JSON对象枚举目录中的所有文件的目录。枚举中包含指向文件原始内容(download_url
参数)的链接。然后可以使用该URL下载该文件。
这是一个两步过程,需要能够发出GET请求,但这可以在几乎任何语言,任何平台上实现。它可以用来获取文件或目录。
我们的团队编写了一个bash脚本来执行此操作,因为我们不想在裸机服务器上安装SVN。
https://github.com/ojbc/docker/blob/master/java8-karaf3/files/git-download.sh
它使用github API,可以从命令行运行,如下所示:
git-download.sh https://api.github.com/repos/ojbc/main/contents/shared/ojb-certs
我使用的CentOS 7服务器没有root访问权限,也没有git,svn等(也不想!),因此制作了一个python脚本来下载任何github文件夹:https : //github.com/andrrrl/github -文件夹下载器
用法很简单,只需从github项目中复制相关部分,假设该项目为https://github.com/MaxCDN/php-maxcdn/,并且您需要一个仅包含一些源文件的文件夹,那么您需要做类似的事情:
$ python gdownload.py "/MaxCDN/php-maxcdn/tree/master/src" /my/target/dir/
(如果不存在,将创建目标文件夹)
它需要lxml库,可以与一起安装。easy_install lxml
如果您没有root访问权限(例如我),则可以.pydistutils.py
在$HOME
目录中创建一个包含以下内容的文件:
[install]
user=1
并且easy_install lxml
可以正常工作(参考:https : //stackoverflow.com/a/ 33464597/591257)。
1)从此处下载SVN。 2)打开CMD并转到SVN bin目录,如下所示:
cd %ProgramFiles%\SlikSvn\bin
3)假设我婉下载此目录网址 4)现在更换 随着 5)现在,在同一个目录下火最后一条命令来下载文件夹。
https://github.com/ZeBobo5/Vlc.DotNet/tree/develop/src/Samples
tree/develop or tree/master
trunk
svn export https://github.com/ZeBobo5/Vlc.DotNet/trunk/src/Samples
要从GitHub导出目录,请将目录网址中的“ / tree / master /”替换为“ / trunk /”。
例如,要从以下URL导出目录:
https://github.com/liferay/liferay-plugins/tree/master/portlets/sample-hibernate-portlet
运行以下命令:
svn export https://github.com/liferay/liferay-plugins/trunk/portlets/sample-hibernate-portlet
一个简单的答案是先从下面的链接开始乌龟svn。
在安装时,请打开CLI选项,以便可以从命令行界面使用它。
复制git hub子目录链接。
例
https://github.com/tensorflow/models/tree/master/research/deeplab
用树干替换树/主树
并做
svn结帐https://github.com/tensorflow/models/trunk/research/deeplab
文件将下载到当前目录的deeplab文件夹中。
您可以通过以下方式使用git svn。
git svn clone https://github.com/lodash/lodash/trunk/test
这样,您就不必特别为Windows用户设置svn。
sudo apt install git-svn
通过WSL运行时需要。
如果您需要以编程方式进行操作并且不想依赖SVN,则可以使用GitHub API递归下载所有内容。
为了获得灵感,这是我的红宝石要点:https : //gist.github.com/cvengros/b2a7e82f66519d423b6f
git clone --filter
从Git 2.19
此选项实际上将跳过从服务器获取不需要的对象的操作:
git clone --depth 1 --no-checkout --filter=blob:none \
"file://$(pwd)/server_repo" local_repo
cd local_repo
git checkout master -- mydir/
服务器应配置为:
git config --local uploadpack.allowfilter 1
git config --local uploadpack.allowanysha1inwant 1
v2.19.0中对Git远程协议进行了扩展以支持此功能,但当时不支持服务器。但是它已经可以在本地测试。
我已经在以下文章中进行了详细介绍:如何仅克隆Git存储库的子目录?
无论出于何种原因,该svn
解决方案都不适合我,并且由于我不需要svn
其他任何东西,因此花时间尝试制作该解决方案也没有任何意义,因此我寻找了一个使用已有工具的简单解决方案。该脚本仅使用curl
和awk
下载描述为的GitHub目录中的所有文件"/:user:repo/contents/:path"
。
调用GitHub REST API "GET /repos/:user:repo/contents/:path"
命令返回的主体
返回一个对象,该对象包含"download_url"
目录中每个文件的链接。
此命令行脚本使用REST API进行调用,curl
并通过AWK发送结果,AWK过滤掉除“ download_url”行以外的所有行,从链接中删除引号和逗号,然后使用另一个调用来下载链接以进行卷曲。
curl -s https://api.github.com/repos/:user/:repo/contents/:path | awk \
'/download_url/ { gsub("\"|,", "", $2); system("curl -O "$2"); }'
git sparse-checkout
Git 2.25.0包括一个新的实验
git sparse-checkout
命令,该命令使现有功能更易于使用,并为大型存储库带来了一些重要的性能优势。(GitHub博客)
当前版本的示例:
git clone --filter=blob:none --sparse https://github.com/git/git.git
cd git
git sparse-checkout init --cone
git sparse-checkout add t
--sparse
仅将git
存储库的顶级目录文件检出到工作副本中git sparse-checkout add t
递增地添加/签出的t
子文件夹git
git sparse-checkout init
做一些准备工作以启用部分签出--filter=blob:none
通过仅下载必要的git对象来优化数据获取(请查看部分克隆功能以获取更多信息)--cone
还通过应用更多受限制的文件包含模式来提高性能GitHub在某些选择的存储库上启用了该功能后,仍在内部对其进行评估。[...] 随着功能的稳定和成熟,我们将不断向您更新其进度。(docs)