很多工具,并不是从一个宏大的计划里长出来的,而是从一件反复出现的小麻烦开始的。
我做 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 也许正好能省掉中间那些重复步骤。
项目地址: