If you are a software developer or studying computer science or another IT subject, you probably have heard and used git. It is great and powerful version control software.
Great! But have you also used git bisect ?
Imagine you have a big git repository and there is a bug in the latest version of your software. Even worse, its a regression. Meaning you know that thing used to work in the past, but now its broken. Who introduced this bug? When? What broke the function?
You could test every single commit between the good one and the broken. But what if there are hundreds or thousands?
It would be much more efficient to jump exactly in the middle of the history between the broken and good commit, test that, then jump in the middle between the youngest good and the oldest bad commit and, so on.,
- on the right side are the newer commits on the left the older ones
- arrows indicate which commit to test
- red-diamond are the commits you have tested and found to be broken
- blue-squares are the commits you have tested and found to be good
(BTW. I’m using shapes and colours to help colour-blind people like me, there are more of us than you think. Please make our lives easier: https://en.wikipedia.org/wiki/Color_blindness )
Guess what, that is exactly what
git bisect is doing for you!
Checkout the point of your repo that has the bug, then start the bisecting with
git bisect start
Tell git that this is a bad commit:
git bisect bad
Then tell git any commit that you know did not have the bug:
git bisect good <git reference>
The git reference can be a tag-name, a commit id or any other valid reference.
Git bisect will checkout the next commit to test, test it and if its the one that does not have the bug tell git so:
git bisect good
If it is already broken do:
git bisect bad
Git will take you to the next commit to test, tell it again if its good or bad, and so on till you get a message like:
f53a8b766190143ea80658170730791ada4db56b is the first bad commit
You’ve made it! This is the commit that introduced the bug!
Simple hey! Only thing left to do is
git bisect reset to get you back to the point you have started at, fix the bug, and of course add tests so that the regression is not gonna happen again!
So that is all fine, but what if you have to compile your software every time you want to test it and its a huge code base? Maybe it takes you an hour or two to compile every time you want to test a commit. Even with bisect it will take you ages to find the right commit.
Ask LibreOffice developers, they have that problem, but they also found a solution: do the compilation work in advance.
- compile every commit of your software
- save the compiled version in a separate git repo
git bisectto jump between the compiled commits and find the commit that introduced a bug
You might think: “it will be a huge repo”. True, but not as huge as you might think, there is still the advantage of de-duplication in git
“It will take a exponential time to compile every commit” - Use CI! Automate the stuff!
Read more about what and how LibreOffice is doing and try it by bibisecting a bug in LibreOffice: https://wiki.documentfoundation.org/QA/Bibisect
And watch Matthew Francis's talk about bisect and bibisect https://www.youtube.com/watch?v=WLmEfvjVN7s