$ git stash save
$ git bisect start
$ git bisect bad
$ git bisect good 0
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[< ... sha ... >] 3
git checkout KNOWN_BAD_COMMIT
git bisect start
# Confirm that our test script is correct, and fails on the bad commit.
./test
# Should output != 0.
echo $?
# Tell Git that the current commit is bad.
git bisect bad
# Same for a known good commit in the past.
git checkout KNOWN_GOOD_COMMIT
./test
# Should output 0.
echo $?
# After this, git automatically checks out to the commit
# in the middle of KNOWN_BAD_COMMIT and KNOWN_GOOD_COMMIT.
git bisect good
# Bisect automatically all the way to the first bad or last good rev.
git bisect run ./test
# End the bisect operation and checkout to master again.
git bisect reset
7条答案
按热度按时间7rfyedvj1#
git bisect
背后的思想是在历史中执行二进制搜索以找到特定的回归。你知道你的程序在
current
版本上不能正常工作,而它在0
版本上工作。所以回归很可能是在1
,2
,3
,4
,5
,current
的某个提交中引入的。你可以试着检查每个提交,构建它,检查回归是否存在。如果有大量的提交,这可能需要很长的时间。这是一个线性搜索。我们可以做一个二分搜索做得更好。这是
git bisect
命令所做的。在每一步,它试图减少一半的潜在坏的修订的数量。您将使用如下命令:
在这个命令之后,
git
将 checkout 一个commit。在我们的例子中,它将是commit3
。你需要构建你的程序,并检查回归是否存在。你还需要告诉git
这个版本的状态,如果回归存在,用git bisect bad
,如果不存在,用git bisect good
。假设回归是在提交
4
时引入的,那么回归在这个版本中不存在,我们把它告诉git
。然后它会 checkout 另一个提交。
4
或5
(因为只有两个提交)。让我们假设它选择了5
。在一个构建之后,我们测试程序,看到回归存在。然后我们告诉git
:我们测试最后一个版本
4
,因为它是引入回归的版本,所以我们将它告诉git
:在这个简单的情况下,我们只需要测试3个版本(
3
、4
、5
)而不是4个(1
,2
,3
,4
)。这是一个小的胜利,但这是因为我们的历史是如此之小。如果搜索范围是N个提交,我们应该期望用git bisect
测试1 + log 2N个提交,而不是用线性搜索测试大约N / 2个提交。一旦你找到了导致回归的提交,你就可以研究它来找到问题所在。一旦完成了这个工作,你就可以使用
git bisect reset
命令把所有东西都恢复到使用git bisect
命令之前的原始状态。f87krz0w2#
git bisect run
自动平分如果您有一个自动化的
./test
脚本,当测试正常时,该脚本的退出状态为0,则您可以自动查找bisect run
错误:当然,这是假设如果测试脚本
./test
被git跟踪,那么它不会在二分法过程中的某个早期提交中消失。我发现很多时候,你可以通过从树中复制树中的脚本,并可能使用类似
PATH
的变量,然后从那里运行它来摆脱困境。当然,如果
test
所依赖的测试基础设施在旧的提交上中断,那么就没有解决方案,您将不得不手动地做一些事情,决定如何一个一个地测试提交。然而我发现使用这种自动化通常是有效的,并且可以为积压的任务中的较慢测试节省大量时间,在那里您可以让它运行一夜,并且可能在第二天早上发现您的bug,这是值得一试的。
更多提示
在bisect之后停留在第一个失败的提交上,而不是返回到
master
:start
+初始的bad
和good
一次完成:与以下内容相同:
查看到目前为止已测试的内容(通过手动
good
和bad
或run
):示例输出:
在git日志上显示好的和坏的引用,以便更好地了解时间:
这只显示带有相应引用的提交,这大大减少了干扰,但确实包括自动生成的类型为:
它告诉我们哪些提交被标记为好或坏。
如果您想尝试使用该命令,请考虑使用this test repo。
失败来得快,成功来得慢
有时候:
对于这些情况,例如,假设故障总是在5秒内发生,并且如果我们不想让测试更具体,我们可以使用
timeout
,如下所示:这是因为
timeout
退出124
,而test-command
的故障退出1
。Magic退出状态
git bisect run
对退出状态有点挑剔:特别是,一个C
assert(0)
会导致一个SIGABRT
,并以状态134退出,非常烦人。git bisect skip
。这样做的目的是帮助跳过由于不相关的原因而中断的构建。
有关详细信息,请参见
man git-bisect
。因此,您可能需要使用类似以下的语句:
在git 2.16.1上测试。
x3naxklr3#
TL;DR
开始日期:
或者
Bisecting: X revisions left to test after this (roughly Y steps)
重复:
问题仍然存在?
$ git bisect bad
$ git bisect good
结果:
完成时:
lp0sw83n4#
再补充一点:
我们可以指定
git bisect start
的文件名或路径,以防我们知道bug来自特定的文件。例如,假设我们知道导致回归的更改在com/workingDir目录下,那么我们可以运行git bisect start com/workingDir
这意味着只有更改了该目录内容的提交才会被检查,这会使操作更快。另外,如果很难判断某个提交是好是坏,你可以运行
git bisect skip
,它会忽略它。如果有足够多的其他提交,git bisect会使用另一个来缩小搜索范围。sqserrrh5#
$ git bisect ..
基本上是一个 * 用于调试的Git工具 *。'Git Bisect'通过检查自上次(已知)工作提交以来的提交来进行调试。它使用二分搜索来检查所有提交,找到引入回归/bug的提交。$ git bisect start
#开始平分$ git bisect bad
#声明当前提交(v1.5)具有回归/设置“坏”点$ git bisect good v1.0
#将其作为最后一次正常工作提交(无回归)提到'bad'和'good'点将帮助git bisect(折半搜索)挑选中间的元素(commit v1.3)。如果在提交v1.3时出现回归,则将其设置为新的'bad'点,即(Good -〉v1.0 and Bad -〉v1.3)
或者类似地,如果提交v1.3是无错误的,你将把它设置为新的“好点”,即(*Good -〉v1.3 and Bad -〉v1.6)。
ifmq2ha26#
注意:术语
good
和bad
并不是唯一可以用来标记带有或不带有某个属性的提交的术语。Git 2.7(2015年第四季度)引入了新的
git bisect
选项。文档中添加了:
有时候,您并不是在寻找引入了中断的提交,而是在寻找一个提交,它导致了其他“旧”状态和“新”状态之间的变化。
例如,您可能正在查找引入特定修复的提交。
或者,你可能正在寻找第一次提交,在这一次提交中,源代码文件名最终都被转换成了你公司的命名标准。
在这种情况下,使用“好”和“坏”来指代“变化之前的状态”和“变化之后的状态”可能会非常混乱。
因此,您可以分别使用术语“
old
“和“new
“来代替“good
“和“bad
“。(But请注意,不能在单个会话中将“
good
“和“bad
“与“old
“和“new
“混合使用。)在这个更一般的用法中,你可以为
git bisect
提供一个“new
“提交,它有一些属性,而一个“old
“提交没有这个属性。每次
git bisect
checkout 一个提交时,测试该提交是否具有以下属性:如果是,则将提交标记为“
new
“;否则,将其标记为“old
“。当二分完成后,
git bisect
将报告哪个提交引入了该属性。请参见Matthieu Moy (
moy
)的commit 06e6a74、commit 21b55e3、commit fe67687(2015年6月29日)。2015年6月29日,第15话(英语:15话)。
(由Junio C Hamano --
gitster
--合并到commit 22dd6eb,2015年10月5日)请务必使用Git 2.39(2022年第四季度)来实现
git bisect run
:它包括修复bisect-helper
中的一个回归,该回归错误地将提供给“git bisect run
”(man)的命令的参数视为帮助程序的参数。请参见commit e9011b6、commit 464ce0a、commit 58786d7(2022年11月10日),作者为Đoàn Trần Công Danh (
sgn
)。(2022年11月23日,由Junio C Hamano --
gitster
--在commit e3d40fb中合并)第1001章:使用
OPT_SUBCOMMAND
解析子命令报告人:卢卡什医生
签署人:段陈公丹
签署人:泰勒·布劳
到目前为止,我们正在使用
OPT_CMDMODE,
解析子命令,即使找到了该命令,它也将继续解析更多选项。当我们运行“
git bisect run
“(man)时,如果命令需要--log
或--no-log
参数,或者“--bisect-...
“参数之一,bisect--helper
可能会错误地认为这些选项是bisect--helper
的选项。我们可以通过在从
git-bisect.sh
调用时传递“--
“并跳过bisect--helper
中的“--
“来解决这些问题。但是,它可能会干扰用户的“
--
“。让我们使用
OPT_SUBCOMMAND
解析子命令,因为该API是为此特定用例而生的。p5fdfcr17#
git二等分退出状态
Ciro Santilli的2014 answer将它们称为“神奇的退出状态”
它们在Git 2.36(Q2 2022)中的使用方式略有不同:一个不太常见的错误是编写一个脚本来运行“
git bisect
“(man),而不使其可执行,在这种情况下,所有的测试都将退出,并返回126或127个错误代码,即使是标记为好的修订版。尝试识别这种情况并尽早停止迭代。
参见René Scharfe (
rscharfe
)的commit 48af1fd、commit ba5bb81、commit 8efa2ac、commit 80c2e96(2022年1月18日)。(2022年3月6日由Junio C Hamano --
gitster
--合并至commit e828747)第1001章:在退出代码126和127上仔细检查运行命令
签署人:勒内·沙夫
当无法执行或找不到运行命令时,shell将分别返回退出代码126或127。
由于历史原因,允许有效的运行命令返回这些代码,以指示错误的修订。
这意味着打字错误可能导致假的二等分运行,在整个距离上运行,并最终报告无效结果。
最好的解决方案是保留退出代码126和127,如71b0251(二等分运行:,2007年10月26日,Git v1.5.4-rc 0--merge)(二等分运行:如果脚本退出代码为125,则“跳过”当前提交。,2007-10-26)对125执行了此操作,并在获得它们时中止
bisect run
。不过,这可能对那些依赖于说明126和127可以用于糟糕修订的文档的人来说不方便。
此修补程序使用的解决方法是在已知良好的修订版上运行该命令,如果仍然得到相同的错误代码,则中止。
这会为使用退出代码126和127的脚本的运行添加一个步骤,但仍支持它们,但有一个例外:如果命令无法识别(手动标记的)已知良好的版本,则无法使用该命令。
使用低退出代码的运行命令不受影响。
在执行缺失命令两次和三次校验(第一步,已知良好的修订版本,并返回第一步的修订版本)后,报告打字错误。
请参阅examples。