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?
- Checkout your past commits until you find a point where things are working. Note down the number of this commit i.e. fe0a645.
- Checkout a commit later on where thing are broken. Note down the number of this commit i.e. 357d870.
- Now to start bisecting: Type in the terminal 'git bisect'.
- Tell Git about the 'good' and 'bad' commits you looked at in 1. and 2. :
$ git bisect good fe0a645
$ git bisect bad 357d870
- 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)
- find the middle and check out that commit or the closest if there's an even number i.e. it now stops at 78d0c8d.
- Reload the page and if things are working tell Git that its a good commit: $ git bisect good.
- Now it will bisect between new known good 78d0c8d and 357d870 and checkout the middle again.
- Reload the page to see if things are good or bad. If they are bad type: $ git bisect bad.
- 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.
- Once you have fixed the problem and want to return to your actual branch HEAD type: $ git bisect reset.
- 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.