Skip to content

Instantly share code, notes, and snippets.

@fmarani
Created November 29, 2014 17:24
Show Gist options
  • Save fmarani/a0df98bdd2c77e9c1c76 to your computer and use it in GitHub Desktop.
Save fmarani/a0df98bdd2c77e9c1c76 to your computer and use it in GitHub Desktop.
very simple content tracker
#!/usr/bin/env python
import sys
import os
import dbm
import json
import uuid
print("BaKKit up")
try:
op = sys.argv[1]
except IndexError:
print ("please specify op")
sys.exit()
try:
repo_dir = sys.argv[2]
if repo_dir[-1] != "/":
repo_dir += "/"
except IndexError:
print ("please specify root folder")
sys.exit()
location = lambda x: os.path.join(repo_dir, x)
if op == "init":
try:
os.unlink(location(".bkkdb"))
except FileNotFoundError:
pass
db = dbm.open(location(".bkkdb"), 'c')
db['root'] = json.dumps({'tree': {}, 'parent': None})
db['head'] = "root"
db.close()
sys.exit()
db = dbm.open(location(".bkkdb"), 'w')
# db structures:
# commit_id -> {'msg': commit msg, 'tree': {'path': blob_id}, 'parent': parent commit_id}
# blob_id -> content
# "head" links to last commit id
# "root" is the first commit, also has no parent
def read_commit(blob_id):
return json.loads(db[blob_id].decode("utf8"))
if op == "log" or op == "longlog":
commit = read_commit(db['head'])
counter = 0
while commit['parent']:
print("%d) %s" % (counter, commit['msg']))
if op == "longlog":
for fname, blob_id in commit['tree'].items():
print("filename %s -- content:" % fname)
print(db[blob_id])
counter -= 1
commit = read_commit(commit['parent'])
if op == "commit":
newcontent = {}
for root, dirs, files in os.walk(repo_dir):
for name in files:
if name.startswith("."):
break
f = os.path.join(root[len(repo_dir):], name)
with open(location(f), 'r') as fd:
newcontent[f] = fd.read()
lastcontent = {}
lasttree = read_commit(db['head'])['tree']
for path, blob_key in lasttree.items():
lastcontent[path] = db[blob_key].decode("utf8")
if lastcontent != newcontent:
print("write commit msg")
msg = input()
new_tree_obj = {}
for path, newcontent in newcontent.items():
if newcontent != lastcontent.get(path):
# if the file changed or new, re-add the whole file
newkey = uuid.uuid4().hex
db[newkey] = newcontent
new_tree_obj[path] = newkey
else:
new_tree_obj[path] = lasttree[path]
newkey = uuid.uuid4().hex
dbval = json.dumps({'msg': msg, 'tree': new_tree_obj, 'parent': db['head'].decode("utf8")})
print("storing %s in %s" % (dbval, newkey))
db[newkey] = dbval
db['head'] = newkey
db.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment