Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

executable file 99 lines (76 sloc) 2.853 kb
#!/usr/bin/env python
import sys
import subprocess
from collections import defaultdict
class AuthorCounter(object):
def __init__(self, rev, filename, size):
self.rev = rev
self.filename = filename
self.size = size
self.umap = defaultdict(lambda: 0)
def count_authors(self):
current_sha = ''
current_user = ''
commit_u_map = {}
if self.size < 2*1024*1024:
args = ['git', 'blame', '-M5', '-C5', '-p', self.rev, self.filename]
sub=subprocess.Popen(args, stdout=subprocess.PIPE, close_fds=True)
for l in sub.stdout:
if l.startswith("\t"):
self.umap[current_user] += 1
else:
try:
if l.rstrip() == 'boundary':
k, v = 'boundary', ''
else:
k, v = l.strip().split(' ', 1)
except ValueError:
sys.stderr.write("Error parsing %s on %s\n" % (repr(l), self.filename))
k = l
v = ''
if len(k) == 40 or k == 'boundary': # Assumed SHA
current = ''
current_sha = k
if current_sha in commit_u_map:
current_user = commit_u_map[current_sha]
elif k == 'author':
current_user = v
commit_u_map[current_sha] = v
def load_blobs(ref):
args = ['git', 'ls-tree', '-z', '-l', '-r', ref]
sub=subprocess.Popen(args, stdout=subprocess.PIPE, close_fds=True)
blobs = sub.stdout.read().split("\0")
rv = []
for b in (b for b in blobs if b):
info, filename = b.split("\t")
mode, t, blob_id, size = info.split()
assert t == 'blob'
rv.append(AuthorCounter(ref, filename, int(size)))
return rv
def rev_parse(ref):
args = ['git', 'rev-parse', ref]
sub = subprocess.Popen(args, stdout=subprocess.PIPE, close_fds=True)
return sub.stdout.read().strip()
def name(ref):
args = ['git', 'describe', ref]
sub = subprocess.Popen(args, stdout=subprocess.PIPE, close_fds=True)
return sub.stdout.read().strip()
def mergeDicts(inputs):
rv = defaultdict(lambda: 0)
for d in inputs:
for k,v in d.iteritems():
rv[k] += v
return rv
def output(d):
for v,k in sorted(((v,k) for k,v in d.iteritems()), reverse=True):
print v, k
if __name__ == '__main__':
refs = sys.argv[1:]
if not refs:
refs = ['HEAD']
for ref in refs:
ref = rev_parse(ref)
blobs = load_blobs(ref)
for b in blobs:
b.count_authors()
output(mergeDicts(b.umap for b in blobs))
Jump to Line
Something went wrong with that request. Please try again.