Want to see the full-length video right now for free?
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.
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
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.
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.
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
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
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
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
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.