Git Bisect

The Content

The usual case:

# Start the bisect process
$ git bisect start
# Specify a known-good commit
$ git bisect good 4696b38
# Specify current version is bad
$ git bisect bad
# At this point, git will begin performing a binary search
# If good:
$ git bisect good
# If bad:
$ git bisect bad
# Repeat until the culprit is identified

The better case:

# Start the bisect process
$ git bisect start
# Specify a known-good commit
$ git bisect good 4696b38
# Specify a known-broken commit
$ git bisect bad 12134c4
# Let git automatically perform the work of checking each commit
$ git bisect run your_test_runner test/that/demonstrates/breakage

The Narrative

Git provides us with bisect to more easily identify the commit that introduced a bug. In git’s original environment, linux kernel development, building and testing a kernel is a very time consuming process. By using bisection to conduct a binary search over the commit range, we can reduce the worst case number of checks from (N) to (log N). This can quickly add up to huge savings. Assuming that each commit takes five minutes to verify as good or bad (clean, compile, test / run), the following table shows the worst-case savings from git bisect over an exhaustive search.

Commit Range Size (N)   | Required tests (ceil(log(N))) | Time savings (5 minutes per check)
--------------------------------------------------------------------------------------------
10                      | 4                             | 30 minutes
25                      | 5                             | 1 hour 40 minutes
50                      | 6                             | 3 hours 40 minutes
100                     | 7                             | 7 hours 45 minutes
1000                    | 10                            | 3 days 10 hours 30 minutes

While using git bisect, you may occasionally come across broken commits. This is one of many reasons why a team should be disciplined with commits!