Quick Links

Tracking down when and where lines of code were added to your codebase can be a headache, but Git stores all changelogs, and does have some tools for searching through commit diffs. You can use them to find lines matching a given search string.

Using Git Log

Unfortunately sites like GitHub don't offer this functionality, so you'll have to use 

        git log
    

. This command has a lot of parameters, including being able to search through commit diffs, but dealing with the output is a little unwieldy.

In any case, Git's interactive pager display is pretty clunky for many people, so we recommend either searching in the command bar with

        /Search
    

, or piping the output directly to the console with 

        | cat
    

, or to a file with

        > log.txt
    

, where it can be searched more effectively.

Running this kind of search on a whole repository will probably generate very large output. You likely want to see commits in a given time range, which you can do with

        --after
    

 and

        --before
    

, which take dates as well as relative dates like "2 week" and "3 month." The following command ignores commits older than a month and a half, and also ignores very recent commits.

git log --after="6 week" --before="1 week"

If you simply want to know which commits contain a given search string, you can use -S, which requires you to put the search string right after it with no whitespace.

git log --after="6 week" -S'Dictionary' --stat

If you'd like to view the files with this output, you can use the -p flag:

git log --after="6 week" -S'Dictionary' --stat -p | cat

However, this output is massive for any large query, and isn't much different from just opening it in your IDE. To solve that, we'll need to use grep and sed, which means the commands are unfortunately going to get complicated.

Using sed For Smarter Matching

To match and print the actual lines in the file, you'll need to use grep, piping the output to it to print the lines that it found the pattern on. This requires you to type the pattern twice:

git log --after="6 week" -S'Dictionary' --stat -p | grep 'Dictionary'

However, this has a problem---it's not longer including the commit messages or IDs. To fix this, we have to break out sed:

SEARCH=Dictionary && git log --after="6 week" -S$SEARCH --stat -p | sed -n "/commit/,/diff/p; /$SEARCH/p"

This command sets a SEARCH variable, since typing the search term twice is cumbersome. It runs git log --stat -p, which prints the full output, but it's passed to sed for parsing. sed matches all lines between "commit" and "diff," which grabs the --stat header output. Then, it appends the line that it matched, producing actual usable output.

Maybe Use Git Blame Instead

The examples above work well for searching through an entire codebase. But, if you know what file is effected, and instead just want to understand the history of it, you might want to use git blame.

Git-blame will print out the entire file, but annotate each line with the person who last modified it. This will let you quickly track down changes, and, in many cases, put the blame on your coworkers.

You can use the git blame command, but GitHub has a great GUI for it, available by clicking the file in question and pressing "Blame."

Note that you can also view the chronological history of the file from the same interface; Git blame condenses it all to a single output.