Git tips: Getting the first commit date of a file
A few years ago (2012), I wrote a post which counted up how many words I wrote in eleven years and also broke it down by month.
While I haven't done a post on that again (I figured that most people don't care), I have been maintaining the metadata on the top of each chapter in case I ever do.
However, when I'm occasionally obsessing about writing, I don't put in the headers and I have to do it after the fact. When that comes, I have to go back and figure out when I actually started a chapter (which is my definition of the date header).
When there is only one or two files, it isn't too hard, but when it is thirty chapters of a commission, I usually try to find a program to help me figure out the dates.
I frequently use Perl for my one-off programs. The following Perl script takes one or more files and simply gives the last date in a semi-useful manner.
#!/usr/bin/perl
USAGE: git-first-commit-date [–bare|-b] file…
Setup
Directives
use strict;
use warnings;
Modules
use Getopt::Long;
Options
–bare means don't put the filename in the line. Otherwise it will
–put the filename, followed by a colon and a space.
my $bare = 0;
&GetOptions(
“b|bare!” => $bare,
);
Go through the input files.
while (@ARGV)
{ # Pull out the filename.
my $filename = shift @ARGV;
my $reason = "<missing>";
my $valid = 0;
if (-f $filename)
{
# Get the date for the file. We tell Git to only give us the
# ISO date (https://xkcd.com/1179/) for the files using
# --pretty=format:%ad --date=short. We use --follow to handle
# renames. Finally, we get the last one (the earliest
# date). --reverse didn't seem to work, so we skip that.
$reason = `git log --follow --pretty=format:%ad --date=short "$filename" | tail -n 1`;
chomp $reason;
# If we have a date, use it. Otherwise say it is untracked.
$reason = "<untracked>" if $reason =~ /^\s*$/s;
}
# Write out the results.
if (!$bare)
{
print "$filename: ";
}
# Print out the reason which will be <untracked>, <missing>, or a
# date.
print $reason, "\n";
}
When it runs, you get something like this:
$ git-first-commit-date untracked-file missing-file chapter-00.markdown
untracked-file: <untracked>
missing-file: <missing>
chapter-00.markdown: 2014-02-20
$
It's a little one-off program, but it solves a very specific problem for me.
Metadata
Categories:
Tags: