Debugging With Git Bisect¶
NOTE: using bash/git commands is not fully supported on jupyterlite yet (due to single thread/process restriction), and the cells below might error out on the browser (jupyterlite) version of this notebook
You can use
git bisect
to find out which commit caused a bug.
An example repository¶
In a nice open source example, I found an arbitrary exemplar on github
import os
top_dir = os.getcwd()
git_dir = os.path.join(top_dir, 'learning_git')
os.chdir(git_dir)
%%bash
rm -rf bisectdemo
git clone https://github.com/UCL-ARC-RSEing-with-Python/bisectdemo.git
bisect_dir=os.path.join(git_dir,'bisectdemo')
os.chdir(bisect_dir)
%%bash
python squares.py 2 # 4
This has been set up to break itself at a random commit, and leave you to use bisect to work out where it has broken:
%%bash
./breakme.sh > break_output
Which will make a bunch of commits, of which one is broken, and leave you in the broken final state
%%bash
python squares.py 2 # Error message
Bisecting manually¶
%%bash
git bisect start
git bisect bad # We know the current state is broken
git switch main
git bisect good # We know the main branch state is OK
Bisect needs one known good and one known bad commit to get started
Solving Manually¶
python squares.py 2 # 4
git bisect good
python squares.py 2 # 4
git bisect good
python squares.py 2 # 4
git bisect good
python squares.py 2 # Crash
git bisect bad
python squares.py 2 # Crash
git bisect bad
python squares.py 2 # Crash
git bisect bad
python squares.py 2 #Crash
git bisect bad
python squares.py 2 # 4
git bisect good
python squares.py 2 # 4
git bisect good
python squares.py 2 # 4
git bisect good
And eventually:
git bisect good
Bisecting: 0 revisions left to test after this (roughly 0 steps)
python squares.py 2
4
git bisect good
2777975a2334c2396ccb9faf98ab149824ec465b is the first bad commit
commit 2777975a2334c2396ccb9faf98ab149824ec465b
Author: Shawn Siefkas <shawn.siefkas@meredith.com>
Date: Thu Nov 14 09:23:55 2013 -0600
Breaking argument type
Stop the bisect process with:
git bisect reset
Solving automatically¶
If we have an appropriate unit test, we can do all this automatically:
(NOTE: You don't need to redirect the stderr
and stdout
(with &>
) of git bisect run
to a file when running these commands outside a jupyter notebook (i.e., on a shell). This is done here so the errors appears with the right commits)
%%bash
git bisect start
git bisect bad HEAD # We know the current state is broken
git bisect good main # We know main is good
git bisect run python squares.py 2 &> gitbisect.out
cat gitbisect.out
Boom!