Git bisect is a command that helps you find the commit that introduced a bug or changed a property of your project using a binary search algorithm. You need to specify at least one good commit and one bad commit, and then git bisect will check out a commit in between and ask you to test it. You can then mark the commit as good or bad depending on the test result. This process will narrow down the range of commits until you find the first bad commit.
In this blog post, I will show you how to use git bisect to find the commit that broke a feature in your project.
Contents / 目次
Basic bisect commands: start, bad, good
Let’s say you want to find the commit that broke a feature that was working fine in version v2.6.13-rc2 of your project. You can start a bisect session like this:
$ git bisect start
$ git bisect bad # Current version is bad
$ git bisect good v2.6.13-rc2 # v2.6.13-rc2 is known to be good
Git bisect will then choose a commit between the two endpoints, check it out, and output something like this:
Bisecting: 675 revisions left to test after this (roughly 10 steps)
You need to compile and test the checked out version. If the version works correctly, you type:
$ git bisect good
If the version does not work, you type:
$ git bisect bad
Git bisect will then respond with something like this:
Bisecting: 337 revisions left to test after this (roughly 9 steps)
You repeat this process: compile, test, and run git bisect good
or git bisect bad
depending on the test result, until there are no more revisions to inspect. The command will then output the description of the first bad commit. The refs/bisect/bad
will point to that commit.
Bisect reset
After a bisect session, you can clean up the bisect state and return to the original head by running this command:
$ git bisect reset
By default, this will bring your tree back to the commit that was checked out before git bisect
was started (a new git bisect start
will also clean up any old bisection state, so you can start it without running this command). You can use an optional argument to go back to another commit instead.
$ git bisect reset <commit>
For example, git bisect reset bisect/bad
will check out the first bad revision, while git bisect reset HEAD
will leave you at the current bisection commit without switching commits at all.
Alternative terms
You might want to find the commit that changed a property of your project instead of a commit that broke something. For example, you might want to find the commit that fixed a bug or improved the performance of a benchmark. In such cases, using the terms “good” and “bad” to indicate “before change” and “after change” might be very confusing. Therefore, you can choose to use the terms “old” and “new” instead of “good” and “bad” (note that you cannot mix “good” and “bad” with “old” and “new” in one session).
In this more general usage, you give git bisect
some new commits that have some property and some old commits that do not have that property. Every time git bisect
checks out a commit, you test whether that commit has the property or not. If it does, you mark the commit as “new”. Otherwise, you mark it as “old”. When the bisection is done, git bisect
will report which commit introduced the property.
To use “old” and “new” instead of “good” and “bad”, you need to run git bisect start
without any commit arguments and then add commits with the following commands:
git bisect old [<rev>]
This marks a commit as before the change, while
git bisect new [<rev>]
marks a commit as after the change.
You can also use your own terms instead of “good” or “bad”, or “new” or “old” by using the --term-{old,good}
and --term-{new,bad}
options of git bisect start
. The old (new) term can be retrieved with git bisect terms --term-old
or git bisect terms --term-good
.
Summary
Git bisect is a useful tool to find the commit that introduced a bug or changed a property of your project. You can use it with different terms to suit your needs. You can also automate the testing process with a script or run other commands like git bisect log
or git bisect visualize
to inspect the bisection process. I hope this blog post helped you understand how to use git bisect and make your debugging easier.
Have a nice Git life!