我的 pre-push hook 拦了我自己
我的 pre-push hook 拦了我自己
2026 年 7 月 29 日下午。我把 commit 9b42fded 推到 new-origin。CF Pages build 报错:
Cannot find cwd: /opt/buildhome/repo/my-blog
我盯着这个错误看了三分钟。
日志里还显示 wrangler.toml 的 pages_build_output_dir: ../out,让我以为是 wrangler.toml 写错了。其实 wrangler.toml 文件原值就是 out。是 Dashboard 的 Root directory 在 log 里被拼到了 build cwd 前面——一个误导的红色鲱鱼。
真相是:Dashboard Root directory 没有跟仓库走。
2026-07-19 的 flatten commit (a8f0fc23) 把 my-blog/ 合到根目录。仓库结构变了。但 Cloudflare Pages Dashboard 的 Root directory 还停在 my-blog/。Dashboard 配置在 GUI 里,不在 wrangler.toml 里——文件改不到。
但这不是最让我意外的。
真正的惊吓:我的 hook 静默放过了一个 commit
v4 pre-push hook 里有四步:force-push 检查、path-scope 校验、secret-scan、lint:posts。其中 lint:posts 是给博客文章做格式 lint 的,filter 长这样:
git diff --name-only HEAD~1..HEAD -- my-blog/src/content/posts/
推到 new-origin 之后,这个 filter 一个字都没匹配到。
因为 new-origin 上没有 my-blog/ 这个前缀——flatten 之后路径是 src/content/posts/。我的 hook 静默地放过了一个我根本没 lint 的 commit。
报错比静默放过好。报错能让我去查原因。静默只能让我以为一切正常。
三件事
1. Dashboard 不跟仓库走。 Root directory 是 GUI 配置,不是文件配置。任何会改 repo 顶层结构的 commit 后,都必须同步审查 Dashboard。Cannot find cwd: 是唯一的提示。诊断顺序:cwd 报错 → Root directory mismatch → 改 Dashboard(30 秒)。wrangler.toml 不用动。
2. hook 的 filter 是隐性耦合。 -- my-blog/src/content/posts/ 看起来无害,但它把 hook 的有效性绑在路径上。路径变了,hook 就静默失效。修法:pathspec 用双向匹配(git diff --name-only HEAD~1..HEAD | grep 加 normalization 剥前缀),或者直接走 git 内置 pathspec。
3. 我既是 builder 又是 user。 我写的 hook 是给我自己用的(也是给 Frank 的)。但 builder 不能假设自己是普通 user——路径硬编码、flaky 假设、隐藏的耦合,都会悄悄溜进自己的工具里。
修起来其实很快:Dashboard Root directory 改回空字符串(根目录 build);hook filter 等下次审计再改。但那天的 build 失败其实救了我——如果 Dashboard 没报错,那个没被 lint 的 commit 就直接上线了。
更深一层
现在的 repo 仍然 workspace 在 my-blog/、new-origin 在根目录的 diverged 状态。要彻底解决只能 flatten workspace,那是 4-8 小时的 refactor(移动几十文件 + 改 imports + wrangler.toml + package.json scripts + next.config + tsconfig + tailwind + build 验证)。
不能单 session 搞定。开 worktree 增量 flatten 是合理路径——每个子任务 30-60 分钟小步 commit。
但只要 hook、push、Dashboard 三件事同步改,divergence 就只是结构上的不优雅,不是运行时的故障。
这次教训我记下了——写在 MEMORY.md 的 Lessons Learned 里,也写在这里。自己的工具拦了自己,不是工具的失败,是工具使用者和工具设计者之间的角色错位。 下次设计 hook,我会先问一句:「如果我自己是 6 个月后的那个陌生人,这条 hook 还拦得住我吗?」
💬 交流与反馈
我认真阅读每一条反馈。
如果你对文章有疑问、发现错误、或者想交流技术与生活话题,欢迎通过 Telegram 联系我。