#!/usr/bin/env python import cPickle, json, os, uuid, subprocess branches = [x.split()[-1] for x in os.popen("git branch").read().splitlines()] logs = {} files = {} def set_file(obj, components, commit): if len(components) == 1: c = components[0] if c not in obj: # only record this the *first* time we see a file obj[c] = commit else: if not obj.has_key(components[0]): obj[components[0]] = {} set_file(obj[components[0]], components[1:], commit) # recurse def dir_exists(commits, files, d=None): """ Return a dictionary directory_name:true/false, where the value is true if the directory contains any non-deleted files and false otherwise. """ if d is None: d = {} for path, val in files.iteritems(): if isinstance(val, dict): # a directory d[path] = os.path.exists(path) dir_exists(commits, val, d) return d for branch in branches: format = "--pretty=format:!%H|%an <%ae>|%ad|%s|" field_sep = str(uuid.uuid4()) commit_sep = str(uuid.uuid4()) format = format.replace('|',field_sep).replace("!",commit_sep) log = subprocess.Popen(['git', 'log', '--name-status', format, branch], stdin=subprocess.PIPE, stdout = subprocess.PIPE, stderr=subprocess.PIPE).stdout.read() commits = log.split(commit_sep) v = {} d = {} files[branch] = d commit_list = [] for entry in commits: if len(entry.strip()) == 0 : continue commit, author, date, message, modified_files= entry.split(field_sep) # modified_files = list of pairs (filename, status) modified_files = [(str(x[2:]).replace('\\\\"','"').replace('\\"',''),x[0]) for x in modified_files.splitlines() if x] meta = {'author':author, 'date':date, 'message':message, 'modified_files':dict(modified_files)} v[commit] = meta commit_list.append(commit) commit_id = commit for filename, status in modified_files: set_file(d, filename.split('/'), commit_id) logs[branch] = {'commit_list':commit_list, 'commits':v, 'dir_exists':dir_exists(v, d)} #open('logs.pickle','w').write(cPickle.dumps(logs)) #open('files.pickle','w').write(cPickle.dumps(files)) print json.dumps(logs, separators=(',',':')) print json.dumps(files, separators=(',',':'))