6 # Copyright (C) 2008 Francesco Salvestrini
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License along
19 # with this program; if not, write to the Free Software Foundation, Inc.,
20 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 # This program is based on gitlog-to-changelog by Jim Meyering
28 use POSIX qw(strftime);
30 (my $ME = $0) =~ s|.*/||;
33 my $PACKAGE_NAME = '@PACKAGE_NAME@';
34 my $PACKAGE_BUGREPORT = '@PACKAGE_BUGREPORT@';
35 my $PACKAGE_VERSION = '@PACKAGE_VERSION@';
38 defined fileno STDOUT or return;
39 close STDOUT and return;
40 warn "$ME: failed to close standard output: $!\n";
47 my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
48 if ($exit_code != 0) {
49 print $STREAM "Try `$ME --help' for more information.\n";
54 Output git committers names.
58 --since=DATE convert only the logs since DATE;
59 the default is to convert all log entries.
60 -h, --help display this help and exit
61 --version output version information and exit
65 $ME --since=2008-01-01 > AUTHORS
67 Report bugs to <${PACKAGE_BUGREPORT}>
73 # If the string $S is a well-behaved file name, simply return it.
74 # If it contains white space, quotes, etc., quote it, and return the new string.
78 if ($s =~ m![^\w+/.,-]!) {
79 # Convert each single quote to '\''
80 $s =~ s/\'/\'\\\'\'/g;
81 # Then single quote the string.
89 return join (' ', map {shell_quote $_} @_);
93 my $since_date = '1970-01-01 UTC';
95 'h|help' => sub { usage 0 },
96 'version' => sub { print "$ME ($PACKAGE_NAME) $VERSION\n"; exit(0); },
97 'since=s' => \$since_date,
101 and (warn "$ME: too many arguments\n"), usage 1;
103 my @cmd = (qw (git shortlog --summary), "--since=$since_date");
104 open PIPE, '-|', @cmd
105 or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n" .
106 "(Is your Git too old? Version 1.5.1 or later required.)\n");
113 defined($line) or last;
116 if ($line =~ /^\s*(\d+)\s+([\w\s]+)\s*$/) {
117 defined($1) or die "$ME: Wrong commits count";
118 defined($2) or die "$ME: Wrong committer name";
120 my $commits = int($1);
123 if (defined($committers{$name})) {
124 die "$ME: Duplicated name found, fix your .mailmap";
126 $committers{$name} = $commits;
127 $total = $total + $commits;
129 die "$ME: Unhandled line found ('$line')";
133 my @keys = sort { $committers{$a} < $committers{$b} } keys %committers;
134 foreach my $name (@keys) {
136 $total -= $committers{$name};
139 ($total == 0) or die("Bug found (total = $total)");
142 or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n";
143 # FIXME-someday: include $PROCESS_STATUS in the diagnostic