When deploying new features to a production environment, risks of regression exist. Especially in big applications with a lot of untested code. We are never safe from negative behaviour, or impacts that need our immediate attention.
In a project using Git as a source code management tool, it appears essential to rapidly find the source of our problem. When dealing with large teams composed of many people, every deployment comes with a lot of commits. But if the origin of the problem is hidden in the middle of all those commits, it is quite complicated to check every commit for the source of the issue.
Git is a very famous tool in software development, and it comes with a bunch of commands that prevent us from missing good old SVN. Today I’d like to talk about a tool that will allow us to rapidly isolate an incorrect commit, that caused a bug in our application: :
To simplify my explanation of
git bisect, I’m going to use the following history of commits:
* bad5bfe - fixed security issue (1 hour ago) <Wilson Bouncer> * a73d98b - implemented feature to get recipe in space kitchen (8 hours ago) <Wilson Cook> * 9bd6395 - updated metrics computation on space launcher (13 hours ago) <Wilson Analyst> * 99f3fa1 - worked on real-time suggestion when encounting problems in space (1 day ago) <Wilson Scientist> * 4021b7f - deleted ab test feature and cleaned up code (1 day ago) <Wilson Cleaner> * 0d7c223 - computed the ideal playlist based upon astronauts tastes (2 days ago) <Wilson DJ> * 29d90f9 - updated README.md (2 days ago) <Wilson Documentation>
Imagine that those commits have been deployed to production. After a few moments, someone notices that something’s wrong. One of the functionalities is broken. The problem is immediately brought to developers and they have to isolate the cause of the bug. They only have one clue: everything was fine before the last deployment.
Git takes away the boredom of testing our commits one by one with
git bisect. This command does a binary search in our history.
At every step of the binary search, we must tell
git bisect if the issue still persists. According to our response,
bisect will go forward or backward to isolate the issue.
There are two main commands with
git bisect :
git bisect good: this allows us to say that the commit which
bisectstopped us on does not contain the bug.
git bisect bad: this allows us to say that the bug still exists on the commit we’re on.
Before we begin debugging, we must start the script, and indicate the interval on which we’re going to use
git bisect start git bisect good 29d90f9 git bisect bad bad5bfe
Once this is done, we can notice that
bisect changed our position in the commits history to the middle of our interval.
Bisecting: 2 revisions left to test after this (roughly 2 steps) [99f3fa1b86489dd9d6f30368d5b5321e04a955df] worked on real-time suggestion when encounting problems in space
Now, we must check if the bug is still here. Unfortunately yes in this case! Keep on “bisecting”.
git bisect bad
We’re now on the middle of our last interval (binary search)
Bisecting: 0 revisions left to test after this (roughly 1 step) [4021b7f911b84daa6ea5ccad51d3171fc0e46b67] deleted ab test feature and cleaned up code
Notice that the number of steps left in the search is indicated:
roughly 1 step. We still have the bug on this commit:
git bisect bad
We’re getting closer!
Bisecting: 0 revisions left to test after this (roughly 0 steps) [0d7c223dcfee62e1750e21385e7fa35b030bc8a7] computed the ideal playlist based upon astronauts taste
On this commit, our problem is gone! Yay! Let’s tell it to
git bisect good
git bisect has reached the end of its search. He has found the culprit:
4021b7f911b84daa6ea5ccad51d3171fc0e46b67 is the first bad commit commit 4021b7f911b84daa6ea5ccad51d3171fc0e46b67 Author: Wilson Cleaner <firstname.lastname@example.org> Date: Tue Oct 17 16:56:06 2017 +0200 deleted ab test feature and cleaned up code :100644 100644 66f0d114adeee6d2141aa6fe64a5cc431ebce65e a0fe62c949a75957245ec1c04728fea047488697 M README.md
To reinitialize nothing more simple:
git bisect reset
We’re now where we began, but we have found the evil commit that tormented the whole team, all of this quite rapidly.
bisect command allows you to automate the search process. Indeed, if you have the luxury of adding a test that highlights the bug, you can launch git bisect as follow:
git bisect run vendor/bin/phpunit --filter ThatWontHappenAgainISwearTest
vendor/bin/phpunit --filter ThatWontHappenAgainISwearTest will be launched at every step seen before, and you’ll automatically have the hash of the commit you’re looking for.
The use of
git bisect allows us to rapidly debug by isolating a bad commit with a binary search. Just indicate
git bisect good or
git bisect bad so that
bisect can navigate through your history.