遇到稳定回归时,git bisect run 可以把二分定位自动化

16 次浏览3 条回复

如果某个测试在旧提交通过、现在失败,而且能用一条命令判断成败,可以让 Git 自动二分:

git bisect start
git bisect bad HEAD
git bisect good <最后一个正常提交>
git bisect run sh -c 'python -m pytest tests/test_parser.py -q'
git bisect reset

测试命令返回 0 表示 good,非 0 表示 bad;脚本要尽量稳定,偶发失败会把结果带偏。环境:Git 2.x,示例是 Python 3.9+ / pytest 7+,命令在仓库根目录执行。git bisect run 会切换提交并运行命令,结束后用 git bisect reset 回到原来的分支。

这里还可以补一个容易踩的点:命令遇到当前提交不适合测试时,可以返回 125,让 bisect 跳过它,不要把环境问题误判成 bad。比如依赖没装全、构建脚本缺文件这类情况先单独处理;真正的测试断言失败再返回非 0。这样二分结果会稳不少。

FinleyLv1#1

这里还可以补一个容易踩的点:命令遇到当前提交不适合测试时,可以返回 125,让 bisect 跳过它,不要把环境问题误判成 bad。比如依赖没装全、构建脚本缺文件这类情况先单独处理;真正的测试断言失败再返回非 0。这样二分结果会稳不少。

还有个细节:bisect 会不断切换提交,测试命令产生的未跟踪文件不会自动清掉,可能污染后续提交。脚本里最好用临时目录,或每轮结束清理;开始前也确认工作区没有未提交改动。否则最后定位到的可能是环境污染,而不是真正引入回归的提交。

Nathan03Lv1#2

还有个细节:bisect 会不断切换提交,测试命令产生的未跟踪文件不会自动清掉,可能污染后续提交。脚本里最好用临时目录,或每轮结束清理;开始前也确认工作区没有未提交改动。否则最后定位到的可能是环境污染,而不是真正引入回归的提交。

用 pytest 时还要留意退出码:5 是“没收集到测试”,不一定代表回归。比如某个旧提交还没有这个测试文件,直接交给 bisect 就会被当成 bad。包装脚本里可以把这类情况映射成 125,真正的断言失败再返回 1。