-
-
Save jfoote/ce9f8ad1a672bef0b45a to your computer and use it in GitHub Desktop.
Analyze git-shadow repos
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# | |
# A quick hack to calculate time spent coding on a project that is tracked | |
# with `git-shadow` | |
# | |
# Jonathan Fote | |
# http://foote.pub | |
# 2014-02-12 | |
# | |
import subprocess, os, sys | |
from datetime import datetime, timedelta | |
if __name__ == "__main__": | |
# Gather timestamps for all shadow repos | |
# Post: timestamps is a list of all commits that match the user-supplied | |
# git-log incantation | |
timestamps = [] | |
dirpath = ".shadow" | |
git_args = sys.argv[1:] | |
print "git_args", git_args | |
for d in os.listdir(dirpath): | |
d = os.path.join(dirpath, d) | |
if not os.path.isdir(d): | |
continue | |
try: | |
for line in subprocess.check_output(["git", "log", "--format=%ct"] + git_args, cwd=d).splitlines(): | |
if not line: | |
continue | |
import re | |
m = re.match("^[\d]+$", line) | |
if not m: | |
continue | |
timestamp = datetime.fromtimestamp(int(line.strip())) | |
timestamps.append(timestamp) | |
except subprocess.CalledProcessError: | |
sys.stderr.write("git log failed for:" + d) | |
# Calculate work intervals -- assumes more than 5 minutes w/o coding is | |
# a break | |
# Post: intervals is a list of non-overlapping coding intervals (start | |
# and end timestamps) | |
intervals = [] | |
timestamps = sorted(timestamps) | |
start = timestamps[0] | |
for i in range(1, len(timestamps)): | |
if ((timestamps[i] - timestamps[i-1]) > timedelta(minutes=5)): | |
if start == timestamps[i-1]: | |
# If this was a single-line edit, count it as 5 seconds | |
intervals.append([start, start+timedelta(seconds=5)]) | |
else: | |
intervals.append([start, timestamps[i-1]]) | |
start = timestamps[i] | |
total = timedelta(0) | |
by_date = {} | |
for interval in intervals: | |
diff = interval[1] - interval[0] | |
#print "Coded from " + interval[0].strftime("%a, %d %b %Y %H:%M:%S") + \ | |
# " to " + interval[1].strftime("%a, %d %b %Y %H:%M:%S") + "(%s)" % diff | |
total += diff | |
by_date[interval[0].strftime("%Y-%m-%d %A")] = \ | |
by_date.get(interval[0].strftime("%Y-%m-%d %A"), timedelta(0)) + diff | |
for datestr, td in sorted(by_date.items()): | |
print datestr, "\t:", td | |
print "*"*8 | |
print "Total time coding (days, H:M:S):", total | |
print "Total commits:", len(timestamps) | |
import json | |
for_tinychart = {"labels":[], "datasets":[{"data":[]}]} | |
for datestr, td in sorted(by_date.items()): | |
for_tinychart["labels"].append(datestr) | |
for_tinychart["datasets"][0]["data"].append(td.total_seconds()) | |
print "for tinychart:" | |
print json.dumps(for_tinychart) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment