Debugging Code You Don't Know With Only Git
Someone discovered a bug in legacy code that no one wants to touch. No one knows when the bug was introduced, and most wouldn’t know how to fix it without introducing new bugs. How do you handle this?
I start a watch
or some rebuild tool to preview the effect of
every source change. Rebuilds don’t have to be quick if you are
patient enough.
Next, run git bisect
to find the commit where the bug was introduced. Write down the name
of the person on the commit it shows you. On the bad commit, run
git diff HEAD HEAD^ | git apply -
to sets the working changes to
the version of code before the bug was introduced.
From here, run git checkout -p
to bring up an interactive prompt
for each hunk, which are smaller changes within a source
file. In this context, checking out a hunk means reintroducing
code that may cause the bug. If a lead doesn’t pan out, checkout
everything and run the diff
/apply
again. Check out the hunks
that you suspect cause the bug, quit the prompt to write the changes,
then see if you reproduced the bug. If you did, propose a fix to the
noted committer (or their replacement). Ask them “Will doing this have
side-effects we’re not anticipating?” Get a second opinion if you
aren’t satisfied with the answer. Write all opinions down and place
them where your team can see before changing anything.
This is not a totally clean process because some hunks must be checked out together. You’ll have to consider dependencies and new function parameters. You’ll have to know enough about code structure to make sure all bindings are correct. What you get out of this work is a mechanical form of debugging that does not require you to understand the code to find a root or proximate cause.
This method works regardless of language or code quality.