Video

Want to see the full-length video right now for free?

Notes

Git is all about tracking the history of the files in our project. As a result, one most important skills we can gain when working with Git is efficiently moving through our repository's history, and finding changes within that history.

In this video, we'll cover a number of different ways to view the git log, to search through that history, and to even find particular changes by the code they change.

Decorated Git Log

The default Git log, viewed by running git log, is useful but not necessarily optimized for day-to-day reviewing of history. Instead, we can view a subset of the information displayed in each commit, and bring in additional context about the branches to add to the usefulness of the git log.

The command we'll use a number of options to the log command to alter display. All together they are:

$ git log --oneline --decorate --graph --all -30

Let's break this down:

Option Description
oneline Only display abbreviated commit hash and commit message subject
decorate Display the local and remote branches along with the commit hash
graph Draw the commits with ASCII art lines to identify branching
all Show the history of all branches, not just the current branch
<number> Show only the specified number of commits, rather than paging through all commits

While the above provides a nicely organized and concise view of the log, it is a bit of a handful to type out. Instead, we can configure an alias in Git to minimize typing.

We'll cover aliases and general Git configuration in detail in a later video, but for now we can simply run the following in our terminal:

$ git config --global alias.sla 'log --oneline --decorate --graph --all'

This creates an alias, sla (stands for "short log all") which wraps up all of those options. Now, anytime we want to see our log in that format we can simply run

$ git sla

Custom Log Format

In some cases, we might want to see a slightly different form of the log output. On smaller projects we may not be concerned about the commit date and author detail, but on larger more distributed projects, this info may be critical.

Luckily, we can provide a customized output format for Git to use.

Say we want to include the date and author, in addition to the commit hash and commit message subject. We can use the following form of the git log command to format our output:

$ git log --pretty=format:'%h - %an [%ar] %s'

Here we're using Git log's --pretty option, specifying a particular format string. The format string uses placeholders:

Placeholder Value
%h Abbreviated commit hash
%an Author name
%ar Commit authored on date, relative (e.g. "3 days ago")
%s Commit subject (first line of the commit message)

In addition, we can spruce this up by adding a little color. Colors are specified with %C(<color-name>), with %C(reset) resetting the color. In the following, we color the commit hash yellow and the date green:

$ git log --pretty=format:'%C(yellow)%h%C(reset) - %an [%C(green)%ar%C(reset)] %s'

Note, the above is just an example. Git supports an impressive collection of placeholders and formatting options for customized logs. To see more of the available formatting specifiers, run git help log and search (using / in your pager) for the "PRETTY FORMATS" section, specifically the "format:<string>" section.

Searching the Logs by Commit Message

While the log formats shown above are great for browsing our history and finding recent changes based on the author or commit message text, occasionally we'll need to go deeper into the history looking for changes related to specific parts of our application.

For these cases, we can use the grep option to the git log command to search through commit messages and list only those that match our search pattern.

As an example, we once had a caching problem on the forum, and using the following log --grep command, we were able to track down the relevant commit.

$ git log --grep -E -i 'cach(e|ing)'

This searched the commit logs for all commits with any form of "cache" or "caching" in the commit message. Breaking down the specific options, we have:

Option Description
--grep Search (grep) the log for the specified string or pattern
-E Use "extended regular expressions" when interpreting the search pattern
-i Search case insensitively

As with our git sla example above, this is perhaps more than we want to have to remember and type, so instead we can save this under the alias "glog", standing for "grep log", using the following command:

$ git config --global alias.glog 'log -E -i --grep'

With that in place, we can now easily perform our case-insensitive, extended regex search our Git log for all things caching with:

$ git glog 'cach(e|ing)'

Note: this is yet another great reason to write good commit messages.

Searching the Logs by Code Change

Our new glog alias is great for cases where we know the commit message will mention a particular term, but in some cases we actually need to search the code, rather than the commit message.

Luckily, git log supports another flag, -S that allows us to search for changes related to particular strings in our code base. Specifically, per the documentation, the -S flag instructs Git to:

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

For instance, we can run the following to search for any time we added or removed a call to with_active_subscription method.

$ git log -S with_active_subscription

For more detail on this type of log searching, check out the great [Code Sleuthing with Git][] post on our blog.

[Code Sleuthing with Git]: https://robots.thoughtbot.com/code-sleuthing-with-git

File Specific Git Log

In some cases, we may want to see the changes to a single file to understand that file's unique history. Taking for instance the Gemfile of the Upcase project, we can run the following to see the log for every change that modified the Gemfile:

$ git log --oneline -- Gemfile

Git Blame

Similar to seeing the log of all changes to a file, we can instead use the git blame command to see the most recent commit that modified a given line, for every line in the file.

$ git blame Gemfile

Git Show

In all of the above examples, we use various forms of git log and git blame to track down commits. Once we've found a commit of interest, we can use the git show command to display the commit info and a diff of the changes the commit introduced.

$ git show 770b1ab6

Conclusion

In this section, we've introduced a wide array of commands we can use to review Git's history and track down specific changes.

Each command has a unique use case where it really shines, so it's good to be aware of the different approaches available.

Hopefully this video has armed you with all the tools you need for the next time you need go spelunking in your repository's history.