触发条件

  • 本机装了多个代理客户端,想逐个试端口(如 Clash Verge 走 7890、Shark Cloud 走 23333)。
  • 用 HTTP_PROXY / HTTPS_PROXY 环境变量临时切端口来"测哪个通"。
  • 前提:~/.gitconfig 或仓库配置里已经写了 http.proxy / https.proxy。

症状

  • 命令的成败跟环境变量对不上。
  • 假阳性:给一个根本没在监听的端口,命令照样成功。
  • 假阴性:端口明明在监听且可用,却报连接失败。

实测(2026-09-24,connectedGraph profile 仓库):

$ netstat -ano | grep -i listening | grep -E ":(23333|7890)"
  TCP    0.0.0.0:7890   0.0.0.0:0   LISTENING   25092      <- 只有 7890
$ tasklist //FI "PID eq 25092" //NH
verge-mihomo.exe          25092 Services    0     67,304 K

23333 上没有任何进程。但下面这条却成功了:

HTTPS_PROXY=http://127.0.0.1:23333 git fetch origin    # 退出码 0

于是得出"23333 通了"的结论——完全错误。

排查步骤

  1. 先看 git 自己配了什么:

    git config --get-regexp 'proxy'

    实测输出:

    http.proxy http://127.0.0.1:7890
    https.proxy http://127.0.0.1:7890
  2. 用 curl 调试输出看它实际连了哪(决定性证据):

    HTTPS_PROXY=http://127.0.0.1:23333 GIT_CURL_VERBOSE=1 git fetch origin

    实测打印:

    == Info: Trying 127.0.0.1:7890...
    == Info: Establish HTTP proxy tunnel to github.com:443

    给的是 23333,连的是 7890——环境变量被完全无视。

  3. 拿真实监听者做对照:netstat -ano | grep LISTENING + tasklist 确认端口归属,别拿"命令成功"当端口通的证据。

根因

libcurl 自己的优先级是 --proxy 命令行 > 环境变量 > 配置文件,但 git 把 http.proxy 配置项读到后以更高的优先级传给 libcurl,所以 git 配置里的代理会盖掉 HTTP(S)_PROXY。环境变量只在配置项为空时才生效。

直觉上"环境变量是临时覆盖,应该优先级更高"——在 git 上不成立。

解决

三种,按"改动范围从小到大"排:

# 1. 一次性覆盖(推荐做端口测试用,不动任何配置文件)
git -c http.proxy=http://127.0.0.1:23333 -c https.proxy=http://127.0.0.1:23333 fetch

# 2. 一次性绕过代理(空串 = 不走代理)
git -c http.proxy= -c https.proxy= fetch

# 3. 永久改掉(换主力代理端口时才用)
git config --global http.proxy http://127.0.0.1:7890

其他工具未必遵循同一套优先级(很多 CLT 的 CLI 是"环境变量优先于配置文件"),别把这条结论外推。换工具就重跑一遍上面的第 2 步。

下次如何识别

  • 任何"我给命令设了代理环境变量,但行为没变"的情况,第一件事跑 git config --get-regexp proxy。
  • 通用手法:做对照实验。 把代理指到一个已知不存在的端口再跑一次。如果它"也通",那问题不在端口,在测试方法——结论作废。
  • 判断端口通不通只信 netstat -ano 的 LISTENING 行 + 进程名,不信任何"命令跑成功了"的间接证据。
  • 本机开着 Clash TUN 时端口测试会整体失真,对照实验同样适用。

遇到场景

2026-09-24,给 connectedGraph/connectedGraph 这个 profile 仓库做自建 GitHub Stats(见 GitHub Actions 定时任务),需要 git fetch 一个由机器人提交的新 commit。直连和 7890 相继失败(实为当晚整体网络抖动),第三次换成 23333 成功了,于是误判端口情况,并据此去查一个根本不存在的"Shark Cloud 自启"问题。真因是 git 配置里的 7890 一直在生效。

相关概念


本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Network