如何从GitHub上托管的远程Git repo中仅下载特定文件夹或目录?

举个GitHub repo的例子:

git@github.com:foobar/Test.git

其目录结构:

Test/
├── foo/ 
│   ├── a.py
│   └── b.py   
└── bar/
    ├── c.py
    └── d.py

我只想下载foo文件夹,而不是克隆整个测试项目。


当前回答

这是我用git v2.25.0做的,也是用v2.26.2测试的。这个技巧不适用于v2.30.1

TLDR

git clone --no-checkout --filter=tree:0 https://github.com/opencv/opencv
cd opencv

# requires git 2.25.x to 2.26.2
git sparse-checkout set data/haarcascades

您可以使用Docker来避免安装特定版本的git

git clone --no-checkout --filter=tree:0 https://github.com/opencv/opencv
cd opencv

# requires git 2.25.x to 2.26.2
docker run --rm -it -v $PWD/:/code/ --workdir=/code/ alpine/git:v2.26.2 sparse-checkout set data/haarcascades

完整解决方案

# bare minimum clone of opencv
$ git clone --no-checkout --filter=tree:0 https://github.com/opencv/opencv
...
Resolving deltas: 100% (529/529), done.

# Downloaded only ~7.3MB , takes ~3 seconds
# du = disk usage, -s = summary, -h = human-readable
$ du -sh opencv
7.3M    opencv/

# Set target dir
$ cd opencv
$ git sparse-checkout set data/haarcascades
...
Updating files: 100% (17/17), done.
# Takes ~10 seconds, depending on your specs

# View downloaded files
$ du -sh data/haarcascades/
9.4M    data/haarcascades/
$ ls data/haarcascades/
haarcascade_eye.xml                      haarcascade_frontalface_alt2.xml      haarcascade_licence_plate_rus_16stages.xml  haarcascade_smile.xml
haarcascade_eye_tree_eyeglasses.xml      haarcascade_frontalface_alt_tree.xml  haarcascade_lowerbody.xml                   haarcascade_upperbody.xml
haarcascade_frontalcatface.xml           haarcascade_frontalface_default.xml   haarcascade_profileface.xml
haarcascade_frontalcatface_extended.xml  haarcascade_fullbody.xml              haarcascade_righteye_2splits.xml
haarcascade_frontalface_alt.xml          haarcascade_lefteye_2splits.xml       haarcascade_russian_plate_number.xml

工具书类

git稀疏签出日志git稀疏签出文档gitfilter props文档

其他回答

对于通用git Repo:

如果您想下载文件,而不是克隆具有历史记录的存储库,可以使用gitarchive来完成此操作。

gitarchive生成git存储库的压缩zip或tar存档。让它与众不同的一些东西:

您可以选择git存储库中要归档的文件或目录。它不会将.git/文件夹或其运行的存储库中任何未跟踪的文件归档。您可以归档特定的分支、标记或提交。使用git管理的项目通常使用它来生成项目版本(beta、release、2.0等)的存档,供用户下载。

使用ssh从远程存储库创建docs/usage目录归档的示例:

# in terminal
$ git archive --format tar --remote ssh://server.org/path/to/git HEAD docs/usage > /tmp/usage_docs.tar

更多信息请参阅本博客文章和git文档。

GitHub Repos注意事项:

GitHub不允许git存档访问。☹️

如果您有svn,可以使用svn导出来执行以下操作:

svn export https://github.com/foobar/Test.git/trunk/foo

请注意URL格式:

基本URL为https://github.com//末尾附加的树干

在运行svn导出之前,最好先使用以下命令验证目录的内容:

svn ls https://github.com/foobar/Test.git/trunk/foo

我在CentOS 7服务器上工作,但我没有root访问权限,也没有git、svn等(也不想!),所以制作了一个python脚本来下载任何github文件夹:https://github.com/andrrrl/github-folder-downloader

用法很简单,只需从github项目中复制相关部分,假设该项目是https://github.com/MaxCDN/php-maxcdn/,如果您需要一个仅包含某些源文件的文件夹,则需要执行以下操作:

$python gdownload.py“/MaxCDN/php MaxCDN/tree/master/src”/my/target/dir/(如果不存在,将创建目标文件夹)

它需要lxml库,可以与easy_install lxml一起安装如果您没有root访问权限(像我一样),可以在$HOME目录中创建一个.pydistutils.py文件,其中包含以下内容:[安装]用户=1easy_install lxml将正常工作(参考:https://stackoverflow.com/a/33464597/591257).

我找到的最简单的方法是如何仅克隆Git存储库的子目录?

我在gitclone命令中添加了-b<branch>--singlebranch以下载特定的分支。所以我使用的命令是:

git clone --depth 1 --single-branch -b <branch> --filter=blob:none --sparse <url>
git sparse-checkout set <directory>

如果您熟悉unix命令,则不需要特殊的依赖项或web应用程序。您可以将回购文件下载为tarball,并只下载您需要的内容。

示例(font真棒中的子目录中的woff2文件):

curl -L https://api.github.com/repos/FortAwesome/Font-Awesome/tarball | tar xz --wildcards "*/web-fonts-with-css/webfonts/*.woff2" --strip-components=3

有关链接格式的详细信息:https://developer.github.com/v3/repos/contents/#get-存档链接(包括如何获取zip文件或特定分支/refs)保留路径的初始部分(*/)以匹配任何目录。Github创建了一个包装器目录,名称中包含commit ref,因此无法知道。您可能希望--strip组件与路径中斜杠(/)的数量相同(上一个参数)。

这将下载整个tarball。如果必须避免这种情况,或者如果您想对GitHub服务器友好,请使用其他答案中提到的SVN方法。