git bisect:把「哪次提交弄坏的」变成一条命令
回归排查的瓶颈不是二分本身,而是没人说得出「什么样的提交算坏」。先写出能自动判定的脚本,bisect 才能把 n 次构建压到 log n 次。
git bisect 真正的门槛不在二分,而在你得先给出一个能自动回答「坏不坏」的判定。没有它,bisect 只能靠人一次次跑、一次次回答 good 或 bad,省不下多少事。
先写判定脚本
把「坏」定义成一条命令的退出码:0 是好,非 0 是坏。
#!/usr/bin/env bash
# scripts/bisect-repro.sh
set -euo pipefail
npm run build
node scripts/check-the-thing.mjs
只要这个脚本在坏提交上失败、在好提交上通过,bisect 就能无人值守地跑完:
git bisect start
git bisect bad HEAD
git bisect good v1.4.0
git bisect run ./scripts/bisect-repro.sh
git bisect run 会自动 checkout、跑脚本、按退出码打标记,最后把第一个坏提交打出来。
好提交必须真的「好」
最常见的事故是起点选得太近:拿上一个 release 当 good,而问题在那个版本里已经存在。这样二分区间从一开始就是错的,最后指到的必然是个无关提交。
判断方法很土但有效:先在候选 good 上把判定脚本跑通。跑不通就继续往前找。
退出码 125
脚本返回 125 表示「这个提交无法判定」,bisect 会跳过它。这对编不过的中间提交特别有用:
if ! npm run build > /dev/null 2>&1; then
exit 125 # 这个提交编不过,跳过
fi
少了这一步,中间任何一个坏掉的构建都会让整轮二分作废。
记录,而不是记住
git bisect log > /tmp/bisect.log # 中途存档
git bisect replay /tmp/bisect.log # 以后原样重跑
排查结束第一件事是 git bisect reset,否则你会带着 detached HEAD 继续干活。日志留着,等修完把这条命令贴进 issue —— 下一个遇到同样问题的人不必重来一遍。
bisect 省下的不是二分那几步,而是「写出判定」这件事逼你想清楚 bug 的边界。

评论
…