January 26, 2016

Git 'bisect' your broken code more quickly and easily

This highlights another benefit of committing regularly (after a few new functions or after every 15 minutes of coding). If you have lots of commits and you hit a wall debugging you could use your commit history to narrow down where the problem lies.

Git has a handy little command that uses a binary search algorithm to find which commit in your project’s history introduced a bug. If you know roughly the commit where it was 'good' you can use Git to bisect between these 'good' and 'bad' commits to find a point you can then debug more easily from without undoing all of your good work.

How do i do this?

  1. Checkout your past commits until you find a point where things are working. Note down the number of this commit i.e. fe0a645.
  2. Checkout a commit later on where thing are broken. Note down the number of this commit i.e. 357d870.
  3. Now to start bisecting: Type in the terminal 'git bisect'.
  4. Tell Git about the 'good' and 'bad' commits you looked at in 1. and 2. : 
    $ git bisect good fe0a645
    $ git bisect bad 357d870
  5. Git will now look at all of the commits made between these two points and tell you something like: Bisecting: 221 revisions left to test after this (roughly 7 steps)
  6. find the middle and check out that commit or the closest if there's an even number i.e. it now stops at 78d0c8d.
  7. Reload the page and if things are working tell Git that its a good commit: $ git bisect good.
  8. Now it will bisect between new known good 78d0c8d and 357d870 and checkout the middle again.
  9. Reload the page to see if things are good or bad. If they are bad type: $ git bisect bad.
  10. Keep doing this via process of elimination. Once Git finds the first bad commit it will show you in the terminal the culprit. You can now fix the problem.
  11. Once you have fixed the problem and want to return to your actual branch HEAD type: $ git bisect reset.
  12. By default, this will return your tree to the commit that was checked out before $ git bisect start. With an optional argument, you can return to a different commit instead: $ git bisect reset <commit>.

There are other commands you can use with bisect but this little tip should help you debug more quickly.