Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I would like to generate a statistic from my git repository to create a time-chart:

<commit> <timestamp> <changed-lines>

35abf648cfc  2011-04-04t17:23:58  +20 -4
93acb668f32  2011-04-04t17:59:01  -4 +1

so I can plot a "nice" graph for that with gnuplot or so. Where <changed-lines> might be anything that is generatable, i.e. +20 -3 (added 20 lines, removed 3 lines) or just 23 or whatever. Important is, that lines are counted -- changed files would not be useful in my scenario.

It would be good, if I could apply this only on a part of the repo, because some directories contain nasty binary files, which would destroy a statistics.

I guess git log might come in there somehow, but I have no idea where to start...

share|improve this question

This line comes close to what you want:

$ git log --format="%h %ad" --numstat
b29dfc1 Sun Apr 24 13:32:06 2011 +0200
3       0       bar
0       2       foo

d552271 Sun Apr 24 13:21:16 2011 +0200
2       1       foo

ac8894a Sun Apr 24 13:20:59 2011 +0200
1       0       foo

5965384 Sun Apr 24 13:20:40 2011 +0200
1       0       bar
1       0       foo

Read the git log manpage for more information.

share|improve this answer
Indeed! I can start from there. Yep, manpage read, but could not bring --numstat together with --format. thanks. – towi Apr 24 '11 at 11:40

I have a smart perl script that does the job:

#!/usr/bin/perl -w

use warnings;
use strict;
use Date::Parse;

my $out = "";
while (<>)
    chomp (my $line = $_);
    $out .= $1 if ($line =~ m/^commit ([a-z0-9]+)$/);
    $out .= "\t" . str2time($1) if ($line =~ m/^Date: (.+)$/);
    if ($line =~ m/ (\d+) files changed, (\d+) insertions\(\+\), (\d+) deletions\(-\)/)
        print $out . "\t" . $1 . "\t" . $2 . "\t" . $3 . "\n";
        $out = "";

print $out."\n";

Just change permissions to make it executable and pipe the output of git log --shortstat to this script (here the script is stored /tmp/gitstats.pl):

user@srv % git log --shortstat | /tmp/gitstats.pl
d56d496ac70f6c441d624413f54aeba1dfb805d7        1303393788      104     51420   12081
98c4b66af7a0c7e6b8155bb2a538f7ca77c1243a        1303285305      234     34756   35022
6e33280279d5bd83ea8d0fde95b08394a297b159        1303251405      6       341     0

First column is commit ID, second entry is unix time stamp, followd by number of files changed, insertions and deletions.

This also tracks your binary files, but that is of course an issue of your repo design...

share|improve this answer
Thats perfect. I couldn't have done this in perl (and in python it would have been longer :-). In only had to remove the use Date, I obviously have a slim perl here. NP, using git log --shortstat --date=short | ./gitstats.pl it's almost perfect. I seem to have some parsing glitches... will work on that. – towi Apr 24 '11 at 14:04
After a Merge the lines get mixed up. Easily solved. – towi Apr 24 '11 at 14:14
No need to parse the default, human-targeted output format. Use --format and --numstat: git log --format='%H %at' --numstat | perl -ne 'if (m/^([[:xdigit:]]{40}) (\d+)$/) { print qq($c\t$t\t$n\t$a\t$r\n) if ($c); ($c,$t) = ($1,$2); $n = $a = $r = 0 }; if (m/^(\d+|-)\t(\d+|-)+\t/) { $n++; $a += $1 if $1 ne q(-); $r += $2 if $2 ne q(-) }' – Chris Johnsen Apr 25 '11 at 7:04
Add an END block to @ChrisJohnsen's script to get the last commit, END { print qq($c\t$t\t$n\t$a\t$r\n) if ($c); } – xn. Nov 2 '14 at 22:42

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.