如何使用 git bisect?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4713088/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use git bisect?
提问by IAdapter
I have read some articles saying that git bisect
is awesome. However, I'm not a native speaker and I can't understand why it's awesome.
我读过一些文章说这git bisect
很棒。但是,我不是母语人士,我不明白为什么它很棒。
Could someone please demonstrate with some code sample:
有人可以用一些代码示例演示一下:
- How to use it?
- Is it just like
svn blame
?
- 如何使用它?
- 是不是就像
svn blame
?
回答by Sylvain Defresne
The idea behind git bisect
is to perform a binary search in the history to find a particular regression. Imagine that you have the following development history:
背后的想法git bisect
是在历史中执行二分搜索以找到特定的回归。假设您有以下开发历史:
... --- 0 --- 1 --- 2 --- 3 --- 4* --- 5 --- current
You know that your program is not working properly at the current
revision, and that it was working at the revision 0
. So the regression was likely introduced in one of the commits 1
, 2
, 3
, 4
, 5
, current
.
您知道您的程序在current
修订版中无法正常工作,并且它在修订版中工作0
。因此,回归中提交的一个可能的介绍1
,2
,3
,4
,5
,current
。
You could try to check out each commit, build it, check if the regression is present or not. If there is a large number of commits, this can take a long time. This is a linear search. We can do better by doing a binary search. This is what the git bisect
command does. At each step it tries to reduce the number of revisions that are potentially bad by half.
您可以尝试检查每个提交,构建它,检查是否存在回归。如果有大量提交,这可能需要很长时间。这是一个线性搜索。我们可以通过二分搜索做得更好。这就是git bisect
命令的作用。在每一步,它都试图将可能有问题的修订数量减少一半。
You'll use the command like this:
您将使用如下命令:
$ 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
After this command, git
will checkout a commit. In our case, it'll be commit 3
. You need to build your program, and check whether or not the regression is present. You'll also need to tell git
the status of this revision with either git bisect bad
if the regression is present, or git bisect good
if it is not.
在这个命令之后,git
将签出一个提交。在我们的例子中,它将是 commit 3
。您需要构建您的程序,并检查是否存在回归。您还需要通过回归是否存在或不存在来告知git
此修订的状态。git bisect bad
git bisect good
Let's suppose that the regression was introduced in commit 4
. Then the regression is not present in this revision, and we tell it to git
.
假设回归是在 commit 中引入的4
。那么这个版本中不存在回归,我们告诉它git
。
$ make
$ make test
... ... ...
$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[< ... sha ... >] 5
It will then checkout another commit. Either 4
or 5
(as there are only two commits). Let's suppose it picked 5
. After a build we test the program and see that the regression is present. We then tell it to git
:
然后它会检出另一个提交。无论是4
或5
(如只有两个提交)。假设它选择了5
。在构建之后,我们测试程序并看到回归存在。然后我们告诉它git
:
$ make
$ make test
... ... ...
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[< ... sha ... >] 4
We test the last revision, 4
. And since it is the one that introduced the regression, we tell it to git
:
我们测试最后一个修订版,4
. 由于它是引入回归的那个,我们告诉它git
:
$ make
$ make test
... ... ...
$ git bisect bad
< ... sha ... > is the first bad commit
< ... commit message ... >
In this simple situation, we only had to test 3 versions (3
, 4
, 5
) instead of 4 (1
, 2
, 3
, 4
). This is a small win, but this is because our history is so small. If the search range is of N commits, we should expect to test 1 + log2 N commits with git bisect
instead of roughly N / 2 commits with a linear search.
在这种简单的情况下,我们只需要测试 3 个版本 ( 3
, 4
, 5
) 而不是 4 个 ( 1
, 2
, 3
, 4
)。这是一个小小的胜利,但这是因为我们的历史太小了。如果搜索范围是 N 次提交,我们应该期望git bisect
使用线性搜索测试 1 + log2 N 次提交,而不是大约 N / 2 次提交。
Once you've found the commit that introduced the regression, you can study it to find the issue. Once this is done, you use git bisect reset
to put everything back on the original state before using git bisect
command.
找到引入回归的提交后,您可以研究它以找到问题。完成此操作后,您可以git bisect reset
在使用git bisect
命令之前将所有内容恢复到原始状态。
回答by Geoffrey Hale
TL;DR
TL; 博士
Start:
开始:
$ git bisect start
$ git bisect bad
$ git bisect good <goodcommit>
Bisecting: X revisions left to test after this (roughly Y steps)
Bisecting: X revisions left to test after this (roughly Y steps)
Repeat:
重复:
Issue still exists?
问题还存在吗?
- Yes:
$ git bisect bad
- No:
$ git bisect good
- 是的:
$ git bisect bad
- 不:
$ git bisect good
Result:
结果:
<abcdef> is the first bad commit
When Done:
完成时:
git bisect reset
回答by Nicks
Just to add a further point:
再补充一点:
We can specify a file name or path to git bisect start
in case we know that the bug has come from particular files.
For example,
Suppose we knew that the changes that caused the regression were in the com/workingDir
directory then we can run git bisect start com/workingDir
This means that
only the commits that changed the contents of this directory will be checked, and
this makes things even faster.
我们可以指定文件名或路径 git bisect start
,以防我们知道错误来自特定文件。例如,假设我们知道导致回归的更改在 com/workingDir 目录中,那么我们可以运行git bisect start com/workingDir
这意味着只会检查更改此目录内容的提交,这使事情变得更快。
Also,If it's difficult to tell if a particular commit is good or bad, you
can run git bisect skip
, which will ignore it. Given there are enough other
commits, git bisect will use another to narrow the search instead.
此外,如果很难判断特定提交是好是坏,您可以运行git bisect skip
,它将忽略它。鉴于有足够多的其他提交,git bisect 将使用另一个来缩小搜索范围。
回答by Nabeel Ahmed
$ git bisect ..
bascically a Git tool for debugging. 'Git Bisect' debugs by going through the previous commitssince your last (known) working commit. It uses binary search to go through all those commits, to get to the one which introduced the regression/bug.
$ git bisect ..
基本上是一个用于调试的Git 工具。“Git Bisect”通过检查自上次(已知)工作提交以来的先前提交进行调试。它使用二进制搜索来遍历所有这些提交,以找到引入回归/错误的提交。
$ git bisect start
# Starting bisect
$ git bisect start
# 开始平分
$ git bisect bad
# stating that the current commit (v1.5) has the regression/ setting 'bad' point
$ git bisect bad
# 说明当前提交(v1.5)具有回归/设置“坏”点
$ git bisect good v1.0
# mentioning it the last good working commit (without regression)
$ git bisect good v1.0
# 提到它最后一个好的工作提交(没有回归)
This mentioning of 'bad' and 'good' points will help git bisect(binary search) pick the middle element (commit v1.3). If the regression is there at commit v1.3, you'll set it as the new 'bad' point i.e. (Good -> v1.0 and Bad -> v1.3)
提到“坏”和“好”点将有助于git bisect(二进制搜索)选择中间元素(commit v1.3)。如果在提交 v1.3 时存在回归,您会将其设置为新的“坏”点,即(Good -> v1.0 和 Bad -> v1.3)
$ git bisect bad
or similarly if the commit v1.3 is bug-free you'll set it as the new 'Good point' i.e. (*Good -> v1.3 and Bad -> v1.6).
或者类似地,如果提交 v1.3 没有错误,您将其设置为新的“好点”,即(*Good -> v1.3 和 Bad -> v1.6)。
$ git bisect good
回答by VonC
Note: the terms good
and bad
are not the only ones you can use for marking a commit with or without a certain property.
注意:术语good
和bad
并不是您可以用于标记具有或不具有特定属性的提交的唯一术语。
Git 2.7 (Q4 2015) introduced new git bisect
options.
Git 2.7(2015 年第四季度)引入了新git bisect
选项。
git bisect start [--term-{old,good}=<term> --term-{new,bad}=<term>]
[--no-checkout] [<bad> [<good>...]] [--] [<paths>...]
With documentation adding:
随着文档添加:
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.
有时,您不是在寻找引入破坏的提交,而是在寻找导致其他“旧”状态和“新”状态之间发生变化的提交。
例如,您可能正在寻找引入特定修复程序的提交。
或者您可能正在寻找源代码文件名最终全部转换为您公司的命名标准的第一次提交。管他呢。在这种情况下,使用术语“好”和“坏”来指代“变更前的状态”和“变更后的状态”可能会非常混乱。
因此,您可以分别使用术语“
old
”和“new
”来代替“good
”和“bad
”。
(但请注意,您不能在单个会话中将“good
”和“bad
”与“old
”和“new
”混合使用。)在这种更一般的用法中,您提供
git bisect
了一个new
具有某些属性的 "old
" 提交和一个没有该属性的 " " 提交。每次
git bisect
检出提交时,您测试该提交是否具有以下属性:
如果具有,则将该提交标记为“new
”;否则,将其标记为“old
”。当二分完成后,
git bisect
将报告哪个提交引入了该属性。
See commit 06e6a74, commit 21b55e3, commit fe67687(29 Jun 2015) by Matthieu Moy (moy
).
See commit 21e5cfd(29 Jun 2015) by Antoine Delaite (CanardChouChinois
).
(Merged by Junio C Hamano -- gitster
--in commit 22dd6eb, 05 Oct 2015)
参见Matthieu Moy ( ) 的commit 06e6a74、commit 21b55e3、commit fe67687(2015 年 6 月 29 日)。
请参阅Antoine Delaite ( ) 的commit 21e5cfd(2015 年 6 月 29 日)。(由Junio C Hamano合并-- --在提交 22dd6eb,2015 年 10 月 5 日)moy
CanardChouChinois
gitster