Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50629 views
#!/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=(',',':'))