定位工具 Git Bisect
分类:技术
经过 @Neuron Teckid 童鞋的提点,发现了 git bisect
这个非常有意思的工具。
话说,我第一眼把 bisect 看成了 biscuit,以为 Git 也开始学 Android 卖萌了呢……结果一查字典,这个词是「等分」的意思……
假设某天你发现你编译出的程序里有个 Bug,该如何找出它是从哪个版本开始引入的呢?在版本历史中找出有 Bug 和无 Bug 两个版本,用简单的二分查找法就可以定位啦。git bisect
正是用来帮助你完成这种二分查找法的自动化的。
基本用法
git bisect start # 初始化二分查找
git bisect bad # 标记当前版本存在问题
git bisect good 38a63d9 # 标记 38a63d9 版本没有问题
至少标记了一个没有问题的版本(Good)和一个有问题的版本(Bad)后,Git 就会开始二分查找的过程,不断检出 Good 和 Bad 中间的版本等待你检查后作出标记。每次检出后 Git 都会提示你还剩多少文件、大致还剩余多少次比较:
Bisecting: 441 revisions left to test after this (roughly 9 steps)
比如上面这三步后,Git 检出了中间版本 b17ff03
。你编译运行后发现这个版本没有问题,就可以用 git bisect good
将当前版本标记为没有问题。此时 Git 就会再把 b17ff03
和最初版本之间的区域二分,检出中间版本等待你的检查。
等一切完成以后,就可以用 git bisect reset
返回开始前的版本。
自动查找
手动标记 Good / Bad 可以帮助人类从挑选下一个合适的版本的工作中解放出来。(似乎可以理解为 C++ 从 for
到 std::for_each
的抽象过程。)但这还是远远不够的,因为测试某个版本是否正常的重任依旧需要人类的介入。
所幸你可以指定一个检测用的程序,让 git bisect
自动完成整个定位的过程。这个程序必须在当前版本没有问题时返回 0,而 1 到 127 之间的值则表示有问题(特殊值 125 表示没法确定)。
git bisect run <cmd>...
例如,让你从一个陌生的代码库里找到能够编译和不能编译的临界提交,我们可以通过传入 make
来实现自动化查找:
git bisect start HEAD 38a63d9 # 简单写法:初始化二分查找,HEAD 有问题,而 38a63d9 没有
git bisect run make # 利用 make 来检测某个版本是否能够通过编译
而后,Git 就会自己用二分查找法不断检出中间版本,每次检出后都会运行 make
,根据 make
的返回值来确定当前版本是否存在问题(是否能够通过编译)。
以上。