Mac安装Homebrew报错128:homebrew-core克隆失败解决

Mac安装Homebrew报错128:homebrew-core克隆失败解决 mac 上第一次装 Homebrew脚本跑到一半终端里突然甩出来一行红字Error: Failure while executing; git clone https://github.com/Homebrew/homebrew-core /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core --depth1 exited with 128。这个场景我见过太多次了尤其是换了新机器、或者隔了一两年重装系统的朋友第一反应往往是我是不是把 Mac 搞坏了。其实没有这条报错的本质非常简单安装脚本在某一刻需要从远端把一个 Git 仓库拉到本地而这个拉取动作失败了。它既可能是网络在长连接上断掉了也可能是本地 Git 配置里有历史包袱还可能是/usr/local这个目录的归属关系不对。这篇文章我把这条报错从链路、根因、配置、实操到排查完整拆一遍包含可以直接抄的命令和参数解释。无论你是刚接触命令行的新手还是装过好几台机器的老手都能从里面找到对应自己那台机器的解法。1. 先搞清楚这条报错卡在了哪一步很多人拿到报错就去搜homebrew 安装失败然后照着几年前的文章一通乱敲结果把本来能用的环境搞得更乱。正确的顺序是先看懂安装脚本在干什么知道自己卡在第几环再决定动手方向。这一节把整条链路拆开讲。1.1 Homebrew 安装脚本的执行顺序Homebrew 的官方安装脚本并不是下载一个二进制丢到某个目录这么简单它是一段会分阶段执行的 shell 逻辑。我把它大致归成四步环境体检检查系统版本、CPU 架构Intel 还是 Apple Silicon、有没有装 Xcode Command Line Tools。如果没装脚本会尝试触发xcode-select --install这时候会弹出一个系统对话框很多人就是在这里点了取消或者没等它装完后面直接崩。确定安装前缀Intel 机型走/usr/localApple Silicon 机型走/opt/homebrew。这个前缀决定了后续所有路径包括报错里出现的那个/usr/local/Homebrew/Library/Taps/...。克隆主仓库把Homebrew/brew这个仓库拉到本地也就是安装前缀下的Homebrew目录。这一步体量不大一般能过。克隆或初始化 Tap这就是出问题的高发区。老版本脚本会去克隆Homebrew/homebrew-core这个仓库历史很长、体量很大浅克隆也要拉不少数据新版本4.0 之后默认改成走 API 模式不再把homebrew-core完整克隆到本地而是按需请求元数据。看到这里你应该能对上号了报错信息里出现homebrew-core说明你的脚本走到了第 4 步而且用的是从 Git 源拉取这种模式。这一步失败前面三步其实都已经成功了所以你的机器并没有被搞坏只是最后一环没接上。1.2 为什么偏偏是 homebrew-core 最容易失败同样是 git clone为什么克隆brew主仓库没事克隆homebrew-core就挂了原因有三个都很实际数据量大homebrew-core记录的是成千上万个软件包的 Formula 定义历史提交极其密集。哪怕加了--depth1拉下来的对象也比主仓库大一个量级。传输时间越长中途出现抖动、连接被重置的概率就越高。对连接持续性要求高Git 的智能传输协议在克隆过程中需要维持较长时间的会话。网络稍有波动服务端或客户端任意一侧断掉整个 clone 就前功尽弃然后返回退出码 128。失败没有断点续传git clone不像下载器那样支持断点续传。断了就是从零开始重试几次都在同一个位置失败给人的感觉是永远装不上。理解这三点之后解决思路就清楚了要么缩短传输距离和体积要么降低对单次长连接的依赖要么干脆绕开这一步不走 Git 源。提示新版 Homebrew 默认使用 API 模式正常情况下安装时是不需要克隆homebrew-core的。如果你的脚本还在做这件事说明要么脚本本身比较旧要么环境变量里显式关掉了 API 模式。这一点在下一节展开。1.3 退出码 128 说明了什么很多人只看到Failure while executing就慌了其实关键信息在后面那个数字。Git 的退出码 128 是一个通用致命错误码常见触发场景包括远端仓库不存在或路径写错、网络连接中断、TLS 证书校验失败、认证被拒绝、目标目录已存在且非空。这里要特别区分一件事Homebrew 的这些仓库都是公开仓库匿名克隆本来就不需要任何凭据。如果你在报错里看到认证相关的字样那基本不是仓库要求你登录而是你本地的 Git 配置或者凭据管理器往里塞了什么不该塞的东西。热词里常出现的需要带账号密码那类说法其实是对 GitHub 认证机制的误读——GitHub 早就不支持账号密码推送了私有仓库要的是 Personal Access Token而公开仓库根本不需要这一套。2. 三类根因与快速定位方法报错文案是同一条但底层原因差别很大。我习惯把它分成网络层、Git 配置层、目录权限层三类。分类的价值在于每一类的验证手段和修复动作完全不同分清楚了就不会瞎折腾。2.1 网络层长连接中途断掉这是占比最高的一类。表现特征是手动curl一下仓库首页能通浏览器也能打开对应的站点但git clone跑到某个百分比就卡死或者报错。原因是短请求能过不代表长连接能稳。验证方法很直接找一个体积相当的公开仓库试一下# 手动做一次浅克隆把仓库扔到临时目录不污染系统路径 git clone --depth1 https://github.com/Homebrew/homebrew-core /tmp/test-core-clone # 只看连通性和响应头不下载内容 curl -I -m 10 https://github.com # 看解析结果是否正常 nslookup github.com如果/tmp/test-core-clone这次成功了说明网络本身能走通问题更可能是偶发的中断或者安装脚本执行时的超时阈值太紧。如果这次也失败那就属于持续性问题建议直接跳到第 3 节用镜像源替换掉默认地址。另外提醒一点如果你所在的环境有企业级的出口策略、校园网的流量整形长连接被中途掐断是很常见的。这类问题不是靠改参数能彻底解决的换源是更务实的选择。2.2 Git 配置层历史遗留的网络参数这一类最容易被忽略也最容易让人抓狂。很多人在第一台机器上为了临时解决某个问题往全局配置里写过一些网络转发类的参数之后换了机器、换了网络环境这些参数被同步过来了比如通过 dotfiles 仓库结果所有 Git 操作都被导向一个已经不存在的地址。先看看全局配置里有什么# 列出所有全局配置项 git config --global --list # 顺手备份一份改坏了能还原 git config --global --list ~/gitconfig-backup.txt重点检查两类内容一类是http.或https.开头、值是一串地址的配置项另一类是url.xxx.insteadOf这种改写规则。后者的作用是把某个地址前缀自动替换成另一个如果以前为了换源写过而目标源现在不可用就会出现明明输入的是 A 地址实际访问的是 B 地址的诡异现象。清理方法# 逐条删除确认没用的配置例如 git config --global --unset-all http.postBuffer git config --global --unset-all url.https://example.invalid/.insteadOf删完再重新跑一次git config --global --list确认干净了。这一步做完再回到安装流程很多莫名其妙的失败就消失了。2.3 权限层与磁盘层被忽视的硬性条件还有两类失败跟网络一点关系都没有但因为报错文案一样经常被误判。权限问题/usr/local这个目录在 macOS 上的归属比较特殊。如果你之前用过sudo手动在里面创建过目录或者在老教程指导下执行过chown可能导致安装脚本没有写权限。验证方式# 看目录归属和权限 ls -ld /usr/local ls -ld /usr/local/Homebrew 2/dev/null # 看当前用户 whoami如果/usr/local/Homebrew存在但归属不是你自己安装脚本就会在创建或写入时失败。这里我要特别提醒不要照抄网上sudo chown -R $(whoami) /usr/local/*这类命令。它会把系统级目录的归属一并改掉短期内看起来问题解决了后续会出现权限混乱、系统更新异常等一堆后遗症。正确做法是删掉 Homebrew 相关的残留目录让安装脚本自己重建。磁盘空间问题homebrew-core完整克隆加上后续的缓存占用比很多人想象的大。先确认剩余空间# 人类可读的方式看磁盘剩余 df -h / # 看 Homebrew 目录当前占了多少 du -sh /usr/local/Homebrew 2/dev/null剩余空间低于 10GB 的时候我会建议先清理再装。空间不足导致的中断往往表现为跑到 80% 突然失败非常具有迷惑性。3. 换掉 clone 目标环境变量与镜像源配置前面说过最务实的解法是不要让安装脚本去访问默认的远端地址而是把它指向一个就近的镜像源。Homebrew 官方是支持通过环境变量指定 Git 远端和 Bottle 下载地址的这不是什么野路子是写在文档里的机制。这一节把相关变量一个一个讲清楚。3.1 关键环境变量逐个解释变量名作用说明HOMEBREW_BREW_GIT_REMOTE指定主仓库brew的 Git 远端安装阶段就会生效决定主仓库从哪拉HOMEBREW_CORE_GIT_REMOTE指定homebrew-core的 Git 远端就是报错里那个仓库换源后这一步会快很多HOMEBREW_API_DOMAIN指定 Formula 元数据 API 的地址新版默认走 API 模式这个变量决定元数据从哪取HOMEBREW_BOTTLE_DOMAIN指定预编译包Bottle的下载地址决定brew install时二进制包从哪下载HOMEBREW_NO_AUTO_UPDATE关闭自动更新装包时跳过更新检查能省下大量等待时间国内几个主流的高校镜像站都提供 Homebrew 的镜像常见的有中科大USTC和清华TUNA。它们给出的具体路径会随版本调整所以我的建议是执行前先去镜像站的页面上确认当前给出的地址不要照抄网上几年前的命令。下面的示例只是结构演示实际路径请以镜像站当期说明为准。# 安装阶段临时生效写进当前 shell 会话即可 export HOMEBREW_BREW_GIT_REMOTEhttps://镜像站/brew.git export HOMEBREW_CORE_GIT_REMOTEhttps://镜像站/homebrew-core.git export HOMEBREW_API_DOMAINhttps://镜像站/homebrew-bottles/api export HOMEBREW_BOTTLE_DOMAINhttps://镜像站/homebrew-bottles这里有个细节值得说这几个变量写在当前会话里只对当前终端窗口有效。安装完成后如果你希望以后brew install也走镜像需要把HOMEBREW_API_DOMAIN和HOMEBREW_BOTTLE_DOMAIN写进~/.zshrc或者~/.bash_profile。但HOMEBREW_BREW_GIT_REMOTE和HOMEBREW_CORE_GIT_REMOTE建议只在安装阶段用装完之后留着反而可能在brew update时造成分支不一致的问题。3.2 安装脚本本身拉不下来怎么办还有一个坑安装脚本本身也是从远端获取的。如果这一步就走不通那就先把脚本下载到本地检查一遍再执行。这样做的另一个好处是你可以先读一遍脚本内容确认它要动哪些目录。# 先下载脚本到本地不直接执行 curl -fsSL 安装脚本地址 -o ~/brew-install.sh # 养成习惯执行前看一眼前几十行 head -n 60 ~/brew-install.sh # 确认没问题再运行 /bin/bash ~/brew-install.sh脚本地址以官方仓库或镜像站当期说明为准。我个人的习惯是任何以直接管道进 bash形式给出的命令我都会先落到本地看一眼。这不是不信任谁而是这个习惯帮我避过好几次脚本参数变了但文章没更新的坑。3.3 Git 侧的调优参数换源解决的是距离问题还有几个 Git 参数能缓解长连接脆弱的问题。这些参数的作用是让 Git 在传输不顺畅时更宽容一些# 加大 HTTP 缓冲区减少大对象传输时的分片问题 git config --global http.postBuffer 524288000 # 把低速中断的门槛调低避免速度波动时被判定为卡死而主动断开 git config --global http.lowSpeedLimit 0 git config --global http.lowSpeedTime 999999 # 关闭压缩用带宽换 CPU某些链路上反而更快 git config --global core.compression 0关于http.postBuffer我要补充一句实话这个参数在社区里被过度神化了。它主要影响的是推送大对象时的分块行为对git clone的帮助有限。真正有效的往往是把lowSpeedLimit这类多久没速度就断开的判定关掉因为很多 clone 失败并不是真断线而是速度掉到阈值以下被 Git 主动放弃了。注意这几个参数是全局生效的会影响你机器上所有的 Git 仓库。如果你的日常开发对 Git 配置有特殊要求建议改完之后记录一下改了什么方便以后回滚。4. 完整实操从清理到验证理论讲完了这一节走一遍完整流程。我会按先体检、再清理、后安装、再验证的顺序来每一步都说明为什么这么做。4.1 动手前的三项体检不要一上来就跑安装脚本。先花两分钟做三项检查能避免 80% 的重复失败。# 检查一Command Line Tools 装好了没 xcode-select -p # 正常会输出类似 /Library/Developer/CommandLineTools # 如果报错或者输出为空先执行 xcode-select --install # 检查二Git 是否可用版本是否太老 git --version # 检查三磁盘剩余空间 df -h /xcode-select -p这一项我要多说两句。很多人的失败其实发生在更早的阶段——安装脚本触发了工具链安装弹窗用户点了取消脚本继续往下跑结果在需要编译或者需要 Git 的时候挂了。所以如果输出为空请把xcode-select --install弹出的安装流程走完看着它显示已完成再继续。4.2 清理上一次失败的残留这是整篇文章里我认为最重要的一步。失败过的机器上/usr/local/Homebrew目录往往已经被创建了一部分里面是空的或者残缺的仓库。安装脚本第二次运行时遇到已存在且非空的目录行为和第一次完全不同很容易出现目录冲突类错误。清理的方式有两种方式一用官方卸载脚本推荐/bin/bash -c $(curl -fsSL 官方卸载脚本地址)方式二手动清理脚本拉不下来时# 先看清要删什么别闭着眼睛 rm ls -la /usr/local/Homebrew 2/dev/null ls -la /opt/homebrew 2/dev/null # 删除 Homebrew 相关目录 sudo rm -rf /usr/local/Homebrew sudo rm -rf /usr/local/Caskroom sudo rm -rf /usr/local/Cellar sudo rm -rf /opt/homebrew # 删掉可能的软链接 sudo rm -f /usr/local/bin/brew清理完还要检查 shell 配置文件里有没有残留的 PATH 设置# 看看 zshrc 里有没有 Homebrew 相关的行 grep -n -i homebrew\|/opt/homebrew\|/usr/local/bin/brew ~/.zshrc如果有把这些行注释掉或者删掉。留着不会立刻报错但下次装完容易出现 PATH 里有两份路径、命令指向错误的问题。4.3 执行安装并观察输出环境变量配置好、残留清理干净之后就可以跑了。这里我强烈建议不要关终端窗口、不要中途按 CtrlC把输出完整看完。# 第一步设置镜像相关的环境变量路径以镜像站当期说明为准 export HOMEBREW_BREW_GIT_REMOTEhttps://镜像站/brew.git export HOMEBREW_CORE_GIT_REMOTEhttps://镜像站/homebrew-core.git export HOMEBREW_API_DOMAINhttps://镜像站/homebrew-bottles/api export HOMEBREW_BOTTLE_DOMAINhttps://镜像站/homebrew-bottles # 第二步执行安装脚本 /bin/bash -c $(curl -fsSL 安装脚本地址)安装过程中终端会输出几个关键阶段 Checking for sudo access、 This script will install:、 Downloading and installing Homebrew...。看到最后那行滚动的进度说明主仓库正在拉取这一步通常一两分钟能过。如果它在这里停了很久说明远端还是不通回到第 2 节用git clone --depth1手动测一下目标地址。安装完成后脚本会提示你执行两条命令把brew加进 PATH。Apple Silicon 和 Intel 的路径不一样脚本会直接告诉你照抄就行通常是这样的形式# Apple Silicon 常见形式 echo eval $(/opt/homebrew/bin/brew shellenv) ~/.zshrc eval $(/opt/homebrew/bin/brew shellenv) # Intel 常见形式 echo eval $(/usr/local/bin/brew shellenv) ~/.zshrc eval $(/usr/local/bin/brew shellenv)写完记得source ~/.zshrc或者干脆开一个新终端窗口。4.4 验证与收尾装完不代表结束验证环节能帮你提前发现问题。# 看版本 brew --version # 看环境配置重点确认各个 Domain 变量是否按预期生效 brew config # 体检Homebrew 自己会给出建议 brew doctorbrew config的输出信息量很大值得逐行看一遍。它会显示HOMEBREW_PREFIX、HOMEBREW_CELLAR、HOMEBREW_REPOSITORY以及你设置的那几个 Domain 是否被识别。如果发现HOMEBREW_BOTTLE_DOMAIN还是默认值说明环境变量没写进配置文件只存在于某个已经关掉的终端里。brew doctor的输出有时候会有一大堆 Warning不用慌。我通常只关注它给出的建议操作里排在前面几条后面的多是可选提醒。但如果你看到关于/usr/local权限的警告那就需要认真处理了说明前面清理得不够干净。最后跑一个真实安装测试一下整条链路# 装个小工具试试比如 jq 这种体积很小的 brew install jq # 确认能正常调用 jq --version如果这一步顺利说明从元数据获取到 Bottle 下载的链路都通了整套环境算是真正可用了。5. 常见问题速查与避坑经验到这一步大部分人的问题应该已经解决了。但实际操作中还有一些反复出现的细节我整理成表格和几条经验方便你对照排查。5.1 问题排查速查表现象可能原因处理方向卡在homebrew-core克隆最终 128长连接中断或体积过大换镜像源或用 API 模式跳过克隆curl能通但git clone失败Git 全局配置有历史改写规则检查git config --global --list报认证相关错误凭据管理器或 URL 改写引入干扰检查insteadOf类和凭据配置同一位置反复失败旧残留目录导致冲突清理/usr/local/Homebrew后重装跑到 80% 突然失败磁盘空间不足df -h /确认剩余空间brew命令找不到PATH 没写入配置文件检查 shell 配置并重新source装完brew install很慢Bottle Domain 没配置检查brew config中的域名项提示无写权限目录归属被改乱清理残留目录不要用chown -R硬改brew doctor一堆警告多为可选提示优先处理权限和路径类警告5.2 我自己踩过的几个坑第一个坑反复重试同一条命令。早期的我做的最蠢的事就是失败之后直接按上箭头重跑。git clone没有断点续传重跑一百次也是从头拉一遍成功率不会因为重试次数变高。真正改变结果的是换一个更近的源或者缩短要拉取的数据量。第二个坑用sudo装 Homebrew。网上有文章说加 sudo 就能解决权限问题这是绝对的错误方向。加了sudo仓库文件归属会变成 root之后所有brew install都要带sudo才能写入整个环境就废了。正确的做法是让安装脚本以普通用户身份运行脚本自己会用sudo处理它需要处理的那几个系统级目录。第三个坑把镜像变量永久写进配置文件。我在一台机器上把HOMEBREW_CORE_GIT_REMOTE写进了~/.zshrc用了大半年没出问题。后来镜像站调整了仓库地址brew update开始报错而且报错信息完全不提环境变量我排查了很久才想起来是自己写死的那行。从那以后我的原则是安装阶段的变量只用在安装阶段运行期的 Domain 变量才写进配置文件。第四个坑忽略brew doctor里的路径警告。有一次我装完之后没管警告用了两周之后发现某些工具的命令行版本和预期不一致。查下来是 PATH 里同时存在两个 Homebrew 路径旧的那份虽然已经被删了目录但 PATH 里还留着导致某些命令走了不可预期的位置。这类问题不会立刻暴露但会在某天以莫名其妙的诡异现象出现。最后分享一个诊断的小习惯遇到任何 Git 相关的失败先用最小化命令复现。不要直接跑完整安装脚本而是把失败的那条git clone单独拎出来换个目标目录、加--depth1、加-v看详细输出。安装脚本的输出很礼貌很多底层错误被它吞掉了而git clone -v会把实际的连接过程一步步打出来卡在哪一环一眼就能看到。我自己用这个习惯定位过好几次问题包括 TLS 握手失败、解析到错误地址、以及服务端返回 5xx 这类脚本层面完全看不出来的原因。后续如果还想再省事一点可以把镜像相关的 Domain 变量整理成一个小脚本新机器上装完系统直接跑一遍。我现在给朋友装机器就是这么干的一个setup-brew.sh里面包含环境变量、安装、PATH 写入、以及几个常用工具的一次性安装。写一次之后每台新机器省下十几分钟。这个思路同样适用于其他需要从远端拉取的工具链核心逻辑都是就近取源 减少传输量 失败可复现。