Skip to Main Content
github_proxy:一个开关接管 zsh、git 与 Homebrew 的 GitHub 加速Back to Top
# <p>github_proxy:一个开关接管 zsh、git 与 Homebrew 的 GitHub 加速</p>
18 minutes

github_proxy:一个开关接管 zsh、git 与 Homebrew 的 GitHub 加速

TL;DR:无代理、无 VPN 的国内网络下,github_proxy on 让 zsh 里的 git clone/fetch、curl/wget,以及 Homebrew 升级时对 GitHub 的直连 全部改走镜像;github_proxy off 一键恢复直连。核心依据是三个实测结论:brew 调用外部命令时会过滤非 HOMEBREW_ 前缀的环境变量;HOMEBREW_ARTIFACT_DOMAIN 在这版 brew 里只管 ghcr.io;真正能接管 brew 网络请求的是它的 shim(HOMEBREW_CURL / HOMEBREW_GIT)。实测同一个 GitHub 托管的 cask:直连 240 秒超时失败,走镜像 2 秒完成,且文件 SHA-256 与官方一致。


1. 前置条件与适用环境

项目本机实测值说明
系统macOS 27.2 / Apple SiliconIntel 机器同样适用
Shellzsh 5.9 + Oh My Zsh依赖交互式 zsh 加载 ~/.zshrc
Homebrew7.0.7(/opt/homebrew)接管 Homebrew 需要 4.x 以上
git / curlgit 2.56.0 / curl 8.7.1macOS 自带或 brew 安装均可
网络国内直连,无代理无 VPNhf-mirror、gh-proxy 可达
镜像https://gh-proxy.com/可用 GITHUB_PROXY_MIRROR 替换
已存在的本机镜像USTC:API / bottles / brew.git / homebrew-core.git与本方案互补,不冲突

前置认知:镜像只能解决“能不能下、下得快不快“,不能改变下载内容——所有经镜像下载的文件仍由原工具按 SHA-256 校验,校验不过就重来,不存在被镜像掉包的风险。

适用边界:本方案面向“在终端里干活“的场景。
浏览器、VS Code、npm/pip/go、以及程序内自建 HTTP 客户端的下载(例如 focr)不经过 zsh 也不经过 brew,
函数无法接管——那类工具要用它自己的镜像参数(如 --manifest、PIP_INDEX_URL)。


> **需求场景描述**
  1. Homebrew 下载 更新 (cask类型; Formula –build-form-source 类型; 第三方Tap 走github做仓库) brew update, brew upgrade, brew install –build-from-source
  2. Github url 安装 更新 拉取模型,例如 focr focr pull
  3. Github 代码仓库 git clone , git pull ,git push

2. 文件与路径一览

路径作用需要手动提供?
~/.zsh/functions/github_proxy.zsh主脚本(约 590 行),由 ~/.zshrc 自动 source✅ 唯一需要你放的文件
~/.local/state/github-proxy/state开关状态文件,唯一权威来源(内容为 on / off)❌ 首次 on/off 时自动生成
~/.local/state/github-proxy/bin/brew-curl自动生成的 curl 包装器(镜像地址写死在文件内)❌ 加载脚本时自动生成
~/.local/state/github-proxy/bin/brew-git自动生成的 git 包装器❌ 加载脚本时自动生成
~/.local/state/github-proxy/debug调试开关的标记文件(存在即记录)❌ 仅 debug on 时创建
~/.local/state/github-proxy/brew.log(含 .1)调试日志:包装器实际请求的地址,超 1 MB 自动轮转❌ 仅调试时写入

结论:你只需要提供 1 个文件——主脚本(附录 A)。
其余 5 个都是运行时产物,删掉后下次开 shell 会自动重建;反过来,把它们拷贝给别人也没有意义(包装器里写死了镜像地址与绝对路径)。

附录 B 列出了自动生成文件的具体内容,方便先审阅再落地。

加载链路:github_proxy.zsh 放在哪个目录由你决定,关键是在 ~/.zshrc 里写出这个路径并 source 它——这就是全部的“安装动作“:

# ~/.zshrc —— 指向你自己存放该脚本的位置(本项目示例放在 ~/.zsh/functions/)
source ~/.zsh/functions/github_proxy.zsh

若习惯把自定义函数集中管理,也可以整目录遍历加载(此时无需逐个写文件名):

if [ -d ~/.zsh/functions ]; then
    for func in ~/.zsh/functions/*.zsh; do
        source "$func"
    done
fi

状态目录则固定在 XDG_STATE_HOME(默认 ~/.local/state)下,属于“可重建的运行态“,删掉也能自动重建。


3. 功能

3.1 命令速查

github_proxy            # 看状态
github_proxy on         # 开启(默认状态)
github_proxy off        # 关闭,全部直连
github_proxy toggle     # 切换
github_proxy test       # 实测镜像 vs 直连速度
github_proxy url <URL>  # 只看改写结果,方便排查
github_proxy brew       # 看 Homebrew 接管状态
github_proxy debug on   # 记录包装器实际请求的地址(排查用)

3.2 接管范围矩阵

场景是否接管走向
git clone / fetch / pull / ls-remote / submodule✅走镜像
git push➖ 不动仍走你自己的 SSH(见 4.2)
curl / wget 中的 github 域名✅走镜像
Homebrew 升级时的 cask 包 / formula 源码 / tap 定义✅走镜像
Homebrew 的 API / bottles / 核心仓库➖ 不动你已有的 USTC 镜像
gh CLI❌自带客户端,只能用 HTTPS_PROXY
npm / pip / go / VS Code / 浏览器 / focr❌不经过 zsh,需各自配置
SSH 形式 git@github.com:…❌保持直连(国内一般可用)

3.3 三种状态语义

状态含义持久化
on走镜像(默认)写入 state 文件
off完全直连,且不残留任何环境变量写入 state 文件
GITHUB_PROXY_FORCE=off zsh只影响这次会话的临时覆盖不动 state 文件

4. 设计:三层接管

flowchart TD
    A["你在 zsh 里敲命令"] --> B["git / curl / wget 函数包装层<br/>改写参数里的 URL"]
    C["brew upgrade / fetch"] --> D["HOMEBREW_CURL_PATH<br/>HOMEBREW_GIT_PATH"]
    D --> E["生成的包装器<br/>brew-curl / brew-git"]
    B --> F["https://gh-proxy.com/https://github.com/…"]
    E --> F
    F --> G["镜像回源并返回<br/>原工具仍校验 SHA-256"]

4.1 第一层:zsh 函数改写参数

curl / wget 被函数包裹,只改写以 http(s):// 开头的参数,其余参数(-o、-H、--data 等)原样透传:

curl() {
  local -a args=()
  local a
  for a in "$@"; do
    case "$a" in
      http://*|https://*) args+=("$(_gp_url "$a")") ;;
      *)                  args+=("$a") ;;
    esac
  done
  command curl "${args[@]}"
}

改写是双向可逆的:_gp_unmirror 会先剥掉已有的镜像前缀再按当前开关决定,所以从浏览器复制来的 gh-proxy.com/https://github.com/… 在关闭状态下会自动还原成直连地址。

4.2 第二层:借 git 自己的 URL 重写规则

git 函数不直接改参数,而是注入 git 原生的重写配置——这样仓库里记录的 remote 地址仍然是原始 GitHub 地址,关掉开关就自动恢复直连,不会把镜像地址固化进 .git/config:

git() {
  ...
  local -a cfg=()
  for h in github.com raw.githubusercontent.com codeload.github.com \
           gist.github.com objects.githubusercontent.com; do
    cfg+=(-c "url.${m}https://${h}/.insteadOf=https://${h}/")
  done
  command git "${cfg[@]}" "$@"
}

git push 不做任何注入,保持原样——本机全局配置里本来就有 pushInsteadOf = https://github.com/(推送改走 SSH),所以写操作永远不受影响。

唯一需要补救的是 git clone:实测 git 会把实际使用的地址写进 .git/config。因此 clone 结束后脚本会把 remote 还原成原始地址,子模块一并处理:

if (( rc == 0 )); then
  case "$sub" in
    clone)     _gp_clone_target_dir "$@" && _gp_fix_remotes "$target" ;;
    submodule) _gp_fix_remotes "$PWD" ;;
  esac
fi

4.3 第三层:Homebrew 的 shim 才是接管点

brew 是 Ruby 程序,它发出的请求不经过 zsh。但它调用外部命令时会先经过自己的 shim,而 shim 会执行 $HOMEBREW_CURL / $HOMEBREW_GIT:

# /opt/homebrew/Library/Homebrew/shims/shared/curl(节选)
try_exec_non_system "${HOMEBREW_CURL:-curl}" "$@"
safe_exec "/usr/bin/curl" "$@"

而 brew.sh 的 setup_curl() / setup_git() 会优先采纳环境变量:

elif [[ -n "${HOMEBREW_CURL_PATH}" ]]
then
  HOMEBREW_CURL="${HOMEBREW_CURL_PATH}"

于是 github_proxy on 只要生成两个包装器脚本并导出两个变量,brew 的全部 curl/git 调用就都过我们的手了。验证方式极简——让 brew 自己告诉我们它用的是谁:

$ HOMEBREW_CURL_PATH=/path/to/wrapper brew config | grep '^Curl:'
Curl: 8.7.1 => /path/to/wrapper

4.4 三个反直觉的实测结论

① brew 会过滤非 HOMEBREW_ 前缀的环境变量。 用一个只记录参数的探针包装器挂在 HOMEBREW_CURL_PATH 上,同时导出 GITHUB_PROXY_MIRROR 和 GITHUB_PROXY_DEBUG,包装器收到的是空值:

MIRROR_ENV=[] DEBUG_ENV=[]

结论:镜像地址不能靠环境变量传给包装器,必须在生成包装器时写死进文件。

② HOMEBREW_ARTIFACT_DOMAIN 在这版 brew 里只管 ghcr.io。 翻源码可以看到它只对 GitHub Packages 域名生效:

# Library/Homebrew/download_strategy/curl_download_strategy.rb
u.sub(%r{^https?://#{GitHubPackages::URL_DOMAIN}/}o, "#{domain}/")
# github_packages.rb: URL_DOMAIN = "ghcr.io"

所以网上那套“设置 HOMEBREW_ARTIFACT_DOMAIN 就能给所有下载加速“的说法,在 7.x 上对 github.com 无效。

③ 导出的开关变量会泄漏,导致“关了却还是开着“。 早期版本把 GITHUB_PROXY 导出给子进程判断,结果它被子进程继承,新终端里读到的仍是 1,状态文件写着 off 却依然走镜像。修法是让状态文件成为唯一权威,GITHUB_PROXY 只做本 shell 内镜像变量且不导出;需要临时覆盖时用语义明确的 GITHUB_PROXY_FORCE。

④ 有些请求的命令行里根本没有 URL。 brew update 更新第三方 tap 时执行的是 git -C <tap目录> fetch --force origin——地址来自仓库 .git/config 里的 remote.origin.url。只改写命令行参数的包装器对这类请求完全无效,于是 20 个 tap 各自裸连 github.com,各卡满 75 秒连接超时。修法是让包装器额外注入 git 原生的重写规则:

cfg=()
for h in github.com raw.githubusercontent.com codeload.github.com gist.github.com; do
  cfg+=(-c "url.${MIRROR}https://${h}/.insteadOf=https://${h}/")
done
# …改写命令行参数后一并传入
exec "$REAL" "${cfg[@]}" "${args[@]}"

验证方式是用 GIT_TRACE=1 看真实连接,修复后变成 git-remote-https origin https://gh-proxy.com/https://github.com/<user>/homebrew-tap;同一台机器上 brew update 从「20 个 tap 全部 75 秒超时」变成 14 秒完成、0 失败。


5. 关键实现片段

生成的 curl 包装器(brew-curl,由主脚本按当前镜像生成):

#!/bin/bash
# 由 github_proxy.zsh 自动生成,请勿手改
MIRROR="https://gh-proxy.com/"
REAL="/usr/bin/curl"
args=()
for a in "$@"; do
  case "$a" in
    https://github.com/*|https://raw.githubusercontent.com/*|https://codeload.github.com/*|https://gist.github.com/*|https://objects.githubusercontent.com/*)
      args+=("${MIRROR}${a}") ;;
    *) args+=("$a") ;;
  esac
done
exec "$REAL" "${args[@]}"

几个刻意的设计选择:

调试日志的埋点也很克制——包装器每次只多一次文件存在性判断,github_proxy debug on 时才追加写入,日常零开销:

if [ -e "$MARKER" ]; then
  { printf '== %s\n' "$(date +%T)"; for a in "${args[@]}"; do printf '   %s\n' "$a"; done; } >> "$LOG" 2>/dev/null
fi

6. 测试与验证

6.1 探针:先看 brew 到底请求了什么

把只记录、不改写的探针挂在 HOMEBREW_CURL_PATH 上跑一次 brew fetch --build-from-source,抓到的真实地址正是 USTC 镜像覆盖不到的部分:

https://raw.githubusercontent.com/Homebrew/homebrew-core/3a68ac0…/Formula/d/dust.rb
https://codeload.github.com/bootandy/dust/tar.gz/refs/tags/v1.2.6
https://github.com/bootandy/dust/archive/refs/tags/v1.2.6.tar.gz

这解释了为什么配了 USTC 镜像,升级时依然会卡——元数据和 bottle 走了镜像,formula 定义、源码包、cask 的 app 包仍然是直连。

6.2 速度对比

场景直连走镜像
brew fetch --cask hiddenbar(约 2 MB,GitHub Releases)240 s 超时失败2.0 s
brew fetch --cask maccy(约 5 MB,GitHub Releases)未单独计时2.2 s
brew fetch --build-from-source jq(源码包在 GitHub)单次 >160 s 仍未完成—
10 MB 单文件三次采样158 / 11 / 45 KB/s24 / 51 / 44 KB/s

必须诚实地说:镜像不是恒定更快。上表最后一行显示两者都在抖动区间里,本机也测到过镜像 9.4 MB/s 的高峰与几十 KB/s 的低谷。镜像的主要价值是可达性兜底——直连会出现彻底超时(000)或长时间挂住,镜像通常能救回;具体该开还是该关,用 github_proxy test 当场判断。

6.3 内容完整性

经镜像下载的文件全部与原工具校验值一致:

文件校验结果
tokenizer.json(9.5 MB,GitHub Releases)SHA-256 与官方清单一致
Hidden-Bar-v1.11.1-macos.zip与 cask 的 sha256 一致
Maccy.app.zip与 cask 的 sha256 一致

6.4 on/off 双状态校验

用真正走 source ~/.zshrc 的全新交互式终端逐项验证:

检查项ONOFF
HOMEBREW_CURL_PATH指向 brew-curl未设置
brew config 的 Curl 行=> …/bin/brew-curl=> /usr/bin/curl
git ls-remote github.com正常(走镜像)直连,可能超时(网络本身抖动)
curl 取 raw.githubusercontent 文件200200
brew info(USTC API)正常正常
GitHub 托管的 cask 下载正常依赖直连状态
git push走 SSH,不受影响走 SSH,不受影响

另外专门构造了“脏环境“测试:故意 export GITHUB_PROXY=1 并注入 HOMEBREW_CURL_PATH,在状态文件为 off 时启动新终端——结果正确关闭(HOMEBREW_CURL_PATH 被清掉、brew 回到 /usr/bin/curl)。这正是 4.4 ③ 那个缺陷的回归验证。

6.5 踩坑记录

现象根因处置
改了 HOMEBREW_ARTIFACT_DOMAIN 对 github 无效该变量只管 ghcr.io改用 shim 接管
包装器拿不到镜像地址brew 过滤非 HOMEBREW_ 变量生成时写死进包装器
clone 出来的仓库 push 失败git 把镜像地址写进了 remoteclone 后自动还原 + 子模块同步
off 后新终端仍走镜像导出的状态变量被继承状态文件唯一权威、变量不导出
brew fetch --build-from-source 仍很慢该路径会先拉 formula 的 .rb 与源码包这两处现在也在白名单里

7. 局限与边界


8. 速查与维护

# 换镜像
export GITHUB_PROXY_MIRROR="https://你的镜像/"
github_proxy on                 # 重新生成包装器并生效

# 只关 Homebrew 接管,保留 git/curl 接管
export GITHUB_PROXY_BREW_ON=0

# 排查:看包装器实际请求了哪些地址
github_proxy debug on
brew fetch --cask maccy
tail -n 20 ~/.local/state/github-proxy/brew.log

# 体检
github_proxy status
github_proxy brew
github_proxy test

维护要点:状态目录整体可删(下次开 shell 自动重建);off 若发现残留,先 github_proxy off 再开新终端即可,因为状态文件是唯一权威。


9. 移植到别人的机器

9.1 前置检查

zsh --version                        # 需要 zsh(macOS 自带)
ls ~/.zshrc                          # 交互式 shell 的入口配置

第一步:决定脚本放哪。 任意目录都行,下文统一以 ~/.zsh/functions/ 举例。

第二步:在 ~/.zshrc 里写出这个路径。 这是唯一必须手工添加的一行,路径换成你实际存放的位置:

source ~/.zsh/functions/github_proxy.zsh

如果同时管理多个自定义函数,可以改成整目录遍历(新增脚本就不用再改 .zshrc):

if [ -d ~/.zsh/functions ]; then
    for func in ~/.zsh/functions/*.zsh; do
        source "$func"
    done
fi

改完后可以用这一行确认路径确实被引用了:

grep -n "github_proxy\|zsh/functions" ~/.zshrc

要求:必须是交互式 zsh(~/.zshrc 只被交互式 shell 加载)。bash、fish、脚本里的 #!/bin/sh 都不会生效。

9.2 放置脚本

方式一(推荐):下载到你选定的目录(下面以 ~/.zsh/functions/ 为例,必须与 9.1 里写进 .zshrc 的路径一致)

mkdir -p ~/.zsh/functions
curl -fLo ~/.zsh/functions/github_proxy.zsh \
  https://suchaharcan.github.io/03Share_blog/github-proxy-zsh-brew/github_proxy.zsh

方式二:把文末 附录 A 的源码整段复制进你那个路径下的 github_proxy.zsh。

只需要这一个文件。第一次被 source 时,脚本会自己在状态目录里创建运行时文件,各文件的生成时机如下:

运行时会生成生成时机内容
bin/brew-curl、bin/brew-git每次加载脚本 / github_proxy on镜像地址写死在内的包装器(附录 B)
state第一次执行 on 或 offon / off,默认开启时不写文件
debuggithub_proxy debug on空标记文件
brew.log(+ .1)调试开启且 brew 真正调用包装器时实际请求的地址,超 1 MB 自动轮转

所以不要把 bin/brew-curl 之类拷给别人用——里面的镜像地址和 REAL 路径是按本机写死的,交给别人反而失效;让他们从主脚本自动生成即可。

9.3 生效与验收

exec zsh                  # 或直接开一个新终端
github_proxy status       # 期望:开启(走镜像)
github_proxy brew         # 有 Homebrew 时期望:curl 已接管 / git 已接管

逐项自测清单:

自测命令期望结果
github_proxy url https://github.com/a/b输出带镜像前缀的地址
git ls-remote https://github.com/octocat/Hello-World.git HEAD能拿到 commit hash
github_proxy test打印镜像/直连两组速度
brew config | grep '^Curl:'ON 时指向 …/github-proxy/bin/brew-curl,OFF 时是 /usr/bin/curl
brew fetch --cask maccy日志(github_proxy debug on)里出现镜像地址
git push(任意自己的仓库)仍走 SSH,与装之前一致

9.4 按需调整

变量默认作用
GITHUB_PROXY_MIRRORhttps://gh-proxy.com/换镜像(末尾斜杠必须保留)
GITHUB_PROXY_BREW_ON1设为 0 只关 Homebrew 接管,保留 git/curl 接管
GITHUB_PROXY_FORCE未设置on / off 临时覆盖一次会话,不改状态文件
GITHUB_PROXY_HOSTS源码内 7 个域名要增删改写的域名,改这一处即可

路径与平台差异:

9.5 卸载

github_proxy off                        # 先关闭,撤掉导出的 HOMEBREW_* 变量
rm  ~/.zsh/functions/github_proxy.zsh   # 删脚本(换成你实际的存放路径)
rm -rf ~/.local/state/github-proxy      # 删状态与自动生成的包装器(可随时重建)
exec zsh

最后把 ~/.zshrc 里那行 source …/github_proxy.zsh 一并删掉(用整目录遍历的则跳过这步)。


附录 A:完整源码

与本文同步的版本共 591 行,文件名 github_proxy.zsh。 直接下载:github_proxy.zsh

#!/usr/bin/env zsh
# ============================================================================
#  github_proxy.zsh —— GitHub 国内加速开关(zsh 交互式环境)
#
#  作用:把在 zsh 里发出的 github 相关请求自动改写到国内加速镜像;
#        关闭后立刻恢复直连。默认「开启」。
#
#  用法(github_proxy help 可随时查看):
#    github_proxy            # 看状态
#    github_proxy on         # 开启(默认状态)
#    github_proxy off        # 关闭,全部直连
#    github_proxy toggle     # 切换
#    github_proxy test       # 实测镜像 vs 直连速度
#    github_proxy url <URL>  # 只看改写结果,方便排查
#    github_proxy brew       # 看 Homebrew 接管状态
#    github_proxy debug on   # 记录包装器实际请求的地址(排查用)
#
#  覆盖范围(只在交互式 zsh 里生效,且不能用 `command xxx` / 绝对路径调用):
#    ✅ git clone / fetch / pull / ls-remote / submodule / archive
#    ✅ git push —— 完全不受影响:你自己的 pushInsteadOf 规则会把 https 推送
#       改写成 SSH,镜像只做只读加速,绝不会碰到写操作
#    ✅ curl / wget 参数里出现的 github.com、raw.githubusercontent.com、
#       codeload.github.com、gist.github.com、objects.githubusercontent.com
#    ✅ Homebrew —— 用 HOMEBREW_CURL_PATH / HOMEBREW_GIT_PATH 指向本脚本生成的
#       包装器来接管。USTC 镜像只管 API / bottles / 两个核心仓库;brew 升级时对
#       github.com、codeload.github.com、raw.githubusercontent.com 的直连
#       (cask 的 app 包、formula 的源码包、tap 的 formula 定义)由这里加速
#    ❌ 程序自身发起的其它请求:npm / pip / go、VS Code、浏览器、focr 等
#       这些不经过 zsh 也不经过 brew,函数无法接管(focr 用 --manifest 方案解决)
#    ❌ gh CLI:走 api.github.com 且自带客户端,只能用 HTTPS_PROXY
#    ❌ SSH 形式(git@github.com:…):保持直连,国内一般可用;
#       若不通,可在 ~/.ssh/config 里改用 ssh.github.com:443
#
#  依赖:git / curl(macOS 自带或 Homebrew 安装均可)
#  自定义镜像:export GITHUB_PROXY_MIRROR="https://你的镜像/"
#  只想关掉 Homebrew 接管(保留 git/curl 接管):export GITHUB_PROXY_BREW_ON=0
# ============================================================================

# ---------------------------------------------------------------------------
# 配置区(可用环境变量覆盖)
# ---------------------------------------------------------------------------
: ${GITHUB_PROXY_MIRROR:=https://gh-proxy.com/}   # 末尾斜杠必须有
typeset -g GITHUB_PROXY_MIRROR

# 命中这些域名就改写
typeset -ga GITHUB_PROXY_HOSTS=(
  github.com
  www.github.com
  raw.githubusercontent.com
  codeload.github.com
  gist.github.com
  objects.githubusercontent.com
  api.github.com
)

# 开关状态持久化位置(默认开启,只有显式 off 才写文件)
typeset -g GITHUB_PROXY_STATE="${XDG_STATE_HOME:-$HOME/.local/state}/github-proxy/state"

# ---- Homebrew 接管(curl / git 包装器由本脚本生成,固定在状态目录里)----
typeset -g GITHUB_PROXY_STATE_DIR="${GITHUB_PROXY_STATE:h}"
typeset -g GITHUB_PROXY_BIN="${GITHUB_PROXY_STATE_DIR}/bin"
typeset -g GITHUB_PROXY_BREW_CURL="${GITHUB_PROXY_BIN}/brew-curl"
typeset -g GITHUB_PROXY_BREW_GIT="${GITHUB_PROXY_BIN}/brew-git"
typeset -g GITHUB_PROXY_DEBUG_MARKER="${GITHUB_PROXY_STATE_DIR}/debug"
typeset -g GITHUB_PROXY_BREW_LOG="${GITHUB_PROXY_STATE_DIR}/brew.log"
# brew 位置:优先用环境变量,缺失时按常见安装路径自动探测
# (Apple Silicon: /opt/homebrew;Intel Mac: /usr/local;Linuxbrew: ~/.linuxbrew)
typeset -g GITHUB_PROXY_PREFIX="${HOMEBREW_PREFIX:-}"
if [[ -z "$GITHUB_PROXY_PREFIX" ]]; then
  typeset _gp_p
  for _gp_p in /opt/homebrew /usr/local /home/linuxbrew/.linuxbrew "$HOME/.linuxbrew"; do
    if [[ -x "$_gp_p/bin/brew" ]]; then GITHUB_PROXY_PREFIX="$_gp_p"; break; fi
  done
  : ${GITHUB_PROXY_PREFIX:=/opt/homebrew}
  unset _gp_p
fi
typeset -g GITHUB_PROXY_BREW_ON="${GITHUB_PROXY_BREW_ON:-1}"   # 0 = 不接管 Homebrew

# 被我们改写之前的值,off 时原样还回去
typeset -g  GITHUB_PROXY_PREV_CURL_PATH GITHUB_PROXY_PREV_GIT_PATH
typeset -gi GITHUB_PROXY_PREV_CURL_SET=0 GITHUB_PROXY_PREV_GIT_SET=0

# ---------------------------------------------------------------------------
# 内部:状态读写
# ---------------------------------------------------------------------------
_gp_state_read() {
  local v=""
  [[ -r "$GITHUB_PROXY_STATE" ]] && v="$(<"$GITHUB_PROXY_STATE" 2>/dev/null)"
  case "$v" in
    off|0|false|no) print -r -- off ;;
    on|1|true|yes)  print -r -- on  ;;
    *)              print -r -- on  ;;   # 默认开启
  esac
}

_gp_enabled() {
  # 状态文件是唯一权威。GITHUB_PROXY 只作为本 shell 内的镜像变量、且不导出,
  # 否则它会被子进程/其它程序继承,出现「文件写着 off 但新终端仍是 on」的假象。
  # 需要临时覆盖时用 GITHUB_PROXY_FORCE=on|off(显式、不会被误继承)。
  case "${GITHUB_PROXY_FORCE-}" in
    on|1|true|yes)  return 0 ;;
    off|0|false|no) return 1 ;;
  esac
  [[ "$(_gp_state_read)" == on ]]
}

_gp_set() {
  local want="$1" dir="${GITHUB_PROXY_STATE:h}"
  [[ -d "$dir" ]] || mkdir -p "$dir" 2>/dev/null
  [[ -w "$dir" ]] && print -r -- "$want" >| "$GITHUB_PROXY_STATE" 2>/dev/null
  export -n GITHUB_PROXY 2>/dev/null      # 不导出:避免泄漏给子进程
  if [[ "$want" == on ]]; then
    GITHUB_PROXY=1
    _gp_brew_enable
  else
    GITHUB_PROXY=0
    _gp_brew_disable
  fi
}

# ---------------------------------------------------------------------------
# Homebrew 接管
#   brew 调 curl/git 时会把非 HOMEBREW_ 前缀的环境变量过滤掉(实测
#   GITHUB_PROXY_MIRROR 传不进包装器),所以镜像地址必须写死在包装器脚本里,
#   每次开启时重新生成一次。
# ---------------------------------------------------------------------------
_gp_brew_available() {
  [[ "$GITHUB_PROXY_BREW_ON" == 0 ]] && return 1
  [[ -x "${GITHUB_PROXY_PREFIX}/bin/brew" ]] || return 1
  return 0
}

_gp_write_brew_wrappers() {
  local dir="$GITHUB_PROXY_BIN" tpl
  [[ -d "$dir" ]] || mkdir -p "$dir" 2>/dev/null
  [[ -d "$dir" ]] || return 1

  # 还原成 brew 原本会用的真实程序
  local real_curl="${GITHUB_PROXY_PREFIX}/opt/curl/bin/curl"
  if [[ -z "${HOMEBREW_FORCE_BREWED_CURL-}" || ! -x "$real_curl" ]]; then
    real_curl="/usr/bin/curl"
  fi
  local real_git="${GITHUB_PROXY_PREFIX}/bin/git"
  [[ -x "$real_git" ]] || real_git="/usr/bin/git"

  # ---- curl 包装器:把 github 域名改写到镜像,其余原样放行 ----
  tpl=$(cat <<'CURL_TPL'
#!/bin/bash
# 由 github_proxy.zsh 自动生成,请勿手改
MIRROR="__MIRROR__"
REAL="__REAL__"
MARKER="__MARKER__"
LOG="__LOG__"
args=()
for a in "$@"; do
  case "$a" in
    https://github.com/*|https://raw.githubusercontent.com/*|https://codeload.github.com/*|https://gist.github.com/*|https://objects.githubusercontent.com/*)
      args+=("${MIRROR}${a}") ;;
    *) args+=("$a") ;;
  esac
done
if [ -e "$MARKER" ]; then
  if [ -f "$LOG" ] && [ "$(wc -c < "$LOG" 2>/dev/null || echo 0)" -gt 1048576 ]; then mv -f "$LOG" "$LOG.1" 2>/dev/null; fi
  { printf '== %s\n' "$(date +%T)"; for a in "${args[@]}"; do printf '   %s\n' "$a"; done; } >> "$LOG" 2>/dev/null
fi
exec "$REAL" "${args[@]}"
CURL_TPL
)
  tpl="${tpl//__MIRROR__/$GITHUB_PROXY_MIRROR}"
  tpl="${tpl//__REAL__/$real_curl}"
  tpl="${tpl//__MARKER__/$GITHUB_PROXY_DEBUG_MARKER}"
  tpl="${tpl//__LOG__/$GITHUB_PROXY_BREW_LOG}"
  print -r -- "$tpl" >| "$GITHUB_PROXY_BREW_CURL" 2>/dev/null

  # ---- git 包装器:只读操作走镜像,push 原样放行 ----
  #  关键点:brew update 更新第三方 tap 时执行的是
  #      git -C <tap> fetch --force origin
  #  命令行里没有 URL,地址来自仓库 .git/config 里的 remote.origin.url。
  #  因此除了改写命令行参数,还必须注入 git 原生的 insteadOf 重写规则,
  #  否则这类请求会绕过镜像直接裸连 github.com。
  tpl=$(cat <<'GIT_TPL'
#!/bin/bash
# 由 github_proxy.zsh 自动生成,请勿手改
MIRROR="__MIRROR__"
REAL="__REAL__"
MARKER="__MARKER__"
LOG="__LOG__"
sub=""
for a in "$@"; do
  case "$a" in -*) continue ;; *) sub="$a"; break ;; esac
done
if [ "$sub" = "push" ]; then
  if [ -e "$MARKER" ]; then
    if [ -f "$LOG" ] && [ "$(wc -c < "$LOG" 2>/dev/null || echo 0)" -gt 1048576 ]; then mv -f "$LOG" "$LOG.1" 2>/dev/null; fi
    { printf '== %s (push, 原样放行)\n' "$(date +%T)"; for a in "$@"; do printf '   %s\n' "$a"; done; } >> "$LOG" 2>/dev/null
  fi
  exec "$REAL" "$@"
fi
# git 原生重写规则:覆盖 remote.origin.url 这类"写在配置里"的地址
cfg=()
for h in github.com raw.githubusercontent.com codeload.github.com gist.github.com; do
  cfg+=(-c "url.${MIRROR}https://${h}/.insteadOf=https://${h}/")
done
args=()
for a in "$@"; do
  case "$a" in
    https://github.com/*|https://raw.githubusercontent.com/*|https://codeload.github.com/*|git@github.com:*)
      args+=("${MIRROR}${a}") ;;
    *) args+=("$a") ;;
  esac
done
if [ -e "$MARKER" ]; then
  if [ -f "$LOG" ] && [ "$(wc -c < "$LOG" 2>/dev/null || echo 0)" -gt 1048576 ]; then mv -f "$LOG" "$LOG.1" 2>/dev/null; fi
  { printf '== %s\n' "$(date +%T)"; for a in "${args[@]}"; do printf '   %s\n' "$a"; done; } >> "$LOG" 2>/dev/null
fi
exec "$REAL" "${cfg[@]}" "${args[@]}"
GIT_TPL
)
  tpl="${tpl//__MIRROR__/$GITHUB_PROXY_MIRROR}"
  tpl="${tpl//__REAL__/$real_git}"
  tpl="${tpl//__MARKER__/$GITHUB_PROXY_DEBUG_MARKER}"
  tpl="${tpl//__LOG__/$GITHUB_PROXY_BREW_LOG}"
  print -r -- "$tpl" >| "$GITHUB_PROXY_BREW_GIT" 2>/dev/null

  chmod 755 "$GITHUB_PROXY_BREW_CURL" "$GITHUB_PROXY_BREW_GIT" 2>/dev/null
  [[ -x "$GITHUB_PROXY_BREW_CURL" && -x "$GITHUB_PROXY_BREW_GIT" ]]
}

_gp_brew_enable() {
  _gp_brew_available || return 0
  _gp_write_brew_wrappers || return 1

  if (( ! GITHUB_PROXY_PREV_CURL_SET )) &&
     [[ -n "${HOMEBREW_CURL_PATH-}" && "${HOMEBREW_CURL_PATH}" != "$GITHUB_PROXY_BREW_CURL" ]]; then
    GITHUB_PROXY_PREV_CURL_PATH="${HOMEBREW_CURL_PATH}"
    GITHUB_PROXY_PREV_CURL_SET=1
  fi
  export HOMEBREW_CURL_PATH="$GITHUB_PROXY_BREW_CURL"

  if (( ! GITHUB_PROXY_PREV_GIT_SET )) &&
     [[ -n "${HOMEBREW_GIT_PATH-}" && "${HOMEBREW_GIT_PATH}" != "$GITHUB_PROXY_BREW_GIT" ]]; then
    GITHUB_PROXY_PREV_GIT_PATH="${HOMEBREW_GIT_PATH}"
    GITHUB_PROXY_PREV_GIT_SET=1
  fi
  export HOMEBREW_GIT_PATH="$GITHUB_PROXY_BREW_GIT"
}

_gp_brew_disable() {
  if [[ "${HOMEBREW_CURL_PATH-}" == "$GITHUB_PROXY_BREW_CURL" ]]; then
    if (( GITHUB_PROXY_PREV_CURL_SET )) &&
       [[ "${GITHUB_PROXY_PREV_CURL_PATH-}" != "$GITHUB_PROXY_BREW_CURL" ]]; then
      export HOMEBREW_CURL_PATH="${GITHUB_PROXY_PREV_CURL_PATH}"
    else
      unset HOMEBREW_CURL_PATH
    fi
  fi
  if [[ "${HOMEBREW_GIT_PATH-}" == "$GITHUB_PROXY_BREW_GIT" ]]; then
    if (( GITHUB_PROXY_PREV_GIT_SET )) &&
       [[ "${GITHUB_PROXY_PREV_GIT_PATH-}" != "$GITHUB_PROXY_BREW_GIT" ]]; then
      export HOMEBREW_GIT_PATH="${GITHUB_PROXY_PREV_GIT_PATH}"
    else
      unset HOMEBREW_GIT_PATH
    fi
  fi
}

_gp_brew_active() {
  [[ "${HOMEBREW_CURL_PATH-}" == "$GITHUB_PROXY_BREW_CURL" ||
     "${HOMEBREW_GIT_PATH-}" == "$GITHUB_PROXY_BREW_GIT" ]]
}

# ---------------------------------------------------------------------------
# 内部:URL 改写
# ---------------------------------------------------------------------------
_gp_is_github_url() {
  local u="$1" rest host
  [[ "$u" == http://* || "$u" == https://* ]] || return 1
  rest="${u#*://}"
  host="${rest%%/*}"
  host="${host%%:*}"
  host="${host##*@}"
  (( ${GITHUB_PROXY_HOSTS[(I)$host]} ))
}

# 加镜像前缀
_gp_mirror() {
  local u="$1"
  if _gp_is_github_url "$u"; then
    print -r -- "${GITHUB_PROXY_MIRROR}${u}"
  else
    print -r -- "$u"
  fi
}

# 去掉已存在的镜像前缀(复制粘贴带前缀的地址也能正确还原)
_gp_unmirror() {
  local u="$1"
  if [[ "$u" == ${GITHUB_PROXY_MIRROR}* ]]; then
    print -r -- "${u#${GITHUB_PROXY_MIRROR}}"
  else
    print -r -- "$u"
  fi
}

# 归一化 + 按当前开关改写:这是所有包装器共用的出口
_gp_url() {
  local u="$1"
  u="$(_gp_unmirror "$u")"
  if _gp_enabled; then
    _gp_mirror "$u"
  else
    print -r -- "$u"
  fi
}

# ---------------------------------------------------------------------------
# 包装器 1:curl
# ---------------------------------------------------------------------------
curl() {
  local -a args=()
  local a
  for a in "$@"; do
    case "$a" in
      http://*|https://*) args+=("$(_gp_url "$a")") ;;
      *)                  args+=("$a") ;;
    esac
  done
  command curl "${args[@]}"
}

# ---------------------------------------------------------------------------
# 包装器 2:wget
# ---------------------------------------------------------------------------
wget() {
  local -a args=()
  local a
  for a in "$@"; do
    case "$a" in
      http://*|https://*) args+=("$(_gp_url "$a")") ;;
      *)                  args+=("$a") ;;
    esac
  done
  command wget "${args[@]}"
}

# ---------------------------------------------------------------------------
# 内部:把一个仓库(含子模块)里指向镜像的 remote 地址还原成原始地址
#   git clone 会把"实际使用的地址"写进 .git/config,若不还原,之后 push
#   这条 remote 会指向镜像(镜像不支持写操作)。
# ---------------------------------------------------------------------------
_gp_fix_remotes_one() {
  local dir="$1" name url clean
  [[ -d "$dir" ]] || return 0
  for name in ${(f)"$(command git -C "$dir" remote 2>/dev/null)"}; do
    url="$(command git -C "$dir" remote get-url "$name" 2>/dev/null)" || continue
    clean="$(_gp_unmirror "$url")"
    [[ "$clean" == "$url" ]] || command git -C "$dir" remote set-url "$name" "$clean" 2>/dev/null
  done
}

_gp_fix_remotes() {
  local dir="$1" mod
  [[ -d "$dir/.git" ]] || return 0
  _gp_fix_remotes_one "$dir"
  for mod in "$dir"/.git/modules/*(N/); do
    _gp_fix_remotes_one "$mod"
  done
}

# 从 clone 的参数里找出目标目录
_gp_clone_target_dir() {
  local -a args=("$@")
  local i url="" dir=""
  for (( i = 2; i <= $#args; i++ )); do
    local a="${args[i]}"
    if [[ -z "$url" ]]; then
      [[ "$a" == *://* || "$a" == *@*:* ]] && url="$a"
      continue
    fi
    [[ "$a" == -* ]] && continue
    dir="$a"; break
  done
  [[ -n "$url" ]] || return 1
  [[ -n "$dir" ]] || dir="${${url%%\?*}#*/}"      # 去掉 query,取路径最后一段
  dir="${dir%.git}"
  [[ -n "$dir" ]] || return 1
  print -r -- "$dir"
}

# ---------------------------------------------------------------------------
# 包装器 3:git
#   通过注入 git 自身的 URL 重写规则实现:
#     · 读操作(clone/fetch/pull/...)自动走镜像
#     · 写操作(push)不注入任何规则,保持你原有的 SSH 推送习惯
#     · clone 结束后把 remote 还原成原始 github 地址,仓库保持"干净"
# ---------------------------------------------------------------------------
git() {
  if ! _gp_enabled; then
    command git "$@"
    return
  fi

  # 找出子命令(跳过选项)
  local sub="" a
  for a in "$@"; do
    [[ "$a" == -* ]] && continue
    sub="$a"; break
  done

  local m="$GITHUB_PROXY_MIRROR" h
  local -a cfg=()
  for h in github.com raw.githubusercontent.com codeload.github.com \
           gist.github.com objects.githubusercontent.com; do
    cfg+=(-c "url.${m}https://${h}/.insteadOf=https://${h}/")
  done

  command git "${cfg[@]}" "$@"
  local rc=$?

  # clone / submodule 之后收拾 remote 地址
  if (( rc == 0 )); then
    case "$sub" in
      clone)
        local target
        target="$(_gp_clone_target_dir "$@")" && _gp_fix_remotes "$target"
        ;;
      submodule)
        _gp_fix_remotes "$PWD"
        ;;
    esac
  fi
  return $rc
}

# ---------------------------------------------------------------------------
# 对外命令
# ---------------------------------------------------------------------------

# 帮助文本(github_proxy help / -h / --help / usage / 参数写错时显示)
_gp_help() {
  local state="关闭(直连)"
  _gp_enabled && state="开启(走镜像)"

  print -r -- "github_proxy —— GitHub 国内加速开关(当前:${state})"
  print -r -- ""
  print -r -- "  github_proxy            # 看状态"
  print -r -- "  github_proxy on         # 开启(默认状态)"
  print -r -- "  github_proxy off        # 关闭,全部直连"
  print -r -- "  github_proxy toggle     # 切换"
  print -r -- "  github_proxy test       # 实测镜像 vs 直连速度"
  print -r -- "  github_proxy url <URL>  # 只看改写结果,方便排查"
  print -r -- "  github_proxy brew       # 看 Homebrew 接管状态"
  print -r -- "  github_proxy debug on   # 记录包装器实际请求的地址(排查用)"
  print -r -- ""
  print -r -- "接管范围:"
  print -r -- "  git clone / fetch / pull / ls-remote / submodule / archive  → 走镜像"
  print -r -- "  git push                                                   → 不受影响,仍走你的 SSH"
  print -r -- "  curl / wget 中的 github 域名                               → 走镜像"
  print -r -- "  Homebrew 升级时的 github 直连(cask 的 app 包、formula 源码、"
  print -r -- "  tap 的 formula 定义 —— USTC 镜像管不到的部分)              → 走镜像"
  print -r -- ""
  print -r -- "接管不到:"
  print -r -- "  npm / pip / go、VS Code、浏览器、focr 等程序自身发起的请求"
  print -r -- "  gh CLI(走 api.github.com,只能用 HTTPS_PROXY)"
  print -r -- "  SSH 形式地址 git@github.com:…"
  print -r -- ""
  local brew_state="未接管"
  _gp_brew_active && brew_state="已接管(brew 的 curl/git → 包装器)"
  print -r -- "Homebrew:${brew_state}"
  print -r -- "镜像:    ${GITHUB_PROXY_MIRROR}   (用 GITHUB_PROXY_MIRROR 环境变量可替换)"
  print -r -- "状态文件:${GITHUB_PROXY_STATE}"
  print -r -- "临时覆盖:GITHUB_PROXY_FORCE=off zsh   (只影响这一次会话,不动状态文件)"
}

github_proxy() {
  local cmd="${1:-status}"
  case "$cmd" in
    on|enable|1)
      _gp_set on
      print -r -- "GitHub 代理:已开启  →  ${GITHUB_PROXY_MIRROR}"
      ;;

    off|disable|0)
      _gp_set off
      print -r -- "GitHub 代理:已关闭  →  直连 github.com(国内通常很慢或超时)"
      ;;

    toggle|switch)
      if _gp_enabled; then github_proxy off; else github_proxy on; fi
      ;;

    status|"")
      local state="关闭(直连)"
      _gp_enabled && state="开启(走镜像)"
      local brew_state="未接管"
      _gp_brew_active && brew_state="已接管"
      print -r -- "GitHub 代理:${state}"
      print -r -- "镜像地址: ${GITHUB_PROXY_MIRROR}"
      print -r -- "Homebrew: ${brew_state}(github_proxy brew 看详情)"
      print -r -- "接管的域名:${(j:, :)GITHUB_PROXY_HOSTS}"
      print -r -- "状态文件: ${GITHUB_PROXY_STATE}"
      ;;

    brew|homebrew)
      local c="未接管" g="未接管" gen="缺失"
      [[ "${HOMEBREW_CURL_PATH-}" == "$GITHUB_PROXY_BREW_CURL" ]] && c="已接管"
      [[ "${HOMEBREW_GIT_PATH-}" == "$GITHUB_PROXY_BREW_GIT" ]] && g="已接管"
      [[ -x "$GITHUB_PROXY_BREW_CURL" && -x "$GITHUB_PROXY_BREW_GIT" ]] && gen="已生成"

      print -r -- "Homebrew 接管:curl ${c} / git ${g}"
      print -r -- "  包装器:        ${gen}(${GITHUB_PROXY_BIN})"
      print -r -- "  HOMEBREW_CURL_PATH=${HOMEBREW_CURL_PATH:-(未设置)}"
      print -r -- "  HOMEBREW_GIT_PATH =${HOMEBREW_GIT_PATH:-(未设置)}"
      if (( $+commands[brew] )); then
        print -r -- "  brew 实测:"
        command brew config 2>/dev/null | command grep -E "^(Curl|Git):" | command sed 's/^/    /'
      fi
      print -r -- "  说明:USTC 镜像管 API / bottles / 两个核心仓库;"
      print -r -- "        cask 的 app 包、formula 源码包、tap 定义仍会直连 github.com,"
      print -r -- "        开启后由本包装器改写(下载完仍由 brew 校验 sha256)。"
      ;;

    debug)
      case "${2:-}" in
        on|1)
          [[ -d "$GITHUB_PROXY_STATE_DIR" ]] || mkdir -p "$GITHUB_PROXY_STATE_DIR" 2>/dev/null
          : >| "$GITHUB_PROXY_DEBUG_MARKER" 2>/dev/null
          print -r -- "调试日志:已开启  →  ${GITHUB_PROXY_BREW_LOG}"
          print -r -- "  (只记录 brew 经包装器发出的请求;用 github_proxy debug off 关闭)"
          ;;
        off|0)
          command rm -f "$GITHUB_PROXY_DEBUG_MARKER" 2>/dev/null
          print -r -- "调试日志:已关闭(日志文件保留在 ${GITHUB_PROXY_BREW_LOG})"
          ;;
        *)
          if [[ -e "$GITHUB_PROXY_DEBUG_MARKER" ]]; then
            print -r -- "调试日志:开启(${GITHUB_PROXY_BREW_LOG})"
          else
            print -r -- "调试日志:关闭"
          fi
          ;;
      esac
      ;;

    url)
      if [[ -z "$2" ]]; then
        print -ru2 -- "用法:github_proxy url <URL>"
        return 2
      fi
      print -r -- "$(_gp_url "$2")"
      ;;

    test|check|bench)
      local probe_gh="https://github.com/Dicklesworthstone/franken_ocr/releases/download/models-v1/tokenizer.json"
      print -r -- "探测文件:tokenizer.json (9.5 MB)"
      print -r -- "-- 镜像 --"
      command curl -sL --max-time 25 -o /dev/null \
        -w "   ${GITHUB_PROXY_MIRROR}\n   速度 %{speed_download} B/s  HTTP %{http_code}\n" \
        "${GITHUB_PROXY_MIRROR}${probe_gh}"
      print -r -- "-- 直连 --"
      command curl -sL --max-time 15 -o /dev/null \
        -w "   https://github.com\n   速度 %{speed_download} B/s  HTTP %{http_code}\n" \
        "$probe_gh"
      ;;

    help|-h|--help|usage|-help)
      _gp_help
      ;;

    *)
      print -ru2 -- "github_proxy: 未知参数 '$cmd'"
      print -ru2 -- ""
      _gp_help
      return 2
      ;;
  esac
}

# 让本 shell 内的脚本能判断开关状态:GITHUB_PROXY 故意「不导出」,
# 免得它被子进程继承(曾导致状态文件为 off 时新终端仍判为开启)。
export -n GITHUB_PROXY 2>/dev/null
unset GITHUB_PROXY

# 同步状态 + Homebrew 接管(静默执行,加载时不打印任何东西)
if _gp_enabled; then
  GITHUB_PROXY=1
  _gp_brew_enable 2>/dev/null
else
  GITHUB_PROXY=0
  _gp_brew_disable 2>/dev/null
fi

附录 B:自动生成的文件长什么样

主脚本会在 ~/.local/state/github-proxy/ 下生成运行时文件。它们不需要你提供,但值得先看清楚——这毕竟是一个会往你磁盘写可执行文件的操作。下面以本机为例(家目录用 ~ 简写)。

B.1 bin/brew-curl(19 行)

#!/bin/bash
# 由 github_proxy.zsh 自动生成,请勿手改
MIRROR="https://gh-proxy.com/"
REAL="/usr/bin/curl"
MARKER="~/.local/state/github-proxy/debug"
LOG="~/.local/state/github-proxy/brew.log"
args=()
for a in "$@"; do
  case "$a" in
    https://github.com/*|https://raw.githubusercontent.com/*|https://codeload.github.com/*|https://gist.github.com/*|https://objects.githubusercontent.com/*)
      args+=("${MIRROR}${a}") ;;
    *) args+=("$a") ;;
  esac
done
if [ -e "$MARKER" ]; then
  if [ -f "$LOG" ] && [ "$(wc -c < "$LOG" 2>/dev/null || echo 0)" -gt 1048576 ]; then mv -f "$LOG" "$LOG.1" 2>/dev/null; fi
  { printf '== %s\n' "$(date +%T)"; for a in "${args[@]}"; do printf '   %s\n' "$a"; done; } >> "$LOG" 2>/dev/null
fi
exec "$REAL" "${args[@]}"

要点:

B.2 bin/brew-git(35 行)

#!/bin/bash
# 由 github_proxy.zsh 自动生成,请勿手改
MIRROR="https://gh-proxy.com/"
REAL="/opt/homebrew/bin/git"
MARKER="~/.local/state/github-proxy/debug"
LOG="~/.local/state/github-proxy/brew.log"
sub=""
for a in "$@"; do
  case "$a" in -*) continue ;; *) sub="$a"; break ;; esac
done
if [ "$sub" = "push" ]; then
  if [ -e "$MARKER" ]; then
    if [ -f "$LOG" ] && [ "$(wc -c < "$LOG" 2>/dev/null || echo 0)" -gt 1048576 ]; then mv -f "$LOG" "$LOG.1" 2>/dev/null; fi
    { printf '== %s (push, 原样放行)\n' "$(date +%T)"; for a in "$@"; do printf '   %s\n' "$a"; done; } >> "$LOG" 2>/dev/null
  fi
  exec "$REAL" "$@"
fi
# git 原生重写规则:覆盖 remote.origin.url 这类"写在配置里"的地址
cfg=()
for h in github.com raw.githubusercontent.com codeload.github.com gist.github.com; do
  cfg+=(-c "url.${MIRROR}https://${h}/.insteadOf=https://${h}/")
done
args=()
for a in "$@"; do
  case "$a" in
    https://github.com/*|https://raw.githubusercontent.com/*|https://codeload.github.com/*|git@github.com:*)
      args+=("${MIRROR}${a}") ;;
    *) args+=("$a") ;;
  esac
done
if [ -e "$MARKER" ]; then
  if [ -f "$LOG" ] && [ "$(wc -c < "$LOG" 2>/dev/null || echo 0)" -gt 1048576 ]; then mv -f "$LOG" "$LOG.1" 2>/dev/null; fi
  { printf '== %s\n' "$(date +%T)"; for a in "${args[@]}"; do printf '   %s\n' "$a"; done; } >> "$LOG" 2>/dev/null
fi
exec "$REAL" "${cfg[@]}" "${args[@]}"

与 curl 版的两点差异:push 直接 exec 原样放行,写操作绝不经过镜像;地址白名单里除 https 之外还认 git@github.com: 这种 SSH 形式。

B.3 另外三个文件

== 10:23:15
   --disable
   --fail
   --location
   https://gh-proxy.com/https://github.com/p0deje/Maccy/releases/download/2.7.1/Maccy.app.zip

github_proxy debug off 只删除标记文件,日志保留供事后查看;想彻底清空直接删掉 brew.log 即可。