Homebrew `brew update` 卡住问题排查以及解决
2026/6/20 7:23:37 网站建设 项目流程

记一次 Homebrewbrew update卡住:镜像源、JSON API 与 Git Tags 的排障

环境背景:macOS Apple Silicon,Homebrew 安装在/opt/homebrew,Shell 为 zsh,网络环境需进行配置优化以访问GitHub等外部资源。

问题现象

执行:

brew update

终端只输出了如下信息:

HOMEBREW_BREW_GIT_REMOTE set: using https://mirrors.aliyun.com/homebrew/brew.git as the Homebrew/brew Git remote. Fetching objects: 7

之后更新非常慢,甚至看起来像卡死。

当时已经配置了阿里云 Homebrew 镜像:

exportHOMEBREW_BREW_GIT_REMOTE="https://mirrors.aliyun.com/homebrew/brew.git"exportHOMEBREW_CORE_GIT_REMOTE="https://mirrors.aliyun.com/homebrew/homebrew-core.git"exportHOMEBREW_API_DOMAIN="https://mirrors.aliyun.com/homebrew-bottles/api"exportHOMEBREW_BOTTLE_DOMAIN="https://mirrors.aliyun.com/homebrew/homebrew-bottles"

后来切到清华 TUNA 后,brew update --debug --verbose能成功走完 API 更新阶段:

Checking if we need to fetch formula.jws.json... Updated formula.jws.json. Checking if we need to fetch cask.jws.json... Updated cask.jws.json. Checking if we need to fetch formula_tap_migrations.jws.json... Updated formula_tap_migrations.jws.json. Checking if we need to fetch cask_tap_migrations.jws.json... Updated cask_tap_migrations.jws.json. Already up-to-date.

brew --version仍然停在:

Homebrew 5.1.0

再次执行普通brew update,又出现 Git fetch 错误:

HOMEBREW_BREW_GIT_REMOTE set: using https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git as the Homebrew/brew Git remote. error: RPC failed; curl 28 Operation too slow. Less than 1000 bytes/sec transferred the last 20 seconds fatal: protocol error: bad pack header Already up-to-date.

这个Already up-to-date很误导。它不代表 Homebrew 主程序已经更新,只代表后续update-report阶段没有更多可报告内容。

先说结论

这次问题不是单纯的“镜像没配好”,而是两个问题叠加:

  1. HOMEBREW_API_DOMAIN/HOMEBREW_BOTTLE_DOMAIN负责 Homebrew JSON API 和 bottle 下载。
  2. HOMEBREW_BREW_GIT_REMOTE负责 Homebrew 主程序仓库Homebrew/brew.git的 Git 更新。

API 镜像切到清华后已经正常;真正让brew版本停留在5.1.0的原因是:

Homebrew/brew.git 的 git fetch --force --tags origin 没成功

因此本地没有拿到5.1.1+6.0.x等新 tag。Homebrew 的 stable 更新逻辑依赖本地已有 tag:本地最新 tag 是5.1.0,它就只能继续停在5.1.0

最终有效方案是:

  • API 和 Bottle 继续走清华镜像;
  • Homebrew 主程序brew.git不再走清华/阿里 Git 镜像;
  • brew.git改回 GitHub;
  • 通过优化网络配置(如使用HTTP/1.1协议)手动刷新 tags;
  • 删除或注释HOMEBREW_BREW_GIT_REMOTEHOMEBREW_CORE_GIT_REMOTE,避免后续又被强制切回镜像 Git remote。

背景知识:Homebrew 4+ 的更新路径变了

Homebrew 4.0 之后,大多数普通用户不再需要完整克隆homebrew/corehomebrew/cask仓库。Homebrew 默认更多依赖 JSON API:

HOMEBREW_API_DOMAIN HOMEBREW_BOTTLE_DOMAIN

其中:

  • HOMEBREW_API_DOMAIN:用于下载 formula/cask 元数据,例如formula.jws.jsoncask.jws.json
  • HOMEBREW_BOTTLE_DOMAIN:用于下载预编译 bottle。
  • HOMEBREW_BREW_GIT_REMOTE:用于更新 Homebrew 自己,也就是Homebrew/brew.git
  • HOMEBREW_CORE_GIT_REMOTE:用于本地homebrew/coreGit tap;普通用户通常不再需要。

清华 TUNA 文档也明确说明,brew 4.0 之后大部分用户不需要再克隆homebrew/core,只需要设置 API 和 bottle 镜像即可。

排障过程

1. 确认环境变量是否生效

先看当前 Shell 是否真的拿到了 Homebrew 镜像变量:

printenv|grep'^HOMEBREW_'

当时输出显示变量已经生效:

HOMEBREW_BREW_GIT_REMOTE=https://mirrors.aliyun.com/homebrew/brew.git HOMEBREW_CORE_GIT_REMOTE=https://mirrors.aliyun.com/homebrew/homebrew-core.git HOMEBREW_API_DOMAIN=https://mirrors.aliyun.com/homebrew-bottles/api HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles

所以问题不是/etc/profile完全没生效。

2. 确认 Homebrew 自身启动速度正常

timebrew--version

输出很快:

Homebrew 5.1.0 brew --version 0.02s user 0.03s system 47% cpu 0.101 total

这排除了 Homebrew 自身启动很慢、Ruby 初始化卡住、基础安装损坏等问题。

3. 确认没有残留brew/git进程占用锁

psaux|grep-E'[b]rew|[g]it|[c]url|[r]uby'

没有发现残留的brew updategit fetchcurl进程。

因此不是另一个brew update进程仍在运行。

4. 单独测试镜像 Git 仓库是否能连通

gitls-remote https://mirrors.aliyun.com/homebrew/brew.git HEAD

可以返回:

01a27a96e15d3bbc02c81b18f95bb1d8f24d490c HEAD

这说明“能列远端 HEAD”不等于“能完整git fetch --tags”。后者需要传输 pack,对网络、镜像质量及HTTP协议要求更高。

5. 用 debug 日志定位brew update卡点

执行:

HOMEBREW_DEBUG=1brew update--verbose2>&1|tee/tmp/brew-update-debug.log

日志显示,API 文件从清华 TUNA 下载成功:

Checking if we need to fetch formula.jws.json... Updated formula.jws.json. Checking if we need to fetch cask.jws.json... Updated cask.jws.json. Checking if we need to fetch formula_tap_migrations.jws.json... Updated formula_tap_migrations.jws.json. Checking if we need to fetch cask_tap_migrations.jws.json... Updated cask_tap_migrations.jws.json.

但 Homebrew 仍然停在5.1.0

关键片段是:

++ git tag --list --sort=-version:refname + grep -m 1 '^[0-9]*\.[0-9]*\.[0-9]*$' + /Library/Developer/CommandLineTools/usr/bin/git tag --list --sort=-version:refname + UPSTREAM_TAG=5.1.0 REMOTE_REF=refs/tags/5.1.0 UPSTREAM_BRANCH=stable git checkout --force -B stable refs/tags/5.1.0 git rebase refs/tags/5.1.0 Current branch stable is up to date.

这说明 Homebrew 是根据本地 tag 决定 stable 版本的。因为本地最新 tag 只有5.1.0,所以它不会升级到更高版本。

6. 验证本地 tags 的确缺失

git-C"$(brew--repo)"tag--list'5.*'--sort=-version:refname|head-10

修复前看到的最高版本是5.1.0。这就解释了为什么brew --version一直不变。

7. 发现git fetch真正失败原因

执行普通brew update时出现:

error: RPC failed; curl 28 Operation too slow. Less than 1000 bytes/sec transferred the last 20 seconds fatal: protocol error: bad pack header

这说明git fetch的 HTTP 传输被低速保护中断,或者镜像/HTTP 协议链路中途断包,导致 Git pack 收到不完整数据,进而报bad pack header

最终修复过程

3. 取消强制使用 Homebrew Git 镜像

unsetHOMEBREW_BREW_GIT_REMOTEunsetHOMEBREW_CORE_GIT_REMOTE

把 Homebrew 主仓库 remote 改回 GitHub:

git-C"$(brew--repo)"remote set-url origin https://github.com/Homebrew/brew.git

4. 强制用 HTTP/1.1 刷新 main 和 tags

git-C"$(brew--repo)"\-chttp.version=HTTP/1.1\fetch--force--tagsorigin refs/heads/main:refs/remotes/origin/main

这次成功:

remote: Enumerating objects: 17951, done. remote: Counting objects: 100% (5036/5036), done. remote: Compressing objects: 100% (58/58), done. remote: Total 17951 (delta 5007), reused 4978 (delta 4978), pack-reused 12915 (from 6) Receiving objects: 100% (17951/17951), 6.64 MiB | 16.66 MiB/s, done. Resolving deltas: 100% (12675/12675), completed with 1135 local objects. From https://github.com/Homebrew/brew 0f7b6e1dd7..01a27a96e1 main -> origin/main * [new tag] 5.1.1 -> 5.1.1 * [new tag] 5.1.10 -> 5.1.10 * [new tag] 5.1.11 -> 5.1.11 * [new tag] 5.1.12 -> 5.1.12 * [new tag] 5.1.13 -> 5.1.13 * [new tag] 5.1.14 -> 5.1.14 * [new tag] 5.1.15 -> 5.1.15 * [new tag] 6.0.0 -> 6.0.0 * [new tag] 6.0.1 -> 6.0.1 * [new tag] 6.0.2 -> 6.0.2

5. 验证 tags 已经补齐

git-C"$(brew--repo)"tag--list'5.*'--sort=-version:refname|head-10

输出:

5.1.15 5.1.14 5.1.13 5.1.12 5.1.11 5.1.10 5.1.9 5.1.8 5.1.7 5.1.6

这时本地已经具备升级条件。

6. 注释镜像 Git remote 配置后,brew update正常

注释掉:

# export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git"# export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git"

然后在当前 Shell 中执行:

unsetHOMEBREW_BREW_GIT_REMOTEunsetHOMEBREW_CORE_GIT_REMOTE

确认变量为空:

printenv|grep'^HOMEBREW_.*GIT_REMOTE'

无输出即表示已清理。

再次执行:

brew update

输出:

==> Updating Homebrew... Already up-to-date.

这次不再出现:

HOMEBREW_BREW_GIT_REMOTE set: using ... error: RPC failed; curl 28 ... fatal: protocol error: bad pack header

最终推荐配置

长期不建议保留:

exportHOMEBREW_BREW_GIT_REMOTE="..."exportHOMEBREW_CORE_GIT_REMOTE="..."

原因:

  1. 它们会让每次brew update都强制修改 Git remote。
  2. 本次故障已经证明 Git 镜像链路容易在fetch --tags时失败。
  3. Homebrew 4+ 大多数普通用户不再需要本地homebrew/coreGit tap。

推荐只保留 API 和 bottle 镜像:

exportHOMEBREW_API_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api"exportHOMEBREW_BOTTLE_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles"

如果希望避免每次安装软件都触发自动更新,可以加:

exportHOMEBREW_NO_AUTO_UPDATE=1

推荐的日常命令

安装软件时不自动 update:

HOMEBREW_NO_AUTO_UPDATE=1brewinstall<formula>

手动更新 Homebrew 和 API 元数据:

brew update

如果 GitHub 链路偶发不稳定,可尝试调整网络配置并使用 HTTP/1.1:

GIT_HTTP_LOW_SPEED_LIMIT=0\GIT_HTTP_LOW_SPEED_TIME=999999\brew update--verbose

也可以只给 Homebrew 仓库固定 HTTP/1.1:

git-C"$(brew--repo)"config http.version HTTP/1.1

常用诊断命令

查看 Homebrew 版本

brew--version

查看 Homebrew 相关环境变量

printenv|grep'^HOMEBREW_'

查看是否仍设置了 Git remote 镜像变量

printenv|grep'^HOMEBREW_.*GIT_REMOTE'

查看 Homebrew 主仓库 remote

git-C"$(brew--repo)"remote-v

查看本地最新 stable tags

git-C"$(brew--repo)"tag--list--sort=-version:refname|grep-m10'^[0-9]*\.[0-9]*\.[0-9]*$'

手动刷新 Homebrew 主仓库 main 和 tags

git-C"$(brew--repo)"\-chttp.version=HTTP/1.1\fetch--force--tagsorigin refs/heads/main:refs/remotes/origin/main

查看 debug 日志

HOMEBREW_DEBUG=1brew update--verbose2>&1|tee/tmp/brew-update-debug.logtail-80/tmp/brew-update-debug.log

误区总结

误区 1:git ls-remote成功就代表git fetch没问题

不是。

git ls-remote只需要列远端引用,数据量很小。git fetch --tags要下载 pack,容易暴露镜像、HTTP/2、低速中断、运营商链路等问题。

误区 2:Already up-to-date一定代表 Homebrew 已升级

不是。

这次就出现了:

Already up-to-date.

但:

brew--version

仍然是:

Homebrew 5.1.0

真正要看的是本地 tags 和brew --version

误区 3:配置完整镜像变量一定更快

不一定。

对于 Homebrew 4+ 普通用户,最有价值的是:

HOMEBREW_API_DOMAIN HOMEBREW_BOTTLE_DOMAIN

而:

HOMEBREW_BREW_GIT_REMOTE HOMEBREW_CORE_GIT_REMOTE

可能让brew update在 Git fetch 阶段失败,尤其是 Git 镜像同步不完整、网络慢、网络环境不稳定时。

根因复盘

本次问题的根因链路是:

  1. 配置了HOMEBREW_BREW_GIT_REMOTEbrew update每次都会尝试使用镜像 Git remote 更新Homebrew/brew.git
  2. 阿里云 Homebrew API 镜像内容较旧,不适合作为当前 Homebrew 5.x 的稳定 API 来源。
  3. 切到清华后,API 下载恢复正常,但brew.gitfetch --tags仍在镜像 Git remote 上出现curl 28/bad pack header
  4. 因为fetch --tags失败,本地最高 stable tag 停留在5.1.0
  5. Homebrew 根据本地最高 tag 选择 stable 版本,因此brew --version一直是5.1.0
  6. 取消HOMEBREW_BREW_GIT_REMOTE,把brew.gitremote 改回 GitHub,并通过优化网络配置(如使用HTTP/1.1协议)成功 fetch tags 后,问题解决。

最终落地方案

最终配置应简化为:

# Homebrew JSON API 与 bottles 走国内镜像exportHOMEBREW_API_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api"exportHOMEBREW_BOTTLE_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles"# 可选:避免安装软件时自动触发 updateexportHOMEBREW_NO_AUTO_UPDATE=1

不要长期设置:

# 不建议长期设置# export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git"# export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git"

参考资料

  • Homebrew Manpage: https://docs.brew.sh/Manpage
  • Homebrew Common Issues: https://docs.brew.sh/Common-Issues
  • TUNA Homebrew 帮助: https://mirrors.tuna.tsinghua.edu.cn/help/homebrew/
  • TUNA Homebrew Bottles 帮助: https://mirrors.tuna.tsinghua.edu.cn/help/homebrew-bottles/
  • Git HTTP 配置文档:http.lowSpeedLimit/http.lowSpeedTime/http.version

总结

Homebrew 4+ 的日常加速重点是 API 和 bottle 镜像;不要盲目长期设置HOMEBREW_BREW_GIT_REMOTE。如果brew update卡在 Git fetch,先让Homebrew/brew.git回到 GitHub,通过优化网络配置(如使用HTTP/1.1协议)成功刷新 tags,再执行brew update


good day!!!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询