How to find a commit introducing a bug?
git bisect start
git bisect bad
git bisect good
To find a commit introducing a bug search your commits with git bisect
. You will need to mark a working version of your code with git bisect good
and the buggy version with git bisect bad
.
After this, bisect
will search your commits and let you decide if the given version has the bug or not, until you find the commit introducing the bug.
Let's try bisect with a simple example. We have a dummy ruby script, which is supposed to add two numbers, but the result is incorrect:
ruby math.rb 2 3
-1
We know, that it worked, when it was first commited (commit with SHA 5dd0af3
) and that it's not working in the current version (HEAD
).
git log --oneline
(HEAD -> main) Use if instead of case
2527a94 Fix operation name issue
322b7b5 Only support existing operators or nil
37ac958 Rename operations
15e4354 Use operation based on param
6927057 Support operator param
6c6725c Add division
cfb26cd Add multiplication
ba9a893 Add substraction
ccc2c6f Add arguments
5dd0af3 Rename addition to math
a944039 Add addition.rb
To start bisecting, we need to run git bisect start
and mark one working and one failing version of our code. The currently checked out commit (HEAD
) is failing, which we mark with git bisect bad
. The working version we found earlier is marked with git bisect good 5dd0af3
.
git bisect start
git bisect bad
git bisect good 5dd0af3
Bisecting: 4 revisions left to test after this (roughly 2 steps)
[69270572fd6450f0b0f57f4a5e783a0099080577] Support operator param
After having marked the bad and the good version of the code, git starts bisecting with an automatic checkout of a version (6927057
) we should test next.
We run the ruby script again, and see that it adds the numbers correctly. The bug was not yet introduced in this commit, which we mark with git bisect good
.
ruby math.rb 2 3
5
git bisect good
Bisecting: 2 revisions left to test after this (roughly 1 step)
[37ac958e3983e2869269da3f816c8dda8d2149f3] Rename operations
Git checks out the next commit for us to test (37ac958
), in which the ruby script is not working properly and we mark the commit with git bisect bad
.
ruby math.rb 2 3
-1
git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[15e435418ba2279217bae9ed70c65a112609234b] Use operation based on param
We need to repeat these steps of testing the script and marking the commit as good or bad until git finds and shows us the commit introducing the bug.
In this example it's commit "Rename operations" (37ac958
):
ruby math.rb 2 3
5
git bisect good
37ac958e3983e2869269da3f816c8dda8d2149f3 is the first bad commit
commit 37ac958e3983e2869269da3f816c8dda8d2149f3
Author: Tom Ato
Date: Fri Dec 3 17:06:32 2021 +0100
Rename operations
math.rb | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
Once we found the bad commit, we can clean up the bisection state with git bisect reset
and git
will return to the original HEAD
, where we started bisecting.
We can also show the changes introduced with the buggy commit and see where the operation return a + b
was changed to return a - b
, breaking our code.
git bisect reset
Previous HEAD position was 15e4354 Use operation based on param
Switched to branch 'main'
git show 37ac958e3983e2869269da3f816c8dda8d2149f3
commit 37ac958e3983e2869269da3f816c8dda8d2149f3
Author: Tom Ato
Date: Fri Dec 3 17:06:32 2021 +0100
Rename operations
diff --git a/math.rb b/math.rb
index e819de6..f79219d 100644
--- a/math.rb
+++ b/math.rb
@@ -1,17 +1,17 @@
-def add(a, b)
- return a + b
+def operation_add(a, b)
+ return a - b
end
See git bisect to learn more about it.