◆

Git 开启代理后拉取提交仍慢的解决办法

2023-03-03 13:250

代理软件开着、浏览器打开 github.com 很流畅,但 git clone 和 git push 还是慢得没法用,这是很常见的一种错觉:我们以为"开了代理全局就都走代理了",实际上代理软件在不开 TUN/系统代理模式时,只是在本地监听一个端口,谁来连它才代理谁。浏览器会读系统代理设置所以自动命中,git 不读,它默认直连。

结论就是得单独告诉 git 走哪个代理。下面记录设置、查看和取消的完整命令,以及一个必须知道的前提:这套配置只对 HTTPS 远程生效,SSH 远程一点都管不到。

场景

使用了代理,github 可以正常访问,但是 git 拉取提交代码依旧很慢。

原因

git pull or git push 命令并没有走代理

git 走 HTTPS 协议传输时底层用的是 libcurl,它只认 git 自己的 http.proxy 配置和 http_proxy / https_proxy 环境变量,不会去读 macOS 的系统代理面板。所以代理软件即使已经接管了系统流量的一部分,git 这条链路仍然是裸连出去的。

解决方法

设置 git 代理

  • 首先找到自己的代理服务器提供的代理信息,如下
https_proxy=http://127.0.0.1:7890
http_proxy=http://127.0.0.1:7890
all_proxy=socks5://127.0.0.1:7890

端口号要以自己代理软件里显示的为准。Clash 系客户端默认是 7890,并且这个端口通常是 HTTP 和 SOCKS 混合的,两种协议写法都能连上;V2Ray 系客户端常见的是 HTTP 1081 加 SOCKS 1080,两个端口分开,写错协议就连不上。地址一律是 127.0.0.1,代理跑在本机。

  • 设置 git 代理
git config --global http.proxy 'http://127.0.0.1:7890'
git config --global https.proxy 'http://127.0.0.1:7890'
# 或者
git config --global http.proxy 'socks5://127.0.0.1:7890'
git config --global https.proxy 'socks5://127.0.0.1:7890'

这里有个反直觉的点:https.proxy 的值写 http:// 是正确的,并不矛盾。它表达的是"用 HTTP 协议连接这个代理服务器",而不是"被代理的流量是 HTTP 流量"。git 会通过 CONNECT 方法让代理建立到目标的隧道,加密仍然是端到端的。

--global 会写进 ~/.gitconfig,对所有仓库生效。只想让某一个仓库走代理的话,在该仓库目录下去掉 --global,配置会落到 .git/config 里。

查看代理

git config --global http.proxy
git config --global https.proxy

没有任何输出说明这项配置不存在。想一次看清所有代理相关配置以及它们分别来自哪个文件,用下面这条更直观,--show-origin 会把配置文件路径打在前面,便于排查"明明取消了却还生效"这种情况:

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

删除代理

git config --global --unset http.proxy
git config --global --unset https.proxy

如果同一个 key 被写了多次(比如手动编辑过 ~/.gitconfig),--unset 会报 multiple values 并拒绝执行,这时用 --unset-all 全部清掉。另外全局配置删干净了但仓库里还慢,就去仓库目录下再执行一次不带 --global 的版本,仓库级配置的优先级高于全局。

只对 HTTPS 远程有效

这一整套配置的作用范围是 https:// 开头的远程地址。用 git remote -v 看一下,如果输出是 git@github.com:xxx/yyy.git 这种形式,那走的是 SSH 协议,http.proxy 配了也白配。

SSH 想走代理得在 ~/.ssh/config 里用 ProxyCommand,例如借助 nc 把连接转给本地代理:

Host github.com
  User git
  ProxyCommand nc -X 5 -x 127.0.0.1:7890 %h %p

-X 5 表示用 SOCKS5 协议,%h 和 %p 是 ssh 传进来的目标主机和端口。不想折腾代理的话,SSH 还有个更省事的办法是改走 GitHub 的 443 端口备用入口,配置更少也更稳定。

加速的另一半:仓库本身

代理配好了但 clone 大仓库依然要等很久,这时候瓶颈已经不是网络策略而是数据量了。只需要最新代码不需要完整历史的话,用浅克隆能省掉绝大部分传输:

git clone --depth 1 https://github.com/xxx/yyy.git

浅克隆的代价是拿不到完整提交历史,git log 只看得到一条,也不能基于旧提交做 rebase。后续需要完整历史时用 git fetch --unshallow 补回来。

💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEGit 开启代理后拉取提交仍慢的解决办法加载中