news 2026/10/9 6:05:59

GitHub克隆/推送慢?3行Git指令+SSH/浅克隆实战提速

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GitHub克隆/推送慢?3行Git指令+SSH/浅克隆实战提速

GitHub克隆/推送速度慢这个话题,几乎隔几天就会在技术群里被捞起来一次。症状非常固定:git clone跑了一半,进度条卡在Receiving objects,接着一行RPC failed; curl 18 transfer closed with outstanding read data remaining直接终结任务;或者git push推到 90%,客户端报The remote end hung up unexpectedly。很多人第一时间会想换网络、上工具,但其实不依赖任何外部网络调整,仅靠 3 行 Git 指令,就能把绝大多数“能连但慢、慢到断”的问题压下去。这篇文章不谈玄学,只讲指令原理、适用边界和一套可复制的排查思路,适合总在 Git 传输上翻车的开发者、运维和经常维护开源仓库的人。

1. 先判断:你的慢是“真慢”还是“假断”

1.1 典型症状:进度条卡死的三种现场

Git 传输慢和网络下载慢不一样,它很少真的“匀速慢”,更多是“一阵一阵卡死,最后连都连不上”。我自己见过三种高频现场:

第一种,Enumerating objects阶段卡住。仓库只有几百兆,但 Git 要先把所有对象枚举出来,这个阶段如果长时间不动,往往是服务器端在压缩包,或者本地 DNS 解析后连到的节点链路质量很差。此时git clone -v能看到 TCP 连接已建立,但数据就是不动。

第二种,Receiving objects进度条停在某个百分比,比如 37%、68%,过几十秒后直接报错。这类是最典型的“低速误杀”或者“缓冲区溢出”。不是断开,而是 Git 在等待数据传输时,发现一段时间内速度低于阈值,主动放弃了。

第三种,git push时推不上去。本地仓库挺完整,前面编译、提交都正常,但一 push,数据包发到一半,远端就挂断了。这种通常是 HTTP 通道在传输大对象时缓冲设置不够,或者网络中间设备掐断了长时间空闲的连接。

这三个场景的共同点是:网络链路并没有彻底不可用,Git 客户端却在传输层做了过多“安全动作”。知道这一点很重要,因为后面那 3 行 Git 指令,本质上就是用来关掉这些动作的。

1.2 用 git 输出和错误码锁定故障点

在动手改配置前,我建议先花两分钟复现一下问题,拿到更多信息。不要上来就复制网上一堆配置,那样出了问题都不知道是哪条引起的。

可以先加verbose参数重跑一次:

git clone -v https://github.com/user/repo.git

如果想看到底层 HTTP 传输细节,还可以临时打开两个环境变量:

export GIT_TRACE=1 export GIT_CURL_VERBOSE=1 git clone https://github.com/user/repo.git

你会看到大量的curl日志,包括连接了哪个 IP、TLS 握手用时多少、是哪个阶段断开的。看到这些之后,再对照下面的错误码就清楚多了:

报错片段大概率原因
curl 18 transfer closed with outstanding read data remaining连接建立后数据传输中断
curl 56 failure when receiving data from the peer对端发完数据前关闭了连接
Unable to rewind rpc post dataHTTP POST 缓冲回卷失败,常见于大文件推送
The remote end hung up unexpectedly服务端主动断开,也可能是本地缓冲太小
Failed to connect to github.com port 443: Connection timed outTCP 层面连不上,改配置无效

如果你发现错误集中在“连接建立后但传输中途断开”,那恭喜,这正是 3 行 Git 指令的射程范围。如果是Connection timed out,那属于 TCP 链路问题,后面第 4 章会讲对应的处理思路。

2. 3 行 Git 指令拆解:为什么这三条能续命

网上一提到 GitHub 克隆慢,就会有人贴出三条命令,但很少解释它们到底改了什么。这里先给出完整的三行:

git config --global http.postBuffer 524288000 git config --global http.lowSpeedLimit 1 git config --global http.lowSpeedTime 999999

这三行的作用不是“加速”,而是不要因为传输慢而自杀。放在一个生活化的类比里:你点了一份外卖,配送员在路上堵车,你要做的不是催他每三秒报一次位置,而是把“我等不下去”的时限从 3 分钟改成 11 天。Git 默认有些策略太激进,碰到跨地域的不稳定链路时,会把“卡顿”误判为“断连”,然后主动放弃。

2.1 第一行:postBuffer 解决“写不进去”的假死

http.postBuffer改的是 HTTP 发送缓冲区的大小,默认值通常是 1MB。这个值的影响在推送大对象时尤其明显。

你可以把 Git 通过 HTTPS 推送数据,想象成用一根吸管往瓶子里注水。吸管很细没关系,但如果储水槽只有 1MB,水灌满之后,Git 就必须停下来等待服务端确认,确认完了再倒下一批。如果这个确认环节因为网络延迟变得很慢,吸管里面就容易出现“堵住”的现象,最终连接假死。把缓冲区调到 500MB 左右,相当于换了个大储水槽,同样一次推送可以少很多次停下来等待,整个流程顺滑得多。

524288000这个数字就是 500MB。如果你的机器内存比较小,比如只有 1GB,也可以折中用536870912或者降到52428800(50MB)。我用的时候发现,500MB 在绝大多数开发机上都没有压力,Git 也不是真的把 500MB 全塞在内存里,只是给了一个上限。

2.2 第二、三行:lowSpeedLimit/lowSpeedTime 关掉“误杀”

http.lowSpeedLimit和http.lowSpeedTime是一对组合参数,含义是:当传输速度低于lowSpeedLimit字节/秒,并且持续了lowSpeedTime秒,Git 就认为这条连接已经没有价值,主动中断。

默认情况下,这个阈值和持续时间都是 0,理论上不会触发。但问题在于,很多人用的系统发行版、Git GUI 客户端或者历史遗留的全局配置,会在不知情的情况下注入一组数值。比如有的环境默认把lowSpeedLimit设成了 1000,lowSpeedTime设成了 30。这在局域网没问题,但跨境访问 GitHub 时,瞬时速度低于 1KB/s 太常见了,只要持续 30 秒,Git 就会决定“你太慢了,我不等了”。

所以第二行把速度阈值设成1,第三行把持续时间设成999999,等效于:只要传输速度没有完全变成 0,并且持续 11 天以上,Git 就绝不主动断开。这会让你在慢速但不中断的网络里,慢慢磨也能把仓库拉完。

2.3 三行指令的正确落地姿势

三条命令执行完后,建议校验一下,避免你改了全局配置但被路径下的局部配置覆盖:

git config --global --list | grep http

如果看到了三条配置,说明已经生效。接着可以重新跑一次刚才失败的操作。注意一点:这三行只对 HTTPS 方式的 Git 传输生效,对你用浏览器下载 zip 包、或者用 SSH 协议都没有作用。

另外,如果是公司统一维护的 Git 服务器,别在全局配置里塞这些值,直接使用:

git -c http.postBuffer=524288000 -c http.lowSpeedLimit=1 -c http.lowSpeedTime=999999 clone https://...

这样可以做到只针对当前这条命令生效,不影响其他仓库。

3. 光改配置不够:配合浅克隆和 SSH,把传输量降一半

3.1 浅克隆与单分支:只下载你需要的提交

如果仓库本身很大,比如历史提交几千次、里面还躺着不少大文件,那么再怎么调缓冲也只能保证“不死”,并不能让速度变快。真正的提速逻辑是:少传数据。

Git 官方早就提供了浅克隆方案,你可以只取最新的一次提交:

git clone --depth 1 --single-branch --branch main https://github.com/user/repo.git

--depth 1表示只拉取最近 1 条提交记录,--single-branch表示只拉main分支。这样克隆下来的仓库体积,往往只有完整仓库的十分之一甚至更小。原因是 Git 不再需要为历史上所有版本生成打包数据,服务端的 CPU 开销也大幅降低,通常能明显缓解Enumerating objects阶段的卡顿。

如果你已经完成了一个全量克隆,只是想裁掉历史,也可以用:

git fetch --depth 1

这会让你本地变为浅仓库。但要注意,浅克隆对后续的git push有限制,如果你想给这个仓库提交代码并推送,通常需要先执行git fetch --unshallow拉全历史。所以我的建议是:以读为主就浅克隆,以写为主还是老老实实全量拉取。

3.2 SSH 认证协议:绕开 HTTP 层的额外开销

HTTPS 克隆慢,除了网络因素,还因为 HTTP 层做了很多 TLS 握手的开销,每次连接都要经历一次完整的证书验证。而 SSH 协议走的是长连接,对频繁操作更友好,也更稳定。

切换方式很简单,先生成一对密钥,如果已经有的话可以跳过:

ssh-keygen -t ed25519 -C "你的邮箱"

然后把~/.ssh/id_ed25519.pub的内容复制到 GitHub 的 SSH keys 设置页。接下来在仓库目录里执行:

git remote set-url origin git@github.com:user/repo.git

用ssh -T git@github.com验证一下,通了之后,后续的 clone 和 push 都会走 SSH 通道。我自己维护开源项目时,凡是频繁 push 的仓库都换成了 SSH,基本没再遇到 HTTP 通道那种莫名的中断。

3.3 大仓库推送技巧

如果你的仓库里有大量图片、压缩包,即使三行配置和 SSH 都用了,push 依然可能很吃力。这时候还可以考虑 Git LFS(Large File Storage),把图片、二进制文件托管到 LFS 存储里。

git lfs install git lfs track "*.zip" git add .gitattributes git commit -m "track zip files with LFS" git push origin main

LFS 本身也是 Git 官方扩展,好处是普通小文件照常走 Git 协议,大文件单独通过 LFS 端点传输。但要注意 GitHub 免费版有 LFS 配额限制,超大仓库还是需要规划一下。

还有一个很多人忽略的点:git push之前先跑一次git fsck检查对象完整性。本地仓库如果有一些损坏对象,推送时会导致服务端反复尝试,速度感和实际耗费时间都会被放大。

4. 从报错反推:常见 GitHub 克隆失败场景与对症下药

4.1 RPC failed; curl 18 / 56 的排查

这条报错是 GitHub 克隆慢场景里的“主角”。先说结论:出现curl 18时,按顺序做三件事,能解决八成问题。

第一步,执行那三行 Git 指令。这能排除客户端主动断连的因素。第二步,如果还是断,就换 SSH 协议,因为 SSH 不依赖 HTTP 的缓冲机制。第三步,用浅克隆测试,把问题缩小到“仓库本身数据量太大”还是“网络传输链路不稳定”。

curl 56和curl 18技术细节不同,现象却很相似,都是接收数据时中断。除了上面三步,还可以尝试强制使用 HTTP/1.1,避免 HTTP/2 多路复用在弱网环境下的连接重置:

git config --global http.version HTTP/1.1

这条配置对某些网络环境效果明显。要命的是,很多人不知道它和 postBuffer 是互补关系,两者一起配上之后,原本频繁断开的克隆,很多就一次通过了。

4.2 “Unable to rewind rpc post data”与缓冲区

如果你的报错里出现Unable to rewind rpc post data,那基本就是 HTTP POST 缓冲区的锅。这个错误在推送大对象时特别常见,Git 试图重新定位 HTTP POST 的数据流位置,但因为缓冲区太小或者网络不稳定而失败。

处理方法依然是把http.postBuffer调大。如果调大后依然无效,还可以尝试降低打包时的压缩窗口,减少内存负担:

git config --global pack.window 0

pack.window控制 Git 在打包时对对象做增量压缩的“参考窗口”大小。默认值越大,压缩率越高,但消耗内存和 CPU 也越多。在低速网络上,过高的压缩率意味着服务端需要更多时间准备数据包,客户端也需要更多时间解压,反而拖慢整体速度。把这个值设成 0,相当于放弃增量压缩,直接传完整对象,虽然名义上“数据量更大”,但因为省掉了前后端的压缩等待,实际体验常常更快。

4.3 推送时 “error: failed to push some refs” 的处理

这个报错很多人误以为是速度问题,其实它是“远端有更新,本地没有拉取”导致的拒绝推送。但在跨域环境下,拉取本身也会触发前面那些网络问题,所以你要做的不是硬推,而是先把同步做好。

推荐设置:

git config --global pull.rebase true

然后每次推送前,先git pull --rebase把本地改动重新放到远端最新提交之后,再执行git push。这样做的好处是,如果远端有新提交,你不会因为 merge 提交而和上游历史纠缠。拉取时也可以用git fetch --depth 1再 rebase,降低历史数据消耗。

如果这还解决不了,再看看是否本地仓库有对象损坏,或者分支名和远端不一致。很多人卡在这一步,其实是把问题归错方向了。

5. 一套完整的提速方案:从 clone 到 push 的实战复盘

5.1 实践场景:克隆一个带大量图片的 Hugo 博客仓库

我自己维护过一个 Hugo 博客仓库,主题里塞了大量截图和压缩包,完整仓库差不多 2.3GB,历史提交 2000 多次。在未做任何配置之前,在国内网络环境下执行git clone https://github.com/user/blog.git,每次都会卡在Receiving objects的 70% 左右,然后报curl 18。

当时的电脑是 Windows 10,Git 版本 2.39,属于最常见的环境。我记录了一下修复全过程,你可以完全照着操作。

5.2 分步执行过程:诊断、配置、切换协议、复爬

第一步,我先执行了三行基础配置:

git config --global http.postBuffer 524288000 git config --global http.lowSpeedLimit 1 git config --global http.lowSpeedTime 999999

接着再次克隆,发现断开的频率降低了,但速度依然很慢,Receiving objects从 70% 熬到了 92%,还是断了。这让我意识到,瓶颈不只是客户端超时,仓库本身的传输量太大。

第二步,我改用浅克隆,看看分支主干的体积是否可接受:

git clone --depth 1 --single-branch --branch main https://github.com/user/blog.git

结果只用了不到 10 分钟就把最新版本拉下来了。但作为维护者,我不能一直停留在浅克隆状态,后面需要全量历史才能正确生成站点归档。于是我先保留浅仓库作为工作副本,再用git fetch --unshallow补齐历史,这一步虽然慢,但不会中断,因为前期的三行配置保证了“慢但不死”。

第三步,我重新生成了一对 ed25519 key,把 remote 从 HTTPS 切换成 SSH:

git remote set-url origin git@github.com:user/blog.git git push -u origin main

之后日常的git push明显比 HTTPS 稳,除非遇到网络完全断开的阶段,几乎不再有推送失败的情况。整套流程下来,我没有使用任何第三方工具或非官方接口,纯粹利用 Git 自身的配置和协议特性,就把这个 2.3GB 仓库的日常维护成本降了下来。

5.3 几条可长期使用的 Git 配置沉淀

如果你也想一劳永逸,可以把下面这段配置写到~/.gitconfig里,作为个人 Git 环境的基础配置:

[user] name = yourname email = youremail [http] postBuffer = 524288000 lowSpeedLimit = 1 lowSpeedTime = 999999 version = HTTP/1.1 [pack] window = 0 [pull] rebase = true

我个人的使用经验是:postBuffer和lowSpeedTime组合适合所有使用 HTTPS 的场景;http.version HTTP/1.1只在出现莫名的 curl 56 时才有必要,如果你所在网络环境完全正常,不设也可以。pack.window=0会稍微增加传输包体积,如果你常推大仓库且内存足够,也可以不设置。

最后再分享一个小技巧:如果你要拉取的仓库很大,但只是想看看代码或跑一下编译,先用--depth 1浅克隆,运行没问题后再考虑要不要补全历史。很多“克隆慢”的痛点,其实是“不必要的数据量”放大了“网络波动”的影响。把这两件事分开处理,GitHub 克隆/推送速度慢的问题,大多数时候真的没那么难缠。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 6:02:04

sqli-labs Less-48实战:ORDER BY子句盲注与排序侧信道利用

sqli-labs这套靶场玩到Less-48这一关,很多人的感受是:终于要把“联合注入”和“报错注入”的惯性思维放下,开始直面ORDER BY子句的注入问题了。Less-48在关卡列表里的定位是“GET - Blind based on Order By Clause - Numeric - Sort Display…

作者头像 李华
网站建设 2026/10/9 6:00:52

从JDK到IDEA:Java与JavaScript开发环境搭建避坑指南

刚带完一个新人,他抱着笔记本跑过来说环境装了三天还没跑起来。我一看,问题非常典型:JDK装了两个版本,Maven依赖一直在下载失败,npm在PowerShell底下直接报“禁止运行脚本”,IntelliJ IDEA里项目一片飘红。…

作者头像 李华
网站建设 2026/10/9 5:59:28

C#仓库管理系统实战:MySQL数据库集成与入库出库完整实现

简介:这是一套面向C#初学者与数据库课程实践者的仓库管理系统完整项目源码,配套MySQL数据库文件,可用于课程设计、毕业设计或自学练手。系统覆盖物品入库、出库、查询、统计等日常作业,并实现按名称、类别、入库时间、库存量、供应…

作者头像 李华
网站建设 2026/10/9 5:59:14

玩转 Windows CMD:10 个高频命令让你的命令行效率翻倍

每次看到有人拿着鼠标在资源管理器里一层层点开目录,我都觉得他还没体验到玩命令行的快感。Windows 下的 CMD 命令提示符,从 Win95 一路走到 Win11,跟图形界面比像个“老古董”,但真正高频用过的人都知道:在批量操作、…

作者头像 李华
网站建设 2026/10/9 5:59:14

Python租房市场数据可视化平台:Django+爬虫+ECharts实战全解析

每年毕业季,“计算机毕业设计选什么题”都是个绕不开的坎。选纯算法怕数学底子撑不住,选管理信息系统又觉得没什么亮点。如果让我给一个稳妥又能出效果的建议,我会毫不犹豫推荐“Python租房市场数据可视化平台”——它把Django框架、Requests…

作者头像 李华
网站建设 2026/10/9 5:58:36

洛谷P1614题解:前缀和与滑动窗口求最小连续子段和

昨天有朋友私信问我洛谷 P1614“爱与愁的心痛”这道题,说样例能过,但交上去总是 WA,心态有点崩。我点开题目一看,这不就是一道很典型的“固定长度连续子段和”问题吗?对于刚学数组和循环的初学者来说,它是非…

作者头像 李华