Git Bisect

Working as a software engineer, a lot of time is spent fixing bugs. Some of these bugs are regressions which means that something which used to work doesn't anymore. When working with a large code base it's often difficult to pinpoint what exactly triggered the regression. It sometimes can be something that at first glance is completely unrelated. When this happens, a technique to determine which commit triggered the regression is to try out every commit until you hit the one that caused the regression. This can be optimized by using dichotomy to ⌊log2(n)⌋ where n is the number of commits between the version where it worked (good) and where it doesn't (bad).

When using git; dichotomy can be done for you. The command is git bisect. But when using plain git bisect you still have to manually tell git if the current version is good or bad. That is unless you have a scripted way to telling if the current version is good or bad. In our case this will be a Maven test. I used this when working on CAMEL-12613.

First of you have to write a script (bash in our case) that outputs 0 if the code is good (doesn't contain the bug) and any number between 1 and 127 if the code is bad (contains the bug). A special return value of 125 can be used to tell git that the current version isn't testable. This can be VERY useful as some commits may have broken the build thus preventing you from running your test. This is the script used in our case:

All this script does is execute a Maven test called FileConsumerPreMoveLastModifiedTest and does some cleaning due to generated files. Once you have this script, you're ready to go! Here's the sample work flow I used:



There are two commands used here: git bisect start HEAD camel-2.17.0, which starts git bisect by telling the HEAD revision is bad and camel-2.17.0 is good; and git bisect run ./git-run.sh which tells git to use a script called git-run.sh (see above) to know if a revision is good or bad. And voilĂ ! Enjoy the free coffee break ;)

Comments

Popular Posts