1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
#!/usr/bin/env perl
use warnings;
use strict;
use Text::Wrap qw(wrap fill $columns $huge);
use Getopt::Long;
use POSIX qw(strftime);
my $days_back = 110365; # Go back a year by default.
my $send_help = 0; # Display help and exit.
my $tag_pattern = "^\\d";
GetOptions(
"age=s" => \$days_back,
"help" => \$send_help,
"tags=s" => \$tag_pattern,
) or $send_help = 1;
# Find the trunk for the current repository if one isn't specified.
die(
"$0 usage:\n",
" [--age DAYS] limit report to DAYS in the past (default: 365)\n",
" [--tags REGEXP] report on tags matching REGEXP (default: ^v\\d+_)\n",
) if $send_help;
my $earliest_date = strftime(
"%FT %T +0000", gmtime(time() - $days_back * 86400)
);
$Text::Wrap::huge = "wrap";
$Text::Wrap::columns = 74;
chomp(my @tags = `git tag`);
{
my $i = @tags;
while ($i--) {
unless ($tags[$i] =~ /$tag_pattern/o) {
splice @tags, $i, 1;
next;
}
my $commit = `git show $tags[$i] --pretty='tformat:(((((%ci)))))' | grep '(((((' | head -1`;
die $commit unless $commit =~ /\(\(\(\(\((.+?)\)\)\)\)\)/;
$tags[$i] = {
'time' => $1,
'tag' => $tags[$i],
};
}
}
push @tags, { 'time' => '9999-99-99 99:99:99 +0000', 'tag' => 'HEAD' };
@tags = sort { $a->{'time'} cmp $b->{'time'} } @tags;
{
my $i = @tags;
while ($i--) {
last if $tags[$i]{time} lt $earliest_date;
my @commit;
open my $commit, "-|", "git log $tags[$i-1]{tag}..$tags[$i]{tag} ." or die $!;
local $/ = "\n\n";
while (<$commit>) {
if (/^\S/) {
s/^/ /mg;
push @commit, $_;
next;
}
# Trim off identical leading whitespace.
my ($whitespace) = /^(\s*)/;
if (length $whitespace) {
s/^$whitespace//mg;
}
# Re-flow the paragraph if it isn't indented from the norm.
# This should preserve indented quoted text, wiki-style.
unless (/^\s/) {
push @commit, fill(" ", " ", $_), "\n\n";
}
else {
push @commit, $_;
}
}
# Don't display the tag if there's nothing under it.
next unless @commit;
my $tag_line = "$tags[$i]{time} $tags[$i]{tag}";
print(
("=" x length($tag_line)), "\n",
$tag_line, "\n",
("=" x length($tag_line)), "\n",
"\n",
);
print @commit;
}
}
print(
"==============\n",
"End of Excerpt\n",
"==============\n",
);
|