我日常在 WSL中开发,享受着它带来的无缝体验。但最近,一个问题几乎让我放弃它:Git 慢到无法使用。本文记录了我从抓狂到解决问题的全过程,希望能帮你绕开我踩过的所有坑。

初步尝试与屡屡碰壁

一切始于我们将一个 C 语言项目从原生 Windows 迁移至 WSL 环境。

问题:网络隔离

项目迁移后,我无法从 WSL 中正常 git clonegit push 到远程仓库。

⚠️ 坑点:WSL 的独立网络栈: WSL 拥有自己的一套虚拟网络,它与宿主机 Windows 并不直接共享 localhost (127.0.0.1)。因此,你在 Windows 上运行的代理服务,对于 WSL 内部的程序来说,并不能通过 localhost 访问到。

迷宫般的代理配置

我当时第一反应是在 WSL 中为 Git 配置代理。

  1. 尝试一:直接指向 localhost,失败。 我尝试在 WSL 的 .gitconfig 中设置 http.proxy 指向 Windows 代理的端口(如 http://127.0.0.1:7890),但连接被拒绝。

  2. 尝试二:移植代理客户端到 WSL,失败。 我试图将代理工具(如 V2Ray)直接在 WSL 内部运行。但这带来了新的问题:复杂的配置、找不到合适的 Linux 版本,以及端口被占用的冲突。

在这条路,我彻底走进了死胡同。

曲线救国和新问题

在 WSL 原生 Git 走不通后,我决定换个思路。

调用 Windows Git

我利用了 WSL 的一个强大特性:可以调用Windows上的可执行文件。

我直接在 WSL 命令行中调用 Windows 环境中的 git.exe 来执行所有 Git 操作。

# 在 WSL 中调用 Windows 的 Git
/mnt/c/Program\ Files/Git/bin/git.exe clone [repository_url]

这立刻解决了网络问题。Windows 的 Git 自然地使用了 Windows 的网络配置,Git的clone和push都恢复了正常。

💡 为什么可以这样做? WSL 允许你在 Linux 环境中直接调用 Windows 的可执行文件 (.exe),反之亦然。这是一个非常强大的“胶水”特性,能让你组合利用两个系统的优势。


新瓶颈和问题

在 WSL 中直接调用 Windows Git (git.exe) 会带来两个新瓶颈。

💡 背景: 此前的方案(在 WSL 中调用 Windows Git)初步解决了“有没有”的问题,但很快就暴露了可用性和性能上的新瓶颈。

一是命令冗长复杂,降低了操作效率。二是跨文件系统的 I/O 损耗,导致性能下降。

⚠️ 坑点:命令的复杂与分裂

在 WSL 中,调用 git.exe 需要写很长的路径(如 /mnt/c/.../git.exe),即便使用别名 (alias) 也难以优雅地管理。若为了简化而只用它处理部分操作(如网络推送),则会破坏命令的统一性,在开发者脑中形成两个分裂的 Git,增加心智负担。

这本质上是 WSL 的架构限制所致。

🔍 细节:跨文件系统的性能开销 WSL 的架构决定了其跨文件系统的性能瓶颈。当 WSL 内的进程(如 bash)操作 Windows 文件(挂载于 /mnt/*)时,或 Windows 进程操作 WSL 文件(位于 \\wsl$\*)时,都会因额外的转换和通信层而产生显著的性能开销。调用 git.exe 正是后一种情况。

结论:必须回归使用 WSL 原生的 Git。

回归初心,根治 WSL 原生 Git

既然“曲线救国”的路也堵死了,我决定正面解决问题。

问题到底出在哪?

我曾怀疑是 WSL 的 NAT (网络地址转换) 导致了性能问题,搜索后探究到发现并非如此。

🔍 细节:NAT 并非瓶颈 WSL 的虚拟交换机 NAT 性能极高(可达 10Gbps 级别),而我通过代理访问公网的瓶颈在于代理节点带宽和国际出口(约 30Mbps)。真正的瓶颈与 NAT 无关。

那为什么 Clone 大仓库时总是会中断?后来我使用下面的方法解决的问题,发现问题可能不在网络层,而是在应用协议层,有以下可能。

  1. 协议不兼容:HTTP/2 协议在通过复杂的代理链路时,其多路复用特性可能因丢包或乱序导致连接重置。
  2. 超时太敏感:Git 默认的超时机制对网络抖动(Jitter)过于敏感,在跨国网络中容易误判连接失败而主动中断。
  3. 缓冲区太小:在高延迟网络下,过小的缓冲区导致了过多的网络 I/O 交互,增加了出错的概率。

最终配置

我制定了最终配置可能是针对解决了以上三个可能的协议层问题,

1.动态获取宿主机 IP

要让 WSL 里的 Git 找到 Windows 的代理,就必须知道 Windows 的真实 IP。

我编写了一个简单的脚本,每次启动 shell 时自动获取宿主机 IP,并设置好代理,写入脚本后使用source ~/.bashrc或者source ~/.zshrc使配置生效。

📝 获取宿主机 IP 的脚本 在你的 .bashrc.zshrc 中加入以下脚本。它会解析 resolv.conf 文件来找到 Windows 主机的 IP,并设置 ALL_PROXY 环境变量。

# 获取 Windows Host IP 并设置代理
export HOST_IP=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
export PROXY_PORT=10800 # 你的 Windows 代理端口
export ALL_PROXY="socks5://${HOST_IP}:${PROXY_PORT}"

# 你也可以选择直接修改 git config,但环境变量更灵活
# git config --global http.proxy "http://${HOST_IP}:${PROXY_PORT}"
# git config --global https.proxy "http://${HOST_IP}:${PROXY_PORT}"

💡 Windows 11 的镜像网络:Win11 高版本引入了 Mirrored Networking,它可以让 WSL 与 Windows 共享网络,直接使用 localhost 即可。如果你使用 Win11 ,强烈建议开启此功能,可以省去以上脚本。

2.优化 Git 传输参数

这是最关键的一步。我在 Git 全局配置中加入了三行配置。

git config --global http.version HTTP/1.1
git config --global http.postBuffer 157286400
git config --global core.lowSpeedLimit 0
git config --global core.lowSpeedTime 999999

🔍 原理:这三行配置到底做了什么?

  • http.version HTTP/1.1:强制 Git 降级使用更稳定、更兼容的 HTTP/1.1 协议,避开 HTTP/2 在复杂代理环境下的“水土不服”。
  • http.postBuffer 157286400:将 POST 请求的缓冲区增大到 150MB。对于 git push 等操作,这意味着 Git 会在内存里准备好一个大文件块再进行单次、大块的传输,显著减少高延迟网络下的交互次数。
  • core.lowSpeedLimit / core.lowSpeedTime:基本禁用了 Git 自身的超时检测机制,允许连接在网络临时抖动或速度极慢时“苟活”下来,把连接管理的任务完全交给底层的 TCP 协议。

3.使用 Linux 原生文件系统

这是确保 I/O 性能的铁律。

永远在 WSL 的主目录 (~) 或其他 Linux 文件系统路径下执行 Git 操作。

第四阶段:战果与反思

配置完成后,我进行了测试。

效果检验:Clone Linux 内核仓库

我选择 Clone Linux 内核这个巨型仓库 Linux Kernel

结果令人振奋:

  • 仓库大小:5.60 GiB
  • 耗时:约 26 分钟
  • 平均速度:约 3.43 MiB/s
  • 过程:全程稳定,无任何断连或报错。

这证明了问题已经得到圆满解决。

总结与最终配置

回顾整个过程,解决 WSL 中 Git 性能问题的关键在于找到核心问题,将问题定位到协议问题。

📝 最终推荐配置 以下是我沉淀下来的最终配置,融合了所有优化和一些额外建议。

1. Shell 启动脚本 (~/.bashrc~/.zshrc)

# For Win10 or Win11 without Mirrored Networking
export HOST_IP=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
export PROXY_PORT=7890 # 修改为你的代理端口
export ALL_PROXY="socks5://${HOST_IP}:${PROXY_PORT}"

2. Git 全局配置 (~/.gitconfig)

[http]
  postBuffer = 157286400
  version = HTTP/1.1

[core]
  lowSpeedLimit = 0
  lowSpeedTime = 999999
# [http]
#   maxRequests = 5 # 警告:此配置可提高并发,但是我没有试过,可能存在被服务器Ban掉的风险,请谨慎使用

⚠️ 注意:我移除了之前测试用的 core.fscache,因为它在 Linux 下无效,是 Windows 专用的 Git 缓存配置。

如果仅仅是为了解决 Git 问题无需升级系统,但从长远看,如果条件允许,我依然推荐升级到 Windows 11,并开启镜像网络。它能从根本上解决 WSL 与 Windows 的网络差异,一劳永逸地解决 IP 变动、VPN 穿透等诸多网络难题,还能原生支持 Linux GUI 应用,整体开发体验会再上一个台阶。


以上