Debugging with git
Git can be used for code archaeology and debugging. We will only look at two commands in some details:
git blame
help you annotate a file with which commit changed what line and even if a line was copiedgit bisect
will 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.
-M
detects moved and copied lines inside a file within a commit-C
detects 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.