做开发这些年,GitHub 下载慢这事几乎没人能完全避开。clone 一个项目卡在remote: Enumerating objects半天不动,release 里几百 MB 的压缩包下到最后突然失败,浏览器里的进度条像被冻住——这些场景我都碰到过,而且不止一次。网上讲提速的办法很多,但要么说得太玄,要么方案本身就不稳定。这篇我把自己长期在用、实测有效的提速手段整理出来:改几个 Git 配置、换一种下载姿势、走公共 CDN,全部操作两分钟之内能配完,基本一次配置长期生效。无论你是用 Hexo 部署博客、拉开源项目跑起来,还是下载模型文件,照着抄就行。直接进正题。
1. 先搞清楚你到底慢在哪一环
提速之前先定位瓶颈,这一步很多人会跳过,结果方案试了一圈也没解决。GitHub 下载慢并不是一个原因,网页打不开、git clone 卡住、release 下载龟速,这三类问题背后的瓶颈完全不一样,用错方案反而更慢。
1.1 一条下载请求要经过哪些环节
可以把它理解成快递从仓库发到你手上的过程。你点下下载按钮之后,一次完整的请求大概要经过四个环节:
- 域名解析:把
github.com这种域名翻译成服务器的 IP 地址。这一步如果解析超时、或解析到质量很差的节点,后面全白搭。 - TCP 连接:建立一条稳定的数据传输通道。相当于快递员先得把你的收货地址跑通,能上门取件。
- TLS 握手:在通道上做加密协商,确保数据在传输过程中不被篡改。这一步通常和 TCP 连接混在一起,耗时波动也很大。
- 数据流传输:实际的数据搬运阶段。仓库文件大、连接带宽小、链路不稳定,都会在这一步暴露问题。
大多数"GitHub 慢"的体感,其实是前三个环节占了大量时间,或者第四个环节频繁断流。所以不能只看网速,得先确认是哪一环出了问题。
1.2 三种典型症状,对应三种瓶颈
我按自己踩过的坑,把现象分成了三类:
| 症状 | 最可能的瓶颈 | 常见场景 |
|---|---|---|
| 网页一直转圈、打不开 | 域名解析异常 / 连接超时 | 浏览器直接访问github.com |
git clone卡在连接或计数阶段 | 传输链路不稳定、握手超时 | 命令行拉仓库、git fetch卡住 |
| release / 大文件下载龟速、中途断 | 单连接带宽受限、链路抖动 | 下载二进制包、模型权重文件 |
区分这三类不需要多高深的手段,看现象基本能判断。网页打不开、但命令行偶尔能拉通,多数问题出在浏览器访问的链路环节;git clone能连上但传输极慢,多半是单条连接不够稳定;下载压缩包失败,常常是单连接被限速或者超时。搞清楚症状,再去翻工具箱。
1.3 两条命令,先给网络做一个体检
我习惯在做任何配置之前,先跑两条命令,看结果再决定动哪里。
第一条,用curl摸底一次页面访问,顺带把 DNS 解析时间、TLS 握手时间、总耗时都打出来:
curl -v -o /dev/null https://github.com --connect-timeout 10 --max-time 20 2>&1 | grep -E "Trying|Connected|SSL|Total time"如果输出里Trying卡了很久才进入Connected,说明域名解析或者连接阶段有问题;如果SSL阶段很久,可能是 TLS 握手不稳定;如果前面都很快,但Total time依然很长,那问题多半在数据传输阶段。
第二条,用nslookup和ping分别看解析结果和延迟:
nslookup github.com ping -c 4 github.comnslookup会显示出当前 DNS 返回的 IP 地址,ping能大致判断延迟。如果延迟忽高忽低、甚至丢包,那不管后面怎么优化,传输环节都会是短板。有了这两组数据,后面选方案就有依据了。
2. 5个立竿见影的Git配置优化
确认大方向是传输慢之后,最值得做的就是优化 Git 本身的传输行为。下面这组配置我一直在用,基本覆盖了git clone、git fetch这些高频操作,改一次全局生效。
2.1 固定 HTTP/1.1,少一次握手重传的烦恼
HTTP/2 在弱网环境下的表现有时候反而不如 HTTP/1.1。多路复用听起来确实先进,但一旦网络抖动,多个请求会互相影响,重传的开销反而把速度拖下来。Git 官方也推荐在网络质量一般的时候回退到 HTTP/1.1。
git config --global http.version HTTP/1.1这是一个全局配置,改完立即生效。我之前在一个延迟波动比较大的环境里拉仓库,默认 HTTP/2 下经常出现传输到一半卡死,切成 HTTP/1.1 之后明显稳定了很多。
2.2 调大缓冲区,降低大仓库中途失败的概率
拉大仓库时,RPC failed; curl 56这类报错非常典型。Git 通过 HTTP 传输数据时,缓冲区设置太小会导致大包被拆分后容易超时,调大之后能显著降低失败概率。习惯上我会把 postBuffer 设到 500MB:
git config --global http.postBuffer 524288000同时再配合一个压缩策略。core.compression控制 Git 传输前的压缩级别,如果仓库里主要是文本源码,默认值就行;如果仓库里有大量二进制文件、模型权重这类本来压不动的文件,建议直接关掉压缩,省去无谓的 CPU 开销:
git config --global core.compression 0实测拉过一个带 300MB 数据文件的仓库,压缩级别保持默认时内存占用高得离谱,还会频繁触发 GC;关掉压缩之后,速度反而更快,中途失败的次数也少了。
2.3 设置低速阈值,让 Git 自动放弃僵死的连接
很多人会遇到这种怪事:git clone已经跑了几分钟,进度条不动,但也没报错,就这么干耗着。与其手动 Ctrl+C 再重来,不如让 Git 自己判断。lowSpeedLimit 和 lowSpeedTime 组合使用,当传输速度低于某个阈值并持续一段时间后,Git 会主动断开并报错,方便你及时换方案。
git config --global http.lowSpeedLimit 1000 git config --global http.lowSpeedTime 60这两行的意思是:如果持续 60 秒的平均传输速度低于 1000 bytes/s,Git 就判定连接僵死,直接中断。初次看可能觉得是"负优化",但它实际上帮你省去了大量和死连接干瞪眼的时间。数值可以根据你的网络环境调整,正常宽带环境下 1000bytes/s 已经足够保守了。
2.4 浅克隆:只拉最近一次提交,速度立刻起飞
这是所有方案里见效最快的一个。很多场景下你根本不需要整个仓库的完整历史,尤其是只想读源码、编译运行、或者看看项目结构的时候。浅克隆只拉取单独一个分支的最新提交,历史记录全部省略:
git clone --depth=1 https://github.com/facebook/react.git想指定分支就加-b参数:
git clone --depth=1 -b main https://github.com/facebook/react.git一个历史库可能有几百MB的历史数据,用--depth=1往往只剩几十MB,差距非常直观。当然它也有局限:看不到历史提交、不能直接 pull 最新变化来做完整对比,参与上游 PR 流程也不建议用浅克隆。这些场景先把浅克隆拉下来,等需要完整历史时再补git fetch --unshallow,分两步走,前慢后稳。
2.5 稀疏检出:大仓库里只拉你要的目录
遇到大型 monorepo 仓库,哪怕用了浅克隆,整个仓库的体积还是很吓人。这时候就该上稀疏检出(sparse-checkout)了。它允许你只把仓库里的某些目录检出到工作区,配合--filter=blob:none还可以做到不下载文件内容,需要的部分才按需拉取。
git clone --depth=1 --filter=blob:none --sparse https://github.com/xxx/llm-project.git cd llm-project git sparse-checkout set examples scripts命令执行完后,工作区里只有examples和scripts两个目录,其他目录的占位文件可能还在树对象里,但 blob 内容不会占本地空间。如果你只是要仓库里的个别子目录,这招能用最小的代价拿到目标代码。之前拉一个几千文件的工程仓库,全量 clone 要 700MB,用这个方式只下载了 30MB 左右就拿到了指定目录。
2.6 一条命令汇总,以后配置不用记
把上面这些常用配置合并成一段,执行完就全部写进全局配置:
git config --global http.version HTTP/1.1 git config --global http.postBuffer 524288000 git config --global core.compression 0 git config --global http.lowSpeedLimit 1000 git config --global http.lowSpeedTime 60这些配置都是幂等的,重复执行不会有副作用。拉仓库时的行为建议单独记:优先--depth=1,需要大仓库局部内容时再加--sparse。整套组合下来,我没有再因为 Git 自身配置问题卡过传输。
3. 下载release和大文件时换条路走
很多人习惯打开 GitHub 页面,点 release 里的 zip 包,再用浏览器默认下载。这个方法在绝大多数情况下不会是速度最优解,稍微换一下工具和思路,下载效率立刻就不一样。
3.1 命令行下载加断点续传,断了也能接着跑
浏览器下载一旦中途断流,进度基本清零,特别打击心态。命令行下载可以断点续传,断了之后从断点位置继续,不用从头再来,这对 GitHub 上的大文件非常关键。
用wget的方式:
wget -c https://github.com/用户名/仓库名/releases/download/v1.0.0/release.zip用curl的方式也可以,-C -表示自动从上次的断点继续,-L表示跟随重定向,-O保存为远程文件名:
curl -C - -L -O https://github.com/用户名/仓库名/releases/download/v1.0.0/release.zipGitHub release 下载地址一般会做重定向,最终指向实际托管文件的位置。只要服务器支持 Range 请求(GitHub codeload 是支持的),续传就没问题,实测中断后继续下载,速度稳定。
3.2 zip包和git clone,别用错了场景
很多人分不清什么时候该下 zip 包、什么时候该git clone。我的经验是分场景选择:
| 目的 | 推荐方式 | 原因 |
|---|---|---|
| 只看代码、解压即用 | 下载 zip 包 | 体积小,不需要 Git 历史 |
| 跑起来测试、编译项目 | git clone --depth=1 | 浅克隆只占最新版本,方便 |
| 要提交 PR、参与开发 | 完整git clone | 需要完整历史才能正常 rebase |
| 仓库里有大文件 | 优先下载 release | release 里的包通常不包含历史记录 |
如果一个项目已经打了 tag、发布了 release,直接用 release 里的归档通常比git clone全量仓库要小。因为很多仓库的代码提交记录本身就非常占空间,归档文件其实是"当前代码 + 子模块声明"的快照,并不包含 split 出来的各类大体积中间文件。
3.3 多线程并发下载 release 大文件
命令行续传解决了"下载中断"的问题,但单连接的速度上限依然存在。想要进一步提效,可以考虑aria2这类支持多线程下载的工具。它能把一个文件拆成多个分片同时下载,再从本地合并,效果立竿见影。
aria2c -x 16 -s 16 -d /path/to/save https://github.com/用户名/仓库名/releases/download/v1.0.0/release.zip-x 16表示单服务器最大 16 个连接,-s 16表示把文件拆成 16 个分片。实测从一个 200MB 左右的 release 文件看,默认单线程下经常下载到一半就超时失败,换成 16 线程之后几乎没再断过,整体耗时也能接受。要注意的是,并发太高会挤压其他应用带宽,-x 8多数场景下已经够用。另外,拆分的分片在本地合并时也会占用一点磁盘 IO,机械硬盘上并发数不要开过头。
3.4 单文件直接走公共CDN,不占Git通道
如果你只需要仓库里的某个文件,比如一个配置文件、一份 README、一张素材图,完全没必要整个仓库拉下来。公共 CDN 可以按文件路径直接获取 GitHub 仓库里的内容,速度比走 GitHub 原始地址稳定很多。
以 jsDelivr 为例,URL 格式是:
https://cdn.jsdelivr.net/gh/用户名/仓库名@分支名/文件路径比如拉取某个公开仓库里的 README 文件:
curl -L -O https://cdn.jsdelivr.net/gh/facebook/react@main/README.md这种方式的优点是轻量、快,尤其适合脚本里需要动态拉取远程配置文件或模板的场景。注意@后面跟的必须是分支名、tag 或 commit hash,不能写latest;文件路径里的空格建议用 URL 编码处理。公共 CDN 有文件大小限制,单个文件几十 MB 内没问题,超过就还是回到 release 下载的方案。
3.5 通过公开代码托管平台的导入功能绕开拥堵链路
还有一种非常实用、但容易被忽略的思路:借助公开代码托管平台提供的仓库导入功能。不少平台支持直接从 GitHub 导入公开仓库,导入完成后,你可以从该平台的地址直接克隆项目。等于让平台帮忙把你的仓库快照"搬"到了另一个网络环境下,本地再从该平台拉取,效率和稳定性都会好不少。
大致流程是:
- 在目标平台(比如 GitCode 等支持导入的公开平台)新建仓库,选择"从 GitHub 导入"。
- 粘贴 GitHub 仓库地址,等待平台完成导入。
- 用该平台生成的仓库地址执行
git clone。
需要提醒三点。第一,只建议导入公开项目,私有项目没有必要;第二,导入动作需要遵守原项目的 LICENSE 条款,尤其是涉及再分发时要看清许可;第三,导入的是当时的一个快照,项目后续有更新,需要再导入一次才能同步到最新状态。这套方案比较适合:本地网络偶尔能连 GitHub 但极不稳定、又必须跑起来一个大项目时作为备选路线,我自己在部署博客源码时就经常这么干。
4. 常见问题与排查技巧实录
配置改完了,方案也试过了,实际操作中还是会遇到各种奇奇怪怪的问题。我把这几年攒下的排查经验整理成一份实录,遇到类似情况直接对照抄。
4.1 换了DNS之后还是打不开、还是很慢
有时候调整 DNS 解析的设置,但问题依然没有解决。建议先确认当前系统是否真的使用了新配置。Windows 上执行ipconfig /flushdns刷新本地 DNS 缓存,Linux 上重启systemd-resolved;然后再跑一次nslookup github.com,看返回的 IP 地址有没有变化。
如果解析结果还是老样子,尝试显式配置公共 DNS。比较常见且稳定的几个公共 DNS 地址,比如223.5.5.5、119.29.29.29、114.114.114.114,均可以分别配置后对比ping延迟。我自己习惯用223.5.5.5作为首选,解析速度整体稳定。更换 DNS 之后记得清缓存,否则配置会延迟生效。
4.2git clone到一半报 RPC failed / unexpected disconnect
这是命令行拉仓库最常见的一种报错。导致的原因通常是三个:HTTP 缓冲区太小、单连接传输超时、仓库体积太大。按顺序排查:
- 确认
http.postBuffer已经调到较大值(如 524288000); - 确认
http.version已固定为 HTTP/1.1; - 如果仓库真的很大,改用浅克隆先拉最新提交。
如果已经执行到一半中断,最省心的做法是把不完整的目录删掉,再用--depth=1重新拉。不要尝试手动修补一个已损坏的.git目录,大多数时候会越搞越乱。等浅克隆成功之后,如果确实需要完整历史,再找网络比较稳定的时候执行git fetch --unshallow补全。
4.3 文件下到90%多卡死,进度条不动了
这个现象在浏览器下载 release 大文件时尤其常见。下载到 90% 多时服务器连接被掐断,但浏览器不会自动续传。解决的思路只有一个:换命令行工具续传。
curl -C - -L -O https://github.com/用户名/仓库名/releases/download/v1.0.0/release.zip注意续传的前提是服务器支持 Range 请求,GitHub release 下载地址支持。如果续传之后依然在同一个位置卡住,那多半是网络链路本身对长连接有限制,换成 aria2 的多线程方案通常能绕开。
4.4 只想拿一个文件,却被迫下了一整个包
这是最让人抓狂的场景之一。有时你只想要仓库里的一个 YAML 配置模板,浏览器下载 zip 包却要拉几 MB 甚至几十 MB。这种时候别犹豫,直接用前面提到的公共 CDN 方案,或者用 GitHub 的 raw 文件地址:
curl -L -O https://raw.githubusercontent.com/用户名/仓库名/分支名/文件路径注意raw.githubusercontent.com这个域名在实际使用中也可能速度不稳,所以如果它也不给力,就切到公共 CDN。两个方案都很快,哪个通就用哪个。
4.5 网络忽快忽慢,Git总是超时
遇到极端不稳定的网络,光靠配置还不够,得加一点自动化重试。你可以写一个简单的循环,多次尝试克隆,直到成功为止:
url="https://github.com/用户名/仓库名.git" for i in 1 2 3 4 5; do git clone --depth=1 "$url" && break echo "第 $i 次尝试失败,等待 5 秒后重试..." sleep 5 done这个脚本比较适合你在无人值守时拉项目,比如早上一来发现跑完了。当然也别无限重试,5 次失败之后大概率是网络整体问题,这时候再换 3.5 节里的公开平台导入方案更靠谱。
4.6 一份速查表,拿走不谢
| 目标 | 推荐操作 |
|---|---|
| 网页打不开 | 检查 DNS 配置,刷新缓存,换公共 DNS |
git clone卡住 | 固定 HTTP/1.1,调大 postBuffer,启用浅克隆 |
| 大仓库只要局部目录 | git clone --depth=1 --sparse后执行sparse-checkout set |
| release 大文件下载失败 | wget -c或curl -C -续传;不行就上 aria2 |
| 只想要单文件 | 用公共 CDN URL 直接拉单个文件 |
| 大项目整体拉不下来 | 试试通过公开代码托管平台导入后再克隆 |
我个人现在拉 GitHub 项目的习惯基本固定下来了:单文件走公共 CDN,大仓库用浅克隆加稀疏检出,release 大文件交给 aria2 多线程,极端不稳定的网络下靠循环重试兜底。提速的本质不是去找什么万能方案,而是先想清楚自己被卡在哪个环节,再把那个环节绕开或者调优。上面这些配置加起来能在两分钟之内配完,大部分还是一次配置长期生效,之后你下载 GitHub 项目的时候,至少能少砸几次键盘。