Debugging With Git Bisect

Please open notebook rrsepython-s1r12.ipynb

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 git@github.com:shawnsi/bisectdemo.git

Cloning into ‘bisectdemo’…

bisect_dir=os.path.join(git_dir,'bisectdemo')
os.chdir(bisect_dir)
%%bash
python squares.py 2 # 4

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

error: branch ‘buggy’ not found.

Switched to a new branch ‘buggy’

Which will make a bunch of commits, of which one is broken, and leave you in the broken final state

python squares.py 2 # Error message

File “", line 1 </span>

python squares.py 2 # Error message

^

SyntaxError: invalid syntax

Bisecting manually

%%bash
git bisect start
git bisect bad # We know the current state is broken
git checkout master
git bisect good # We know the master branch state is OK

Your branch is up-to-date with ‘origin/master’.

Bisecting: 500 revisions left to test after this (roughly 9 steps)

[f85561dbe54b69fc7f037e3fd1b742b7395726b5] Comment 500

Previous HEAD position was f85561d… Comment 500

Switched to branch ‘buggy’

Switched to branch ‘master’

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

git bisect end

Solving automatically

If we have an appropriate unit test, we can do all this automatically:

%%bash
git bisect start
git bisect bad HEAD # We know the current state is broken
git bisect good master # We know master is good
git bisect run python squares.py 2

Bisecting: 500 revisions left to test after this (roughly 9 steps)

[f85561dbe54b69fc7f037e3fd1b742b7395726b5] Comment 500

running python squares.py 2

4

Bisecting: 250 revisions left to test after this (roughly 8 steps)

[1842ee96db81d26ce5c00a4b8750bd19ec380bfc] Comment 749

running python squares.py 2

Bisecting: 124 revisions left to test after this (roughly 7 steps)

[749d1352b870cc169bc3c6e9e15c69d191a2a66e] Comment 625

running python squares.py 2

4

Bisecting: 62 revisions left to test after this (roughly 6 steps)

[150773712a2e9e8a371f33429abf9826d3a2b65e] Comment 687

running python squares.py 2

4

Bisecting: 31 revisions left to test after this (roughly 5 steps)

[0e12bcd2d685904abf22431381000c68ca0af230] Comment 717

running python squares.py 2

Bisecting: 15 revisions left to test after this (roughly 4 steps)

[cd59a9f75102f1b49863ad424fc35dc802522ccd] Comment 702

running python squares.py 2

4

Bisecting: 7 revisions left to test after this (roughly 3 steps)

[a105ae052d898733015676ac6709b1ffe88ed8bd] Comment 709

running python squares.py 2

Bisecting: 3 revisions left to test after this (roughly 2 steps)

[08508dd54091baa9e00c3599cb83cd0cda5b5837] Comment 706

running python squares.py 2

4

Bisecting: 1 revision left to test after this (roughly 1 step)

[7ced4763b6ab1600aab31d18fd2592186fd78b89] Comment 707

running python squares.py 2

Bisecting: 0 revisions left to test after this (roughly 0 steps)

[ebb3f4a5f4000c28bbc12d4d0187bbdad3d92241] Breaking argument type

running python squares.py 2

ebb3f4a5f4000c28bbc12d4d0187bbdad3d92241 is the first bad commit

commit ebb3f4a5f4000c28bbc12d4d0187bbdad3d92241

Author: Shawn Siefkas shawn.siefkas@meredith.com

Date: Thu Nov 14 09:23:55 2013 -0600

Breaking argument type

:100644 100644 430222f37d6aad3ba2b7f235991473e680c7e4d8 03bc808166ca5cd0a8cca51cfb522e0724a31bc6 M squares.py

bisect run success

Previous HEAD position was f85561d… Comment 500

Switched to branch ‘buggy’

Traceback (most recent call last):

File “squares.py”, line 9, in </span>

print(integer**2)

TypeError: unsupported operand type(s) for ** or pow(): ‘str’ and ‘int’

Traceback (most recent call last):

File “squares.py”, line 9, in </span>

print(integer**2)

TypeError: unsupported operand type(s) for ** or pow(): ‘str’ and ‘int’

Traceback (most recent call last):

File “squares.py”, line 9, in </span>

print(integer**2)

TypeError: unsupported operand type(s) for ** or pow(): ‘str’ and ‘int’

Traceback (most recent call last):

File “squares.py”, line 9, in </span> print(integer**2)

TypeError: unsupported operand type(s) for ** or pow(): ‘str’ and ‘int’

Traceback (most recent call last):

File “squares.py”, line 9, in </span>

print(integer**2)

TypeError: unsupported operand type(s) for ** or pow(): ‘str’ and ‘int’

Boom! Error identified.

Next: Exercise - Home-made SSH servers