git clone/fetch 卡死超时速查:挂起现场的六个根因
更新时间:2026-10-24。FAQ 速查页,面向
git clone/git fetch卡在半分钟没动静、最后吐出Connection timed out或干脆永远挂着的同学。git clone 卡死的特点是:没有报错原文可锚,现场就是「光标不动」——但挂起不是一种病,它是六种病的共同症状。收敛在六根轴上:仓库太大传得慢被误判、SSH 的 22 端口被网络封死、该走代理没走或不该走却走了、smart HTTP 的缓冲与 postBuffer 顶到上限、DNS 解析拖死在第一步、以及 MTU 分片掉包导致的「能连上但传不动」。本篇的主旋律是「先分清挂在哪一层,再决定修哪一层」,每层给一条秒级验证命令。报错明确是认证拒绝的(publickey、Authentication failed)不在本篇范围,转 Permission denied (publickey) 速查 与 Git 认证失败速查。
本文要回答的问题
- clone 卡住不动,怎么判断是「真慢」还是「真死」?
- 为什么网页能打开 Git 平台,git clone 却 Connection timed out?
- 公司网络下 SSH 走不通,443 端口的 SSH 怎么配?
http.postBuffer到底调什么场景,什么时候调了也没用?- 代理在 shell 里配了,git 为什么没走?
一、挂起现场与典型报错
卡死/超时的几种真实形态如下(主机名以 git.example.com 占位,路径以 /proj/demo 占位):
$ git clone git@git.example.com:zhangsan/demo.git /proj/demo
Cloning into '/proj/demo'...
(光标停在这里,一分多钟后)
ssh: connect to host git.example.com port 22: Connection timed out
fatal: Could not read from remote repository.$ git clone https://git.example.com/zhangsan/demo.git /proj/demo
Cloning into '/proj/demo'...
(停在 remote: Enumerating objects 或 Receiving objects: 12% 长时间不动)
error: RPC failed; curl 56 GnuTLS recv error (-54): Error in the pull function.
fatal: the remote end hung up unexpectedly$ git fetch
fatal: unable to access 'https://git.example.com/zhangsan/demo.git/':
Failed to connect to git.example.com port 443 after 75000 ms: Connection timed out读现场抓三个信号:卡在 Cloning into 之后一行进度都没有的,是连接层问题(端口、DNS、代理),连服务端都没搭上话;能看到 Receiving objects 百分比但龟速或中途断的,是传输层问题(仓库大、缓冲、MTU);报错里带端口号(22/443)的直接指明了该查哪条链路。先定位层,再谈修复。
二、病因处置速查表
| 报错现象 / 场景 | 可能原因 | 快速验证 | 处置 |
|---|---|---|---|
| SSH 链 22 端口 timed out | 公司/酒店网络封 22 出站 | nc -vz git.example.com 22 挂起 | 改走平台 443 SSH 别名或换 HTTPS |
| HTTPS 也 timed out | 需要代理而 git 没配上 | curl -v https://git.example.com 同样挂 | 配 http.proxy 或走平台镜像 |
| 有进度但极慢、几分钟后断 | 仓库体积大、带宽低 | 平台页面看仓库体积 | --depth 1 浅克隆或 --filter=blob:none |
| Receiving objects 中途 RPC failed | postBuffer 太小或服务端时限 | 报错带 curl 56 / early EOF | 调大 http.postBuffer + 浅克隆 |
| 连域名都要转半分钟 | DNS 解析慢或失败 | time nslookup git.example.com | 换 DNS 或写 hosts 条目 |
| 小仓库能拉、大点的必挂 | MTU 分片掉包(VPN 高发) | ping 大包测试 | 调低 MTU 或避开问题 VPN 节点 |
| shell 有代理 git 不走 | git 不继承部分代理变量 | git config --get http.proxy | 显式 git config http.proxy |
| fetch 某个大提交必挂 | 单个大 blob 顶爆服务端时限 | 平台 pipelines 页面/管理员日志 | 浅 fetch 或请管理员放宽时限 |
三、排查决策图
下面这张图是标准排查路线,颜色按角色区分:红是报错入口与命中的根因,蓝是排查动作,绿是通过分支,橙是修复动作,紫是防复发沉淀。
读这张图抓唯一的分水岭:有没有进度百分比。无进度说明 TCP 都没建立,一切围绕端口、DNS、代理三件事;有进度但慢或断,才轮到仓库体积、缓冲与链路质量。不先分这一刀,最常见的空转就是「连接层死了却在调 postBuffer」——那是传输层的药。
四、逐条排查展开
第一条:先分清「真慢」还是「真死」。 大仓库(几 GB 级)在普通家用带宽下,进度条几分钟跳一格是正常现象,不是卡死。判别三招:GIT_TRACE=1 git clone ... 看底层是不是还在收发数据;系统层面看网络接口流量有没有持续走动;平台仓库页面看体积。确认真慢之后,正解不是干等,而是减小传输量:
git clone --depth 1 https://git.example.com/zhangsan/demo.git # 只要最新一层历史
git clone --filter=blob:none https://... # 按需取 blob 的部分克隆
git clone --single-branch --branch master https://... # 只拉一个分支浅克隆的历史可以日后 git fetch --unshallow 补全;部分克隆会在首次 checkout 老文件时按需下载。建仓与克隆参数的完整口径见 Git 配置、init 与 clone。
第二条:22 端口被封——公司网与公共 Wi-Fi 的经典剧情。 现象是 SSH 链稳定 port 22: Connection timed out,而浏览器开平台网页毫无问题——因为网页走 443,封网策略通常只拦非标端口。验证:
nc -vz git.example.com 22 # 挂起即被封
nc -vz git.example.com 443 # 通则有路处置两条路。其一,主流平台都提供 443 端口的 SSH 入口,在 ~/.ssh/config 里配置:
Host git.example.com
HostName ssh.git.example.com
Port 443其二,直接换 HTTPS 协议:git remote set-url origin https://git.example.com/zhangsan/demo.git。协议切换后的凭据配套见 remote、pull、push 用法 与 Git 认证失败速查。
第三条:代理——没配、配错、配串。 公司环境必须走代理才能出网时,git 不会自动继承所有 shell 变量(尤其 GUI 里启动的终端),要显式配:
git config --global http.proxy http://proxy.example.com:8080
git config --global --get http.proxy # 确认生效
git config --global --unset http.proxy # 离开公司网记得摘三个高发坑:只给 https 代理而仓库用 ssh 协议(SSH 链要走 ~/.ssh/config 的 ProxyCommand,不是 http.proxy);代理只代理 http 而 clone 的是 git:// 协议(这个老协议很多网络根本不放行,换 https);以及回家网忘摘代理导致「在家反而连不上」。验证链路时先用 curl -v https://git.example.com 确认代理本身能到平台,再怀疑 git 配置。
第四条:smart HTTP 缓冲与 postBuffer。 HTTPS 链在 Receiving objects 中途断,报 RPC failed; curl 56 ... 或 early EOF,常见触发是单个大 pack 超过客户端缓冲或服务端的响应时限。客户端侧的标准处置:
git config --global http.postBuffer 524288000 # 500MB,push 大包时用
git config --global http.version HTTP/1.1 # 个别服务端与 HTTP/2 组合不稳时退回 1.1但要说清边界:postBuffer 管的是 push 侧请求体和传输缓冲,clone/fetch 大包的根因更多在服务端时限与网络质量,调 buffer 不是万能药——断点续传 git 不支持,真正稳的解法是浅克隆起步、git fetch --depth 逐步加深,把单次传输切成小块。某个具体大提交必挂时,找管理员看服务端超时配置,别在客户端参数上无限加码。
第五条:DNS——最容易被忽略的第一公里。 Failed to connect ... after 75000 ms 里那 75 秒很多时候不是连接在等,是 DNS 解析在超时重试。验证:time nslookup git.example.com,解析超过几秒就是 DNS 链路有问题。处置:把系统/路由 DNS 换成公共解析服务,或在 hosts 文件里给 git.example.com 写一条静态条目(IP 以 ping/nslookup 解析结果为准,平台换 IP 后记得更新)。VPN 软件接管 DNS 时尤其高发——挂 VPN 前后 nslookup 结果不一致,基本就坐实了。
第六条:MTU 与分片掉包——VPN 用户的幽灵问题。 症状邪门:小仓库秒拉,稍大的必挂在固定百分比;网页正常、ping 正常,就是传不动。机理是 VPN 隧道吃掉了部分 MTU,大包分片后某一片被丢,TCP 重传再丢,死循环。验证:逐步加大 ping 包找临界尺寸。处置:把网卡 MTU 从 1500 降到 1400/1380 试,或换 VPN 协议与节点。这个问题在 git 层面没有任何参数可解,识别出来就别在 git config 上空转——这是本篇专门把它列为一条的原因。
第七条:挂起诊断的三板斧。 遇到任何挂起现场,按顺序打:GIT_TRACE=1 GIT_SSH_COMMAND="ssh -v" git fetch(看 SSH 握手卡在哪一行);GIT_CURL_VERBOSE=1 git fetch(HTTPS 链看 curl 卡在哪一步);nc -vz/nslookup/ping(网络层基线)。三板斧下来,问题在哪一层一目了然,比换着参数瞎试快一个量级。诊断信息也是去社区/管理员处求助时最值钱的东西。
五、规范做法与预防
- 大仓库默认浅克隆:CI 与本地一次性用途一律
--depth 1,要历史再补;团队文档里写明仓库体积与推荐克隆姿势。 - 443 SSH 别名提前配好:经常切换网络环境的机器,
~/.ssh/config里直接备好 443 入口,被封时零成本切换。 - 代理配置集中管理:写进 setup 脚本(配/摘一对命令),不靠记忆;换网络环境第一件事
git config --get http.proxy。 - VPN 出问题先疑 MTU:大传输必挂的场景,先调 MTU 再调 git 参数,顺序反了就是一下午。
- 超时参数留余量:CI 里给 clone/fetch 包一层超时与重试,网络抖动不让整条流水线陪葬。
这一篇在知识体系里的位置
本篇是 Git 排错速查簇的网络链路篇,定位「连不上、传不动」:连接能建立但服务端不认钥匙看 Permission denied (publickey) 速查;凭据被拒看 Git 认证失败速查;传输没问题但推送被历史原因拒绝看 Git push 被拒 non-fast-forward 速查;协议与 remote 地址的选择看 remote、pull、push 用法;浅克隆参数与建仓姿势看 Git 配置、init 与 clone;拉下来的历史怎么看怎么想,看 log、show、blame。
一句话总结
git clone 卡死先用「有无进度百分比」分两层:无进度是连接层——nc -vz 测 22/443 端口(22 被封就配平台 443 SSH 别名或换 HTTPS)、nslookup 测 DNS、git config --get http.proxy 查代理该配没配或忘摘;有进度但慢或中途断是传输层——大仓库改 --depth 1 浅克隆起步,RPC failed 调 http.postBuffer 并退回 HTTP/1.1,VPN 下大传输必挂先降 MTU。诊断三板斧 GIT_TRACE、ssh -v、GIT_CURL_VERBOSE 永远先于调参,大仓库默认浅克隆、代理配置脚本化,这类挂起基本绝迹。