blob: 8feed741e80ead240b0aa1fcf3ec51db86286824 [file] [log] [blame]
#!/usr/bin/env perl
use strict;
use warnings;
use Cwd;
my (@data, @authors, @repos, @changed) = ((), (), (), ());
# Syntax: git-hist [author (default: whoami)] [number of weeks (default 10 / all 0)]";
my $author = `whoami`;
my $weeks = 10;
my $rootdir = getcwd;
my $totalcommits = 0;
if (scalar @ARGV) {
foreach my $arg (@ARGV) {
if ($arg =~ /^\d+$/) {
$weeks = $arg;
} else {
$author = $arg;
}
}
}
chomp($author);
# Make sure there are repositories to use
if (-d ".git") {
push @repos, ".";
} else {
opendir(my $dh, ".") || die "can't open local dir: $!";
@repos = grep { /^[^\.]/ && -d "$_/.git" } readdir($dh);
closedir $dh;
}
die "Directory (or subs) not git repo\n" unless (scalar @repos);
&main();
exit;
#####################################################
sub main() {
# Each week
my $week = 0;
while ($week <= $weeks) {
# Adjust for non-zero week list
$week++ if ($weeks != 0 and $week == 0);
print "\rParsing week: $week" if $week;
my $commits = 0;
# For each repo
for my $repo (@repos) {
#print "REPO: $repo\n";
my $log = &get_weeklog($repo, $author, $week);
#print "LOG: [$log]\n";
my $this = &get_commits($log);
#print "COMMITS: $this\n";
if ($this and ! &find($repo, \@changed)) {
#print "ADDING REPO\n";
push @changed, $repo;
}
&get_authors($log);
$commits += $this;
}
push @data, $commits;
last if ($weeks == 0);
$week++;
}
print "\n\n";
# Log
&print_report();
}
######################
sub print_report() {
return if ($weeks > 0 && scalar @data != $weeks);
# Weekly histogram
for my $week (0..$weeks-1) {
printf("%02d week [%02d]: ", $week, $data[$week]);
for (1..$data[$week]) {
print "*";
}
print "\n";
}
# Summary
print "\nTotal commits: ";
printf("%3d", $totalcommits);
print "\n Repositories: ";
printf("%3d ", scalar @changed);
&dump(\@changed);
print "\n Authors: ";
printf("%3d ", scalar @authors);
&dump(\@authors);
print "\n";
}
######################
sub get_weeklog() {
my ($repo, $author, $week) = @_;
# Author
my $cmd = "git shortlog -s -n ".
"--author='$author' ";
# And week (if available)
if ($week) {
my $prev = $week-1;
$cmd .= "--since='$week.week' ".
"--until='$prev.week'";
}
# Run command
chdir($repo);
my $log = `$cmd`;
chdir($rootdir);
return $log;
}
######################
sub get_commits() {
my ($log) = @_;
my $commits = 0;
foreach my $line (split(/\n/, $log)) {
my ($this) = ($line =~ /(\d+)/);
$commits += $this;
}
$totalcommits += $commits;
return $commits;
}
######################
sub get_authors() {
my ($log) = @_;
foreach my $line (split(/\n/, $log)) {
my ($author) = ($line =~ /\d+\s+(\w.*)/);
if (!&find($author, \@authors)) {
push @authors, $author;
}
}
}
######################
sub find() {
my ($elm, $array) = @_;
foreach my $e (@$array) {
return 1 if ($e eq $elm);
}
return 0;
}
######################
sub dump() {
my ($array) = @_;
return if (!scalar @{$array});
my $out = "";
foreach my $i (@$array) {
$out .= "$i, ";
}
$out =~ s/, $//;
print $out;
}