On 5th Feb, I attended DDD North. There were many excellent talks on the day, but in this post, I’m delving into something that I saw in one of the grok talks (I gave one myself). It concerns a feature of git that I’d never heard about until then, and it’s proved to be enormously useful. This post is, as all of my posts are, really for myself.
Something has broken
You’re giving the app a quick test, and suddenly you realise that something in the application has stopped working (or maybe it’s started, but it shouldn’t have). You remember that two days ago, this particular thing was working fine. This post is going to cover manually using git bisect to determine when your code was broken.
Get the good commit
To use git bisect, you need a good commit and a bad commit. Obviously, git doesn’t know what’s good or bad, so you could use it to determine when something was changed, added, or removed. Providing the behaviour is different, you can identify it.
If you know the date of the ‘good’ commit, you can ask git for the logs after that date. To list commits after a given date:
git log --after="2019-03-19T00:00:00-00:00"
This will give you all the commits (you can add a ‘—before’, too if you’re dealing with a long time ago. When you get the git Commit Id, make a note of it; for example:
Bc1afa359dc98b899cc4194ec8130a6229643172
Let’s do some bisecting
You start the bisect process by:
git bisect start
At all times through this process, git does precisely nothing to help you along, so if you even get an acknowledgement of your command you should consider yourself lucky!
The next step is to tell git that the current release is bad:
git bisect bad
You can give it a commit here that isn’t the current release, if you so choose.
The final step to start the process is to tell it where to start - i.e. what was the last known good release. This is your commit Id from earlier:
git bisect good Bc1afa359dc98b899cc4194ec8130a6229643172
What git does here is a binary chop. So the first code it will check out will be halfway between the two commits. It then tells you nothing (as usual). Now that it’s checked out the code for you, run your application with the code and see whether it is ‘good’ or ‘bad’. Once you’ve determined that, go back to git and tell it:
git bisect good
Or:
git bisect bad
Each time you tell it it’s good or bad, it will check out new code, and you need to test again:
(apologies for all the redacting)
Finally, it will determine which commit was the first bad one, and report back:
$ git bisect bad
Eea8e3d72fcb26cdebb2dbf2c13fdd88d7f3782a is the first bad commit
commit Eea8e3d72fcb26cdebb2dbf2c13fdd88d7f3782a
Author: Ian Kilmister <[email protected]>
Date: Wed Mar 20 11:49:18 2019 +0100
New lyrics
Once you’re done, you need to reset - this will book out the code you had out before you started:
git bisect reset