Git Bisect

Reference Documentation

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)] $