git bisect can make you save eons when you are looking in your
git history to find the exact revision that created a problem. This is a quick
A lot inspired from
git bisect will make your day - I
am writing this article because it did make my day!
The example project
Let’s do a bit of work together.
mkdir demo-git-bisect cd demo-git-bisect git init echo 'Yeah, we created a new git repository!' > notes.md git add notes.md git commit -m 'First commit' echo '' >> notes.md echo 'A cool title' >> notes.md echo '======' >> notes.md git commit -a -m 'Add a cool title'
Now we have a repository with a couple commits.
echo 'my_add = lambda x, y: x + y' > addScript.py git add addScript.py git commit -m 'Add an addition script' echo 'from addScript import my_add' > addScript_test.py echo '' >> addScript_test.py echo '' >> addScript_test.py echo 'assert(my_add(1, 1) == 2)' >> addScript_test.py git add addScript_test.py git commit -m 'Add test for our addition script'
We now have a working
my_add addition function, and we can test if it works
All is fine in the world… The project goes on.
echo '' >> notes.md echo 'We now have an addition function.' >> notes.md git commit -a -m 'Add some documentation' echo 'Just call my_add() to add things' >> notes.md git commit -a -m 'Add some moar documentation' echo 'my_add = lambda x, y: x * y' > addScript.py git commit -a -m 'Update my_add function' echo '' >> notes.md echo '' >> notes.md echo 'To be implemented: my_div and my_mult' >> notes.md git commit -a -m 'Add some ambition'
Now if we call
python addScript_test.py we will see that the test is
Here we only have a handful of commits, but in a real project we can have a lot more and finding the last working version that will highlight us the changes that have cause the problem. Which can be a real help.
Fortunately we have a test here otherwise we could simply add one.
First we are going to create a script to test if the current version is working, with that script:
- We can install dependencies if they change between versions.
- We can restore some specific version of our testing script (for example if we had to extend it to highlight our bug).
- We must make sure that the script last call returns 0 if everything is fine and something else otherwise.
echo '#!/bin/bash' > test_current.sh echo '' >> test_current.sh echo 'echo "* (optional) Installing dependencies"' >> test_current.sh echo 'echo "* (optional) cp-ing some old test script"' >> test_current.sh echo 'echo "* Calling the script"' >> test_current.sh echo 'python3 addScript_test.py' >> test_current.sh
git bisect actually runs a binary search in a commit history in order to
identify a culprit revision. More information on
So, one last thing. After we start, we need to mark good and bad commits so
git bisect knows between which commits it should look.
git bisect start # current revision does not work git bisect bad # Four revisions ago is when we added the test (HEAD~4), we know it worked git bisect good HEAD~4
Then we can just tell
git bisect to use our script to find the breaking
git bisect sh test_current.sh
And tadddaaaaaaaahhhhh, we are know at the breaking revision. We can visualize the changes which are very likely to have caused the problem:
git diff HEAD HEAD^
We can now finish our errand:
git bisect reset