我读过一些文章,说git平分很棒。然而,我不明白为什么它很棒。
有人能演示一些代码示例:
如何使用它? 就像责备一样吗?
我读过一些文章,说git平分很棒。然而,我不明白为什么它很棒。
有人能演示一些代码示例:
如何使用它? 就像责备一样吗?
当前回答
git bisect背后的思想是在历史中执行二进制搜索以找到特定的回归。假设您拥有以下开发历史:
... --- 0 --- 1 --- 2 --- 3 --- 4* --- 5 --- current
您知道您的程序在当前的修订版本中不能正常工作,它在修订版本0时工作。因此,回归很可能是在当前的1、2、3、4、5次提交中引入的。
你可以试着检查每个提交,构建它,检查回归是否存在。如果有大量的提交,这可能会花费很长时间。这是线性搜索。我们可以用二分法搜索。这就是git bisect命令的作用。在每一步中,它都试图将有潜在缺陷的修订数量减少一半。
你会像这样使用命令:
$ 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将检出提交。在我们的例子中,它是commit 3。您需要构建您的程序,并检查回归是否存在。你还需要告诉git这个修订的状态,如果回归存在,git平分为坏,如果没有,git平分为好。
让我们假设在提交4中引入了回归。然后回归在这个修订中不存在,我们告诉它git。
$ make
$ make test
... ... ...
$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[< ... sha ... >] 5
然后它将检出另一个提交。4或5(因为只有两次提交)。假设它选了5。在构建之后,我们测试程序并查看回归是否存在。然后我们告诉它git:
$ make
$ make test
... ... ...
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[< ... sha ... >] 4
我们测试最后的版本4。因为它是引入回归的那个,我们告诉它git:
$ make
$ make test
... ... ...
$ git bisect bad
< ... sha ... > is the first bad commit
< ... commit message ... >
在这种简单的情况下,我们只需要测试3个版本(3,4,5),而不是4个版本(1,2,3,4)。这是一个小胜利,但这是因为我们的历史是如此之小。如果搜索范围是N个提交,我们应该期望用git平分测试1 + log2n个提交,而不是用线性搜索粗略地测试N / 2个提交。
一旦找到了引入回归的提交,就可以研究它以找到问题所在。完成后,使用git bisect reset将所有内容恢复到使用git bisect命令之前的原始状态。
其他回答
再补充一点:
我们可以为git bisect start指定一个文件名或路径,以防我们知道bug来自特定的文件。 例如, 假设我们知道导致回归的更改在com/workingDir中 然后运行git bisect start / workingdir 只有修改了此目录内容的提交才会被检查 这让事情变得更快。
此外,如果很难判断一个特定的提交是好是坏,您可以使用 可以运行git的等分跳过,这将忽略它。考虑到有足够多的其他 提交时,git bisect将使用另一个来缩小搜索范围。
注意:术语good和bad并不是唯一可以用于标记带有或不带有某个属性的提交的术语。
Git 2.7(2015年Q4)引入了新的Git平分选项。
git bisect start [--term-{old,good}=<term> --term-{new,bad}=<term>]
[--no-checkout] [<bad> [<good>...]] [--] [<paths>...]
文档添加:
Sometimes you are not looking for the commit that introduced a breakage, but rather for a commit that caused a change between some other "old" state and "new" state. For example, you might be looking for the commit that introduced a particular fix. Or you might be looking for the first commit in which the source-code filenames were finally all converted to your company's naming standard. Or whatever. In such cases it can be very confusing to use the terms "good" and "bad" to refer to "the state before the change" and "the state after the change". So instead, you can use the terms "old" and "new", respectively, in place of "good" and "bad". (But note that you cannot mix "good" and "bad" with "old" and "new" in a single session.) In this more general usage, you provide git bisect with a "new" commit has some property and an "old" commit that doesn't have that property. Each time git bisect checks out a commit, you test if that commit has the property: If it does, mark the commit as "new"; otherwise, mark it as "old". When the bisection is done, git bisect will report which commit introduced the property.
参见Matthieu Moy (Moy)的commit 06e6a74, commit 21b55e3, commit fe67687(2015年6月29日)。 参见Antoine Delaite (CanardChouChinois)提交的21e5cfd(2015年6月29日)。 (由Junio C Hamano—gitster—在commit 22dd6eb中合并,2015年10月5日)
确保使用Git 2.39 (Q4 2022)进行Git bisect run:它包括修复bisect-helper中的回归,该回归错误地将给予' Git bisect run'(man)的命令的参数作为helper的参数。
参见commit e9011b6, commit 464ce0a, commit 58786d7 (10 Nov 2022) by Đoàn trn Công Danh (sgn)。 (由Junio C Hamano—gitster—在commit e3d40fb中合并,2022年11月23日)
bisect——helper:用OPT_SUBCOMMAND解析子命令 报告:Lukáš博士 署名:Đoàn trn Công Danh 署名:泰勒·布劳
As of it is, we're parsing subcommand with OPT_CMDMODE, which will continue to parse more options even if the command has been found. When we're running "git bisect run"(man) with a command that expecting a --log or --no-log arguments, or one of those "--bisect-..." arguments, bisect--helper may mistakenly think those options are bisect--helper's option. We may fix those problems by passing "--" when calling from git-bisect.sh, and skip that "--" in bisect--helper. However, it may interfere with user's "--". Let's parse subcommand with OPT_SUBCOMMAND since that API was born for this specific use-case.
git bisect背后的思想是在历史中执行二进制搜索以找到特定的回归。假设您拥有以下开发历史:
... --- 0 --- 1 --- 2 --- 3 --- 4* --- 5 --- current
您知道您的程序在当前的修订版本中不能正常工作,它在修订版本0时工作。因此,回归很可能是在当前的1、2、3、4、5次提交中引入的。
你可以试着检查每个提交,构建它,检查回归是否存在。如果有大量的提交,这可能会花费很长时间。这是线性搜索。我们可以用二分法搜索。这就是git bisect命令的作用。在每一步中,它都试图将有潜在缺陷的修订数量减少一半。
你会像这样使用命令:
$ 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将检出提交。在我们的例子中,它是commit 3。您需要构建您的程序,并检查回归是否存在。你还需要告诉git这个修订的状态,如果回归存在,git平分为坏,如果没有,git平分为好。
让我们假设在提交4中引入了回归。然后回归在这个修订中不存在,我们告诉它git。
$ make
$ make test
... ... ...
$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[< ... sha ... >] 5
然后它将检出另一个提交。4或5(因为只有两次提交)。假设它选了5。在构建之后,我们测试程序并查看回归是否存在。然后我们告诉它git:
$ make
$ make test
... ... ...
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[< ... sha ... >] 4
我们测试最后的版本4。因为它是引入回归的那个,我们告诉它git:
$ make
$ make test
... ... ...
$ git bisect bad
< ... sha ... > is the first bad commit
< ... commit message ... >
在这种简单的情况下,我们只需要测试3个版本(3,4,5),而不是4个版本(1,2,3,4)。这是一个小胜利,但这是因为我们的历史是如此之小。如果搜索范围是N个提交,我们应该期望用git平分测试1 + log2n个提交,而不是用线性搜索粗略地测试N / 2个提交。
一旦找到了引入回归的提交,就可以研究它以找到问题所在。完成后,使用git bisect reset将所有内容恢复到使用git bisect命令之前的原始状态。
$ git平分…基本上是一个Git调试工具。'Git Bisect'通过检查上次(已知的)工作提交后的前一次提交来调试。它使用二分搜索遍历所有提交,找到引入回归/错误的提交。
$ git bisect start #开始平分
$ git bisect bad #表示当前提交(v1.5)有回归/设置“坏”点
$ git bisect good v1.0 #提到它的最后一个良好的工作提交(没有回归)
这里提到的“坏”和“好”点将帮助git平分(二分搜索)选择中间的元素(提交v1.3)。如果回归是在提交v1.3,你将把它设置为新的“坏”点,即(好-> v1.0和坏-> v1.3)
$ git bisect bad
或者类似地,如果提交v1.3没有bug,你将把它设置为新的“Good point”,即(*Good -> v1.3和Bad -> v1.6)。
$ git bisect good
Git对退出状态进行等分
Ciro Santilli在2014年给出的答案将其称为“神奇的退出状态”
在Git 2.36 (Q2 2022)中,它们的使用略有不同:一个不太常见的错误是编写了一个脚本,让“Git bisect”(man)运行而不使其可执行,在这种情况下,所有测试都会以126或127个错误代码退出,即使是在标记为良好的修订中。
试着认识到这种情况并尽早停止迭代。
参见commit 48af1fd, commit ba5bb81, commit 8efa2ac, commit 80c2e96 (18 Jan 2022) by René Scharfe (rscharfe)。 (由Junio C Hamano—gitster—在提交e828747中合并,2022年3月6日)
Bisect——helper:在退出码126和127上再次检查运行命令 署名:René Scharfe
When a run command cannot be executed or found, shells return exit code 126 or 127, respectively. Valid run commands are allowed to return these codes as well to indicate bad revisions, though, for historical reasons. This means typos can cause bogus bisect runs that go over the full distance and end up reporting invalid results. The best solution would be to reserve exit codes 126 and 127, like 71b0251 (Bisect run: , 2007-10-26, Git v1.5.4-rc0 -- merge) (Bisect run: "skip" current commit if script exit code is 125., 2007-10-26) did for 125, and abort bisect run when we get them. That might be inconvenient for those who relied on the documentation stating that 126 and 127 can be used for bad revisions, though. The workaround used by this patch is to run the command on a known-good revision and abort if we still get the same error code. This adds one step to runs with scripts that use exit codes 126 and 127, but keeps them supported, with one exception: It won't work with commands that cannot recognize the (manually marked) known-good revision as such. Run commands that use low exit codes are unaffected. Typos are reported after executing the missing command twice and three checkouts (the first step, the known good revision and back to the revision of the first step).
看到的例子。