git-bisect is very cool.
If you have ever had a situation where a commit was made that had a bug – but you are not sure which commit it is – then git-bisect is the tool you need.
To use git-bisect, you need to know a good commit and a bad commit. It does not matter how recent the good commit is – as long as it is free of the bug in question. So if you think the bug was introduced in the last 2 weeks, choose the good commit from two weeks ago. Usually the bad commit is the current commit.
The bisect process is started with three commands: 1 to start the bisect operation, 1 to indicate a good commit, and 1 to indicate a bad commit.
Given that information, git will find the commit exactly in the middle of the good and bad commits and perform a checkout. At that point your job is to determine if the bug is present in that version of the code. Once you have determined if the checked out commit is good or bad, you enter git-bisect good (or bad)
This process is repeated with git successively cutting the commits in half and you responding with git bisect good or bad. When the offending commit is found, git will indicate that the operation is complete.
To stop the bisect, type ‘git-bisect reset’.
The below example is small but it illustrates how bisect works. The binary nature of this search means that even a repository with thousands of commits can be searched relatively quickly.
C:\code\blog [master]> git l1 c0c8983 renamed index 1c3fca8 added new file f5394fc removed app3.js 2891ab0 updated app2 4233352 updated app1.js c8fbbc1 modified index page 71e0471 initial commit C:\code\blog [master]> git bisect start C:\code\blog [master]> git bisect bad C:\code\blog [master]> git bisect good c8fbbc1 Bisecting: 2 revisions left to test after this (roughly 1 step) [2891ab0fedd45e553979de942368d3728a6412f4] updated app 2 C:\code\blog [(2891ab0...)|BISECTING]> git bisect good Bisecting: 0 revisions left to test after this (roughly 1 step) [1c3fca854d02c4ebce605bbe234cfb8d95a1ae66] added new file C:\code\blog [(1c3fca8...)|BISECTING]> git bisect bad Bisecting: 0 revisions left to test after this (roughly 0 steps) [f5394fc841d35f004b368dff438dccf4607e1bec] removed app3.js C:\code\blog [f5394fc...)|BISECTING]> git bisect bad f5394fc841d35f004b368dff438dccf4607e1bec Author: Rick Herrmann <firstname.lastname@example.org> Date: Sat Jun 13 12:03:44 2015 -0400 removed app3.js :100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 D app3.js C:\code\blog [(f5394fc...)|BISECT]>
In steps 1, 2, and 3, I indicate if the checked out commit contains the bug (bad) or not (good). In step 4, git has identified the offending commit and lists the commit details (who to blame…).