Finding Everything in Git

1521

In previous articles about the Git version control system, I provided a Git cheat sheet and showed how to fix mistakes in Git. In this article, however, I will show how to mine your Git log to find information on everything that happened in your repository: what happened, who did it, and when.

Git Log Tells All

You can run the git log command to see a complete commit history for your repository, from most recent to oldest. Run it with no options as shown here to display the commit hash, author, date, and comment.

$ git log

commit baffcc6389f4499624f51dce3fe59864d0
Author: Dev Loper <devlop@example.com>
Date:   Fri Apr 15 12:46:47 2016 +0200

   Fix loading the storage autoloader

commit cc034cd893752f23f6e51b8fdd6425bd11e
Author: Co Derr <coderr@example.com>
Date:   Fri Apr 15 12:01:13 2016 +0200

   Move apitranslate to apiversiontranslate

The git log –state command adds a list of changed files to the git log output:

lib/private/version.php   | 382 +++
lib/private/checkhttp.php | 753 +++++++
lib/private/username.php  |  62 +++++++
lib/private/htaccess.php  | 382 -----------
lib/private/apicheck.php  | 753 --------------
lib/private/errortext.php |  62 -------
6 files changed, 1197 insertions(+), 1197 deletions(-)

You can view all details of a single commit. This displays everything: date, committer, diff, and entire content of the commit.

$ git show baffcc63

Using git log –no-merges streamlines output by displaying only commits, and not merges. You can view only merges with git log –merges, and see who made the merges with git log –merges –author.

You can also view the diffs of the commits with the -p (patch) option:

$ git log -p

commit faf693af499797735b9a6309d520fbf3fc90b268
Author: Com Mitter <committer@example.com>
Date:   Fri Apr 15 12:04:45 2016 -0700

   link to file.html
   
   describes configuration settings and examples for last three versions

diff --git a/config.file b/config.file
index c2671f9..86dffa2 100644
--- a/config.file
+++ b/config.file
@@ -430,14 +430,14 @@ $CONFIG = array(

You can limit the number of commits displayed, for example, diff only the most recent five commits with git log -p -5.

There is a graph view, which can be rather fun to trace on complex projects.

$ git log --graph
| |     
* |   commit 03fea9e18d613f844c111e6cbe03ad7f3b7
|   Merge: 2fdd888 174af8e
| | | Author: donym <donym@example.com>
| | | Date:   Thu Feb 4 11:33:01 2016 -0800
| | | 
| | |     Merge pull request #133 from repo/libs
| | |     
| | |     corrections to public api

View commits by name with git log –committer=carla and git log –author=carla. Substituting your own name, of course, or the name of anyone on the project. You may search for commits on a specific file:

$ git log -- path/tofile

Searching in Date Ranges

Add a date range to your search; this is a great tool for fine-tuning your searches:

$ git log --graph --author=carla --after="2015-06-15" /
 --before="2016-07-15" --no-merges -- path/tofile

You may use –after= and –before= by themselves.

Use the –oneline= option to create a streamlined summary of your commits in a time period. This makes a nice report to give your boss when he’s grumping how he never knows what you’re doing:

$ git log --author="layla" --after="1 week ago" --oneline
54ccc4e corrections to public api
40774df Update user README
5146605 Update dev docs
a833ee3 Revert "advance version number"
ff2247c Merge pull request #351 from eagle/backport_235
fa0ffa4 clarify temp storage location

File Histories

You can also display a simplified history of a file:

$ git log -- path/tofile

Or, see all commits on a file, including renames:

$ git log --follow -- path/tofile

The Blame Game

Using git blame — path/tofile outputs a history of everyone who made commits on the file, with the date and changes. You can even narrow your search to a range of lines in the file:

$ git blame  -L 5,15 -- path/tofile

Finding Content in Files

Suppose you want to hunt down everything related to the word “http”. You can do this in Git with git grep. It works just like plain grep, as in this case-insensitive search for http:

$ git grep -i http

Just like grep, this outputs a list of files and quotes the line your search term is found in. You can limit the results to filenames only with the -l option:

$ git grep -l http

Or, you can add the line number to the output with -n:

$ git grep -in http

You can search for a specific code snippet. This example looks for anything pertaining to “Apache”, and displays single-line commit summaries:

$ git log --oneline -S'Apache'
a7b2056 corrections to htaccess
5b05e61 add warning to use only Apache 2.4
d539643 list Apache module dependencies
f0b2428 list supported HTTP servers

Of course, Git offers much more functionality than I’ve covered here. I recommend you look at git-log – Show commit logs and 2.3 Git Basics – Viewing the Commit History to learn more.

And, remember, to save time and headaches, always consult the official Git documentation first.