Introduction
As we've covered in many of our previous articles, Git is a very useful tool for developers, albeit, it tends to be a bit confusing to newcomers.
And all the while many know the basics of Git and know how to perform common operations, such as merging commits, branching, or cloning repos - there is a long-tail subset of things you'll likely need to do over time that you just won't know off the top of your head.
For instance, all commits contain some amount of metadata. How do we find that exactly?
In this short article, we'll see how to extract the date of a specific Git commit.
Get Date of a Commit using Git
For many use-cases, you can easily find information like this in the repo's hosting provider repository (such as GitHub), but that's not always viable.
In that case, you can use the command line. There are a number of different ways to achieve this, but for now we'll focus on the following command:
$ git show -s --format=%ci <commit>
Using this in actual repository, you'll get something along the lines of:
$ git show -s --format=%ci d4d20c2
2021-09-28 11:13:46 -0500
You can also omit the commit hash to get the date for the latest commit instead:
$ git show -s --format=%ci
2021-09-29 10:04:27 -0500
For what seems like a simple task, there is a lot going on here. Let's break it down to better understand what's going on.
First, we use the show
command. According to the man page, this command is used to "Show various types of objects". That sounds a bit vague, but that's exactly what it does.
You can use the show
command to extract various metadata about blobs, trees, tags, and commits.
So when you want to find out just about any specific information about a commit, for example, this is the command you'll likely want to use.
The next option in our command is -s
. This option simply suppresses the diff output. Without this option, the show
command displays the commit patch by default, thus cluttering your output:
$ git show --format=%ci d4d20c2
2021-09-28 11:13:46 -0500
diff --git a/routes/api.js b/routes/api.js
index d09cae0..bf6004f 100644
--- a/routes/api.js
+++ b/routes/api.js
@@ -111,7 +111,7 @@ exports.edit = async (req, res) => {
}
if (!user.hasPermission('content_edit')) {
- response.failed('You don\'t have permission to edit this user.');
+ response.failed('You don\'t have permission to edit this content.');
return res.json(response.done());
}
We get a lot more information from the output than what we care for, so -s
is a useful option to remove this.
The next option is the --format=%ci
. This tells the show
command exactly what information we're requesting about the object. In this case, %ci
specifies the committer date, specifically in ISO 8601-like format. Other similar formats are the date in RFC2822 style (%cD
) or Unix timestamp (%ct
).
The --format
option is important as it's where you can specify a wide range of metadata to show. Other than the commit date, here are a few other examples of metadata that you can show with this command:
- Commit hash (
%H
) - Tree hash (
%T
) - Author name (
%an
) - Author email (
%ae
) - Subject (
%s
) - Commit notes (
%N
)
And of course, the last argument in our command is <commit>
, which is fairly self-explanatory. This is an optional argument where you can specify the commit you're interested in. Since the show
command works on many different types of objects, this argument can be used to specify any of the supported objects, like tags or trees.
For example, if you wanted to specify a tag, you'd simply use the tag name instead of commit hash:
$ git show -s --format=%ci
2021-09-28 11:13:46 -0500
$ git show -s --format=%ci v0.1.2
tag v0.1.2
Tagger: Scott Robinson <[email protected]>
Fix failure message when user doesn't have content_edit permission
Extracting Commit Date with log and Formatting Dates
You might not actually care about all of the different ways you can extract information like this from Git, but it is helpful to see other approaches as it will give you a good idea of what all is possible with Git.
Formatting Dates
While there are multiple date formats directly supported by the --format
option, it doesn't support all possible style of dates you might want to get as output. A more versatile option is to use --format=%cd
, which returns the committer date while also respecting the date format provided in the --date=
option. This option can be given values like relative
, local
, default
, iso
, and others.
The --date
option can also be used to specify more fine-grained date formats using formatting tokens:
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
$ git show -s --format=%cd --date=format:'%Y-%m-%d %H:%M:%S' d4d20c2
2021-09-29 10:04:27
Using the formatter tokens, you can format the date in any form and shape you'd like.
Using the log Command
Along with the show
command, we can also use the log
command to get the date for a commit. This is a redundant method, in this case, but it has its own uses in other respects.
According to the man pages, log
"Shows the commit logs", which may seem obvious. If you read through the man pages, you'll notice that there are a lot of overlapping features with show
.
The main difference is that show
is mainly used for inspecting a single commit, whereas log
is used for showing a range of commits. log
also has many more features in terms of returning and formatting commits, like searching/skipping/limiting returned commit messages.
To get the commit date, we can use the log
command, with the same arguments as before, but with the addition of -1
:
$ git log -1 --format=%ci d4d20c2
2021-09-29 10:04:27 -0500
The only difference is the -1
parameter, which tells this command to return date information for only 1 commit. Using -2
here would return 2 commits, and so-on. The rest of the parameters are identical to show
.
Conclusion
In this article we looked, in detail, into how we can use the show
command to retrieve metadata about a commit, specifically getting its commit date. We also saw how it can be used to retrieve a number of other pieces of information, as well as other commands available to use for similar uses.