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
--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
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
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
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 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.