花拾录
← 返回知识库

代码托管客户端配了代理却没启动代理软件,一次 push 卡住的排查

云计算 / 运维导入2026/09/220 阅读0 评论

你在终端敲下 git push,等推送完成。几秒后报错了,说连不上某个本地端口的代理。你有点纳闷——上次明明能推。

现象

推送代码时报错:

fatal: unable to access '...': Failed to connect to 127.0.0.1 port 7890:
Connection refused

看起来像网络问题,但目标站点其实是国内的,直连完全可行。而且同一台机器上浏览器打开该站点毫无问题。错误信息里的 Connection refused 是关键——不是超时,是连接被拒绝,说明那个端口后面没有任何东西在监听。

这里有个容易混淆的点:报错里出现的 127.0.0.1 很容易被当成"远程服务地址",实际上它是本机地址。也就是说,git 是在尝试连本机的一个端口,而不是在访问远端仓库——这一眼就能把方向从"网络问题"扭到"本地配置问题"。

根因

本机的 git 配置里(局部 .git/config 和全局 ~/.gitconfig 都)写了走本地代理——这是之前为了拉取国外仓库配的,一直留着。

而这次推送的目标是国内站点,直连毫无问题。问题在于代理软件当时根本没开。于是 git 忠实地按配置去连 127.0.0.1:7890,得到的自然是 Connection refused。

所以真正的原因不是"网络不通",而是"git 被配置强制走了一个不存在的代理"。浏览器的系统代理设置里可能配了自动绕过(或者代理软件没开时浏览器会自动回退直连),所以浏览器没事——但 git 只认自己的配置。

顺带解释一个常见困惑:为什么"上次明明能推"?因为上次代理软件开着,或者上次推的是需要代理的国外仓库。配置没变,变的是"运行时环境"——这正是配置残留类问题最难排查的地方:它不报"配置错",只在特定时刻才暴露。

解决

有几种思路,推荐最小侵入的那种。

不改动全局配置,只对本次命令生效:

git -c http.proxy= -c https.proxy= push

这里 -c http.proxy= 的作用是把代理显式置空——用空字符串覆盖掉配置文件里的值。全局配置纹丝不动,本次推送走直连,一步到位。它之所以有效,是因为命令行参数的优先级高于配置文件。

如果经常需要用,可以做成别名:

git config --global alias.dpush '!git -c http.proxy= -c https.proxy= push'
# 之后用
git dpush

不建议为了这一次去删全局配置——因为下次你拉国外仓库时可能还需要它。删掉之后过几天又要重新配,反而更折腾。

顺便记一下另一种情况的处理:如果代理软件开着但配置的端口不对(比如代理实际监听在 7891,配置写的是 7890),同样会 Connection refused。这时先确认端口:

ss -tln | grep -E '789[0-9]'

再按实际端口改配置,或者用上面的方式临时清空。要快速看清 git 当前到底用了什么代理配置,可以这样查:

git config --show-origin --get-regexp 'proxy'

--show-origin 会告诉你每一项来自哪个文件,避免"改了全局却没生效,其实是局部文件在覆盖"的困惑。

延伸与预防

核心习惯只有一句话:改配置用最小作用域。

全局配置影响所有仓库、所有时间;命令行参数只影响这一次。当你要临时改变某个行为时,优先用命令行覆盖而不是改文件。

另外值得记一次这个诊断信号:Connection refused 和 timeout 表示完全不同的两件事。

  • Connection refused:目标端口没人监听(服务没开、端口不对、防火墙 REJECT)。
  • timeout:包发出去了但没响应(网络不通、被丢弃、防火墙 DROP)。

看到 refused 先去查"那个服务在不在",看到 timeout 才去查"路径通不通"。这个区分能在排查时省下大量时间。

最后一条预防:给"需要代理"和"不需要代理"的操作分别准备命令或别名,把代理配置集中在明确的入口(比如只在拉取国外仓库时显式指定),而不是"全局配一次、之后不管"。配置越少、越集中,这类残留问题就越不容易冒出来。

评论(0)

  • 还没有评论,来抢沙发~

相关文章