Git is a powerful tool. Once you’ve mastered
merge, there are endless possibilities. A very useful one is
git-bisect. It helps you find a commit that introduced a certain change in behavior.
When you find a regression, something broken that used to work, use
git-bisect to find the commit that broke it. Mark the current commit as
bad and mark an old commit, where that feature still worked, as
Git-bisect will then bisect all the changes between those two commits with a binary search. At every step, you are asked to mark the commit as
bisect finds the first bad commit.
git bisect start
npm test # Double check that this commit is broken.
git bisect bad
git log --oneline # Find the hash of a good commit.
git checkout 7425633 # Checkout that good commit.
npm test # Double check that everything was green.
git bisect good
Bisect uses binary search, so the range decreases exponentially. Every step cuts the range in half. If you
bisect twice as many commits, it takes one additional step on average — not twice as long. Thus bisecting large ranges of commits is fairly quick.
git-bisect a lot in the Node.js project. The Node.js project has good continuous integration but some bugs are only discovered after a release. With
git-bisect, it’s easy to find the bad commit.
If you want to try out
git-bisect, here is a demo repository. At some point, a bug was introduced as you can see by running
npx mocha test1.js. Can you find the bad commit?
Instead of testing each step manually, you can run
git-bisect with a script. It will use the script at each step and automatically mark the commit, until it finds the first bad commit.