#!/usr/bin/perl use Getopt::Long; use POSIX qw(ceil); use strict; Getopt::Long::Configure(qw(bundling)); my %authors; my $total; my $files; my $rev = shift(@ARGV) || "HEAD"; foreach my $file (`git ls-tree --name-only -r $rev`) { chomp($file); print STDERR "Processing $file\n"; foreach my $line (`git blame -M -w $rev -- "$file"`) { chomp($line); if (substr($line, 0, 1) eq "^") { ++$authors{"*initial checkin"}; } else { $line =~ s[^.*?\((.*?)\s*\d{4}-\d{2}-\d{2}.*][$1]; ++$authors{$line}; } ++$total; } } print "Total lines: $total\n"; my $i = 0; my $author_ind = ceil(log(scalar(keys %authors)) / log(10)); my $lines_ind = ceil(log($total) / log(10)); foreach my $author (sort { $authors{$b} <=> $authors{$a} } keys %authors) { printf "%${author_ind}s %${lines_ind}u %5.2f%% %s\n", sprintf("#%u", ++$i), $authors{$author}, $authors{$author} * 100 / $total, $author; }