Git Bisect
Git Bisect is a super helpful tool to determine where a bug or issue was introduced into the codebase when you’re not sure what commit caused it.
Finding the Commit that Introduced a Bug
Step #1: Tell Git to start the bisect process
1
$ git bisect start
Step #2: Tell Git that the current commit is where the problem exists
1
$ git bisect bad
Step #3: Tell Git which commit you know things were working properly
1
$ git bisect good <commit hash or tag>
Next, Git will check out a commit somewhere approximately in the middle.
You test to see if the issue still exists in that commit or not.
Step #4: Then, you just need to tell Git the result of your test
If the issue still exists, tell Git the commit is bad:
1
$ git bisect bad
If the issue isn’t there, tell Git the commit is good:
1
$ git bisect good
Git will split the remaining commits in half and check out a commit somewhere in the middle of this set.
Return to Step #4 and repeat until Git has found the commit that introduced the issue.
Once You’ve Found the Commit that Introduced the Issue
Once you have the commit that caused the unexpected behavior, tell Git you’re done with the bisect process:
1
$ git bisect reset
Voila! You now know which commit introduced the issue. Now for the fun part: fixing it!
What does the output look like?
Let’s check out a sample output from a real-world example:
Starting the bisect process
1
2
3
4
5
6
[project-directory (Current Branch: main)]$ git bisect start
[project-directory (Current Branch: main)]$ git bisect bad
[project-directory (Current Branch: main)]$ git bisect good ef6c9010
Bisecting: 61 revisions left to test after this (roughly 6 steps)
<Git displays information about the commit it checked out for testing>
Finding the commit that introduced the issue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[project-directory ((no branch, bisect started on main))]$ git bisect bad
Bisecting: 30 revisions left to test after this (roughly 5 steps)
<Git displays information about the commit it checked out for testing>
[project-directory ((no branch, bisect started on main))]$ git bisect bad
Bisecting: 14 revisions left to test after this (roughly 4 steps)
<Git displays information about the commit it checked out for testing>
[project-directory ((no branch, bisect started on main))]$ git bisect bad
Bisecting: 7 revisions left to test after this (roughly 3 steps)
<Git displays information about the commit it checked out for testing>
[project-directory ((no branch, bisect started on main))]$ git bisect good
Bisecting: 3 revisions left to test after this (roughly 2 steps)
<Git displays information about the commit it checked out for testing>
[project-directory ((no branch, bisect started on main))]$ git bisect good
Bisecting: 1 revision left to test after this (roughly 1 step)
<Git displays information about the commit it checked out for testing>
[project-directory ((no branch, bisect started on main))]$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 0 steps)
<Git displays information about the commit it checked out for testing>
[project-directory ((no branch, bisect started on main))]$ git bisect good
<commit hash> is the first bad commit
_<Git displays information about the commit>_
x files changed, y insertions(+)
Wrapping up the bisect process
1
2
3
4
5
6
7
[project-directory ((no branch, bisect started on main))]$ git bisect reset
Previous HEAD position was <Commit Hash and Message>
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
[project-directory (Current Branch: main)] $