Debugging with git
Git can be used for code archaeology and debugging. We will only look at two commands in some details:
git blamehelp you annotate a file with which commit changed what line and even if a line was copiedgit bisectwill help you to find a commit which introduced a bug
Git blame
A standard git blame annotates every line in a file with the
abbreviate commit hash, the commit author and time it was changed. There
are a lot of command switches to experiment with, use
man git blame to get an overview. We want to look into two
of them.
$ git blame filename
8e04d7e0 (Hans 2025-06-22 12:07:49 +0200 1) Line 1
8e04d7e0 (Hans 2025-06-22 12:07:49 +0200 2) Line 2
Finding out from where a line came from
When we refactor code we often move lines between files or inside those files. There are two switches which can help us identify those lines.
-Mdetects moved and copied lines inside a file within a commit-Cdetects also moved and copied lines from other files within a commit
Both have a cut-off of 20 chars. Only if at least 20 chars are moved
the will detect it. The cut-off can be changed by supplying a number
after the switch, e.g. -C5 will reduce it to 5.
$ git blame -C5 filename
8e04d7e0 file2.txt (Hans 2025-06-22 12:07:49 +0200 1) Line 1
^1b75ab3 file1.txt (maschmi 2025-06-22 12:07:49 +0200 2) Line 2
As we can see, Line 2 is coming from
file1.txt and was introduced in commit
^1b75ab3.
Git bisect
If you create small, logical and atomically commits
git bisect can go a long way in hunting down a change which
introduced unwanted behavior. git bisect needs to have a
commit range defined, where one commit is bad, the other one is good.
Then it will perform a binary search and asking you every time if the
current commit is good or bad. After you are finished you need to end
the bisect with git bisect reset. If you have a possibility
to test fast if the commit is good or bad this goes a long way in
hunting down issues. Sometimes, you may find the issue in a commit you
never thought of looking into as the commit message put you on the wrong
track.
The methodology is as follow:
# start the bisect
$ git bisect start
# mark the current commit as bad
$ git bisect bad
# mark another commit as good
$ git bisect good commitHash
# loop from here untill you found the commit
# run your test, decide if it is good or bad
# if the test was good
$ git bisect good
# if the test was bad
$ git bisect bad
# end loop
# if you are finished, exit bisect mode
$ git bisect reset
Exercises
There is a prepared exercise for both commands available: Debugging Exercise.