#!/usr/bin/env python
print "NOT DONE -- just for testing"
sys.exit(1)
##################################################################
#
# This is a script that takes as input a branch and a path and outputs
# -- *very* efficiently via one git call -- two JSON strings. The
# first contains information about all relevant commits, and the
# second gives for each file at least its status code and last commit
# to touch it.
#
# The path is *NOT* recursively walked, since it is important that
# the size of the output stay manageable.
#
# The information about given in each list may grow as our needs
# expand.
#
##################################################################
import json, os, subprocess, sys, uuid
if len(sys.argv) < 2:
print "Usage: %s <path> [branch]"%(sys.argv[0])
sys.exit(1)
path = sys.argv[1]
if not os.path.exists(path):
print "path %s does not exist"%path
sys.exit(1)
if len(sys.argv) >= 3:
branch = sys.argv[2]
else:
branch = ""
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
def go():
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)
file_list = [os.path.listdir(path)
log = subprocess.Popen(['git', 'log', '--name-status', format, branch, "--"] + file_list,
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)}
print json.dumps(logs, separators=(',',':'))
print json.dumps(files, separators=(',',':'))