One of the most fundamental services provided by Git is the project history. Since Git keeps track of all changes to files made within a repository, it can offer very powerful logging features. You can query a project’s history in many different ways and you can extract and display various data using one flexible command.
The git log command is huge, the biggest of any regular Git command. Its manual is over 2,500 lines long. Fortunately, git log provides much of its most useful behavior from just a few key options.
Basic Logging With the Default Behaviour
By default, git log shows a reverse-chronological list of commits. Each commit includes its hash, author, date, and commit message:
The command uses a pager (e.g. less, more) to show the full output so you can easily navigate the results. You can configure Git to use a program of your choice, such as the most pager.
Here’s some git log output from the repository of the git source code itself:
commit 670b81a890388c60b7032a4f5b879f2ece8c4558 (HEAD -> master, origin/next,
Author: Junio C Hamano <[email protected]>
Date: Mon Jun 14 13:23:28 2021 +0900
The second batch
Signed-off-by: Junio C Hamano <[email protected]>
The result starts with the commit hash (670…) followed by a list of branches that currently point at that commit (HEAD -> master, etc.)
The next line describes the author of this commit, giving their name and email address.
The full date and time of the commit follow on the next line.
Finally, the full contents of the commit message appears. You can control most of everything else that git log offers with command-line options. There are two main types of options:
- Formatting, which defines how Git displays each commit.
- Filtering, which defines which commits git log includes.
In addition to command-line options, git log accepts arguments that specify files, commits, branches, or other types of reference. These apply further filtering.
Formatting Git Log Output
One of the simplest adjustments is the –oneline option which produces a very brief output:
git log --oneline
Each line in the log now contains just an abbreviated commit hash and the subject of the commit message. This is an excellent way of getting an overview of recent commits to the project:
Unfortunately, with no other context, this information isn’t always that useful. It might give you a vague feel for the project, but it lacks dates and other useful information about authors and files.
Viewing a Branch Graph
The –graph option allows you to visualize relationships between branches. It’s very basic but can help untangle a complicated history.
git log --oneline --graph
Customized Pretty Output
You can achieve more complicated formatting by specifying it in detail using the –pretty option. The syntax goes from very simple to much more complex, so consult a manual for complete details.
git log --pretty=short
Is essentially the same as git log without the date or full message:
git log --pretty=oneline
Is equivalent to git log –oneline.
git log --pretty=fuller
Includes a lot of detail. It even separates author and committer who may, in theory, be different people:
With the format: variant, you can supply a string containing whatever content you want, including placeholders that are replaced by various data. Here are some example placeholders:
- %H commit hash
- %h abbreviated commit hash
- %ad author date
- %ar author date, relative
- %s commit message subject
- %b commit message body
- %p abbreviated parent hashes
You can add fixed characters to the output and colorize it. This example also shows a variation on date format:
git log --pretty=format:'%C(auto) %h [%ad] %s' --date=short
Note that brackets surround the date. Whatever formatting you choose, if you want the output to be useful in a pipeline or for other forms of text processing, you should consider how to demarcate each part of the output.
Showing Diffs in the Log
An important detail when looking at a repository’s history is the diffs themselves. They represent what’s actually changed in the code, after all! For starters, you can get a summary of changes alongside each commit using –shortstat:
git log --shortstat
This adds a line like:
1 file changed, 48 insertions(+), 2 deletions(-)
To the bottom of each commit. You’ll often see this kind of summary—throughout pages on GitHub, for example—and it’s a useful way of quickly judging the scope of a specific commit. For more detailed information, you can include full patch output (diffs) using the -p flag:
git log -p
Filtering Git Log Output
Whatever formatting you apply, you’ll still see the complete log of all commits in the current branch. Even though Git breaks them up into pages, it can still be a lot of output. The following options allow you to customize which commits the log includes.
Restricting by Amount
If you just want to trim the results to show the most recent few commits, use the -[number] syntax:
git log -2
Restricting by Date
To restrict the set of commits to a given date range, use the –since (–after) and –until (–before) options. These each take a date in ISO 8601 format. You can use either –since or –until on their own, or both together to specify a range. The options –after and –before are synonyms.
git log --since="2021-01-01" --until="2021-05-01"
Restricting by File
Git log can focus on a specific file rather than every file in your repository. This is great for helping you find out how a particular file has changed over time. Simply append the filename to the end of your git command:
git log filename
You’ll see only those commits that affected filename.
Differences Between Branches
You might have some unique requirements when viewing the log of a branch. For example, rather than see the entire history, you might just want to see what’s changed in that specific branch. Git log can help via the ref1..ref2 syntax. There are three slightly different approaches that you can use:
View commits that are in main, but not branch:
git log --oneline origin/branch..origin/main
View commits that are in branch, but not main:
git log --oneline origin/main..origin/branch
View commits that exist only in branch or main:
git log --oneline origin/branch...origin/main
Differences Between Two Tags
Just as you can view history between branches using the ref1..ref2 syntax, you can also view history between tags in the same way. After all, both tags and branches are types of reference.
git log --abbrev-commit --pretty=format:'%h %ar %s' v2.32.0-rc3..v2.32.0
If you’re preparing release notes for a larger project, git shortlog should be your first port of call. It produces a list of authors with commit subjects alongside them. You can pass it a reference range to limit the history in a similar way to git log:
git shortlog v2.32.0-rc3..v2.32.0
The git show command is even more versatile than git log. It can work with tags and other types of git objects beyond commit history. It shares many options with git log, but you’ll only really need it if you need to dig down into lower-level details.
Review the Past With Git Log
Git log is a complicated command, but you can get a lot of use from its most basic options. Browsing a repository’s history is an excellent way to understand how often changes occur and how many people make them. Once you have a good understanding of a project’s history, you’ll be in a great position to contribute to it yourself.
Want to exercise your coding muscles and help open source projects? Here’s how to contribute to GitHub.
About The Author