我读过一些文章,说git平分很棒。然而,我不明白为什么它很棒。

有人能演示一些代码示例:

如何使用它? 就像责备一样吗?


当前回答

注意:术语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 start指定一个文件名或路径,以防我们知道bug来自特定的文件。 例如, 假设我们知道导致回归的更改在com/workingDir中 然后运行git bisect start / workingdir 只有修改了此目录内容的提交才会被检查 这让事情变得更快。

此外,如果很难判断一个特定的提交是好是坏,您可以使用 可以运行git的等分跳过,这将忽略它。考虑到有足够多的其他 提交时,git bisect将使用另一个来缩小搜索范围。

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命令之前的原始状态。

注意:术语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.

博士TL;

开始:

$ git bisect start
$ git bisect bad
$ git bisect good <goodcommit>

Or

$ git bisect start
$ git bisect good
$ git bisect bad <badcommit>

平分:在此之后留下X个修订进行测试(大约Y步)

重复一遍:

问题还存在吗?

是的:$ git平分坏 不:$ git平分好

结果:

<abcdef> is the first bad commit

当完成:

git bisect reset

$ 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