Skip to content

Instantly share code, notes, and snippets.

@jfoote
Created February 20, 2015 17:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfoote/ce9f8ad1a672bef0b45a to your computer and use it in GitHub Desktop.
Save jfoote/ce9f8ad1a672bef0b45a to your computer and use it in GitHub Desktop.
Analyze git-shadow repos
#!/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