定位回归问题时,可以让 git bisect 自动跑测试

78 次浏览5 条回复

如果能写一个返回 0/非 0 的检查命令,git bisect 不一定要手动一版版试。比如项目里已有测试命令时,可以这样:

git bisect start
git bisect bad HEAD
git bisect good <已知正常的提交>
git bisect run pytest -q tests/test_login.py

Git 会在每个候选提交执行命令,根据退出码继续缩小范围,最后停在疑似引入问题的提交。环境:Git 1.7.1+;检查命令要稳定,别让网络、时间或未固定的外部服务影响退出码。跑完记得 git bisect reset 回到原分支。

补一个容易踩的点:git bisect run 不只看 0/非 0。命令返回 125 时会跳过当前提交,适合处理“这版没法编译/测试条件不满足”的情况;返回 128 以上通常会中止。把检查脚本里的环境异常和测试失败区分开,定位结果会稳不少。

我还会把检查命令包成一个小脚本,先清掉上一次提交留下的构建产物,再编译/跑测试。否则不同提交复用旧缓存,bisect 找到的点可能不准。脚本里也可以固定测试选择和必要的环境变量,后面复现会省事不少。

还有个小细节:如果回归只在合并提交附近出现,可以先用 git bisect visualize 看一下候选范围,必要时把明显不相关的分支点标成 good/bad,别让测试结果把问题带到另一条支线上。检查脚本最好把当前 git rev-parse HEAD 和退出码写进日志,最后复核时会清楚很多。

别熬夜啦Lv1#3

还有个小细节:如果回归只在合并提交附近出现,可以先用 git bisect visualize 看一下候选范围,必要时把明显不相关的分支点标成 good/bad,别让测试结果把问题带到另一条支线上。检查脚本最好把当前 git rev-parse HEAD 和退出码写进日志,最后复核时会清楚很多。

我觉得还可以把“测试失败后是否重跑”单独定下来:默认不要自动重跑,否则偶发失败可能被吞掉。若确实要重试,记录每次运行的提交号、退出码和次数,并把最终结果标成不确定,别直接当成 good/bad。这样 bisect 找到候选提交后,复核时不容易被 flaky test 带偏。

雾很大Lv1#4

我觉得还可以把“测试失败后是否重跑”单独定下来:默认不要自动重跑,否则偶发失败可能被吞掉。若确实要重试,记录每次运行的提交号、退出码和次数,并把最终结果标成不确定,别直接当成 good/bad。这样 bisect 找到候选提交后,复核时不容易被 flaky test 带偏。

还有一点我会提前处理:测试最好用临时目录或临时数据库,别让某个提交留下的状态影响下一轮。尤其是会写缓存、迁移数据库的测试,包装成脚本时顺手清理资源,bisect 跑出来的结果会更可信。