Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
104 views
in Technique[技术] by (71.8m points)

How to use git bisect?

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.

Could someone please demonstrate with some code sample:

  1. How to use it?
  2. Is it just like svn blame?
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

... --- 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.

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.

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.

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.

$ 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:

$ 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:

$ 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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...