git bisect : The awesomeness of git

We all have been in awe of git for some time now. Features like revert, rebase, diff, merge have been very useful and have solved almost all of our problems almost all the time. But imagine this! You and your team/community are working on different features for an application. You happily test a feature and say its ready to be pushed. But as all good team programmers do, you first rebase your repository with the latest changes in the master and try to test the feature again. Bam! It's broken. Now often in a large community/team there are already hundreds of commits in between. How do you find the commit that has broken your feature? You could browse through all the commit history and try to pin point which commit broke your feature and whom to curse. But it's not that easy always.

That's where git bisect come in. git bisect uses divide and conquer algorithm to find a broken commit among a large number of commits.It will allow you to find the breaking change in the fastest time possible.


Let's find the bad commit

First identify any known good commit and bad commit, where bad commit can be the very last commit in the history before your commit. Once you specify that to the git bisect, it will split the in-between commits in half, and checkout a new (nameless) branch in the middle commit to let you check if your future is broken at that point in time.

Let's say the middle commit still works. You would then let git know that via git bisect good command. Then you only have half of the commits left to test. Git would then split the remaining commits in half and into a new branch(again), letting you to test the feature again. git bisect will continue to narrow down your commits in a similar manner, until the first bad commit is found. Since you divide the number of commits by half on every iteration, you are able to find your bad commits in log(n) time (damn, that's fast).

The command process
  1. git bisect start – let git know to start bisecting.
  2. git bisect good {{some-commit-hash}} – let git know about a known good commit (i.e. last commit that you made before the vacation).
  3. git bisect bad {{some-commit-hash}} – let git know about a known bad commit (i.e. the HEAD of the master branch). git bisect bad HEAD (HEAD just means the last commit).
    At this point git would check out a middle commit, and let you know to run your tests.
  4. git bisect bad – let git know that the feature does not work in currently checked out commit.
  5. git bisect good – let git know that the feature does work in currently checked out commit.
    When the first bad commit is found, git would let you know. At this point git bisect is done.
  6. git bisect reset – returns you to the initial starting point of git bisect process, (i.e. the HEAD of the master branch).
  7. git bisect log – log the last git bisect that completed successfully.

Reference

Git Docs : http://git-scm.com/docs/git-bisect