我经常只想从 GitHub 仓库里拿几个文件或某个目录,于是做了 `gh-download`

0 阅读7分钟

github.com/belingud/gh…

很多工具,并不是从一个宏大的计划里长出来的,而是从一件反复出现的小麻烦开始的。

我做 gh-download,起点就很具体。

我在 GitHub 上经常遇到一种需求:我不要整个仓库,我只想下载其中一部分内容。

有时候是一个目录,比如文档目录、脚本目录、模板目录;有时候是某几个单独文件,比如配置文件、说明文件、示例代码;还有一种很常见的情况,就是下载某个 skill 目录。一个 skills/xxx 下面,往往带着脚本、说明文档和 reference/ 材料,我真正需要的,其实就是这一小块内容,而不是整个仓库。

但这件事,平时做起来并不顺。

过去我一般会用浏览器插件去下载 GitHub 上的某个目录。问题是,下载回来的通常是一个 zip 包。接下来还要手动解压、整理目录、调整名字、再挪到目标位置。只是下载仓库里的一小部分内容,本来应该是一条命令能做完的事,最后变成了一串机械操作。

做的次数一多,就会发现问题不在“能不能下载”,而在“这一步为什么还这么绕”。

我想解决的,不是下载本身,而是下载前后的麻烦

现成办法当然有。

git clone 可以拿到整个仓库,但很多时候我并不需要完整仓库,更不需要历史记录。为了一个目录、几个文件,甚至只是某个 skill 去克隆整个项目,动作太重。

直接找 raw 链接也能拿单个文件,但目录就不方便了。目录里有脚本、有子目录、有 reference,还可能要指定分支,甚至要处理私有仓库。手工拼这些步骤,既费时间,也不稳定。

浏览器插件能下载目录,但结果是 zip。下载之后还要再收拾一遍,这对偶尔点几下网页的人还算能接受,对经常在终端、脚本和自动化流程里工作的人来说,就不够顺手了。

我真正想要的是另一种体验:

  • 给我仓库名
  • 给我仓库内路径
  • 给我本地保存位置
  • 剩下的交给工具完成

它应该先判断这个路径是文件还是目录,再决定怎么下;目录要能递归保存,结构不能乱;文件要能直接落到指定位置;本地已有文件时要有明确策略;要能指定分支,也要能处理私有仓库。再进一步,它最好还能直接接进脚本里,而不是只能给人手工点着用。

于是有了 gh-download

gh-download 是一个按 GitHub 仓库路径下载内容的命令行工具。你可以下载单个文件,也可以把整个目录递归拉到本地。

对我来说,它最典型的使用场景不是“下载整个仓库”,而是“把仓库里真正要用的那一部分内容直接拿到本地”。有时是某个 skill 目录,有时是一个文档目录,有时就是某几个文件。

像这样:

gh-download jimliu/baoyu-skills skills/baoyu-translate ~/.codex/skills

这条命令做的事很直接:

  • jimliu/baoyu-skills 里找到 skills/baoyu-translate
  • 识别它是一个目录,而不是单文件
  • 把目录下面的内容递归下载下来
  • 按原有相对路径写到本地

中间不需要手动下 zip,不需要额外解压,也不需要再手工把目录挪来挪去。

这正是我当初想要的那一步。

上手快

如果你平时也会做类似的事,试起来很快。

先安装:

cargo install gh-download

拿单个文件:

gh-download openai/openai-python README.md .

拿整个目录:

gh-download owner/repo docs ./downloads

下载私有仓库内容:

gh-download owner/private-repo skills/my-skill ./skills/my-skill --token "$GITHUB_TOKEN"

如果你要拿多个分散的文件,按路径各跑一次就可以:

gh-download owner/repo README.md .
gh-download owner/repo docs/guide.md ./docs/
gh-download owner/repo .github/workflows/ci.yml ./.github/workflows/

这些例子背后,其实都是同一件事:你给出仓库、仓库内路径和本地目标,工具把剩下的步骤补齐。

这个工具,我重点把哪几件事做顺了

我没有把它做成一个“大而全”的 GitHub 客户端,而是盯着“按路径下载”这件事,把几个最容易让人不舒服的地方处理掉。

1. 目录和文件都能直接下

很多工具只适合拿单文件,碰到目录就开始绕路。gh-download 会先用 GitHub metadata API 判断目标到底是文件还是目录,再选对应策略。对使用者来说,不需要先猜,不需要自己切换命令。

2. 目录下载下来,结构保持原样

skill 目录通常不是单层结构,下面可能还有脚本、子目录和参考资料。目录下载时,gh-download 会把相对路径一并保留下来,不会把内容摊平,也不会把目录关系弄乱。

3. 单个文件也能直接落到指定位置

很多时候,我们不是要一个目录,而是只拿某几个文件。gh-download 支持按仓库路径直接下载单文件,本地目标既可以是明确文件路径,也可以是已有目录。这样你不需要先手动打开 raw 链接,再自己整理保存位置。

4. 不克隆整个仓库,不干多余的事

这个工具的目标很明确:只下载你指定的那段内容。你不需要为了一个目录、几个文件或某个 skill 去克隆整个仓库,也不需要自己清理不相关文件。

5. 终端能用,脚本也能用,AI更能用

我自己会把这类工具放进日常脚本里,所以 gh-download 不只考虑“命令能跑”,也考虑“脚本怎么接”。它支持 --json 输出结果,适合放进自动化流程;也支持 --ref--token 这些实际会用到的参数,公开仓库和私有仓库都能覆盖。

6. 把边界定义清晰

很多命令行工具,一旦进入网络、代理、认证这些环节,行为就容易变得模糊。这个项目里,我刻意把边界写得很清楚:

  • 先通过 GitHub metadata API 判断目标类型
  • raw 文件下载的代理行为是显式配置,不是偷偷改路由
  • 带 token 时,不把凭据转给公共代理
  • 下载时直接流式写盘,不把整个文件先塞进内存

这些点看起来不像宣传卖点,但它们决定了这个工具在真实环境里是不是让人放心。

它适合什么人

gh-download 适合的不是所有 GitHub 用户,而是下面这类人:

  • 经常只想拿仓库里的某个目录,或者某几个文件
  • 会复用别人的 skill、模板、脚本或文档目录
  • 希望把下载动作放进终端习惯、安装脚本或 CI 流程
  • 不想每次都经历“下载 zip、解压、整理目录”这一套重复动作

换句话说,它不追求替代 git clone,而是在 git clone 太重、手工下载太慢的时候,提供一条更短的路径。

我希望它成为一个“拿来就用”的小工具

我很喜欢那种边界清楚、目的单一、装上就能工作的命令行工具。它不一定庞大,但足够可靠;不一定覆盖所有场景,但能把一个常见动作做得省心。

gh-download 就是按这个方向做的。

我做它,不是因为“GitHub 下载”这件事没人碰,而是因为我自己反复遇到一个具体场景:想从仓库里拿一小部分内容,可能是一个 skill 目录,可能是一个文档目录,也可能是几个单独文件,现成办法总要多走几步。既然这个动作会一再出现,那就值得把它缩成一条命令。

你平时也会从 GitHub 上取某个目录、某个模板、几份配置文件,或者直接拿一个 skill 放进本地环境的话,gh-download 也许正好能省掉中间那些重复步骤。

项目地址:

github.com/belingud/gh…