Code Sleuthing with Git

Ian C. Anderson

Let’s say you want to delete a method foo that seems to be dead code. You use a tool like grep to find callers of foo, and there are no results. It’s tempting to consider foo to be unused at this point, but you want to know the story of this method so you can be confident in removing it. Why did this method ever exist?

Search your commits

From the git-log docs:

-S <string>
    Look for differences that change the number of occurrences of the specified string (i.e. addition/deletion) in a file.

Git will spit out all of the commits that either deleted or added the given string (e.g. calls to a method). Unlike git log --grep, git log -S actually searches the code in the repo, not the commit messages.

$ git log -S foo

    commit 8f19a1fa0...
    Author: Ian C. Anderson
    Date:   Fri Mar 27 21:44:17 2015 -0500

        stop using the foo method because eww

    commit 216895189...
    Author: Ian C. Anderson
    Date:   Thu Mar 6 21:09:44 1999 -0500

        new foo method - so great!

Search your commits by regex

-G <regex>
    Look for differences whose patch text contains added/removed lines that match <regex>.

This -G option becomes handy when you’re looking for a pattern instead of a literal string.

Consider a bar method that has 1 argument with a default value, but none of the current calls to bar use the default value. Let’s use -G to look for past usages of bar that did use the default value (by looking for the string bar without a following parenthesis).

$ git log -G "bar[^(]"

    commit 8f19a1fa1...
    Author: Ian C. Anderson
    Date:   Fri Mar 27 21:44:17 2015 -0500

        remove custom args to bar method

    commit 216895180...
    Author: Ian C. Anderson
    Date:   Thu Mar 6 21:09:44 1999 -0500

        new bar method

We now see all of the commits that added or removed a line matching our pattern.

These two commands have become indispensable tools for me, especially when navigating and refactoring large and/or legacy codebases.

For a thorough guide to practical Git techniques, check out thoughtbot’s Goal-Oriented Git book, written by developer George Brocklehurst.

For a convenient and productive way to run git commands in the terminal, give gitsh a try.