aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pomu/util/git.py')
-rw-r--r--pomu/util/git.py52
1 files changed, 52 insertions, 0 deletions
diff --git a/pomu/util/git.py b/pomu/util/git.py
new file mode 100644
index 0000000..985087c
--- /dev/null
+++ b/pomu/util/git.py
@@ -0,0 +1,52 @@
+"""Miscellaneous utility functions for git structures"""
+
+from base64 import b16encode
+import zlib
+
+from pomu.util.result import Result
+
+def parse_tree(blob, path=b''):
+ """Parses a git tree"""
+ res = []
+ leng, _, tree = blob.partition(b'\0')
+ if path is str:
+ path = path.encode('utf-8')
+ if not tree:
+ return Result.Err('Invalid tree')
+ while len(tree) > 0:
+ mode, _, tree = tree.partition(b' ')
+ name, _, tree = tree.partition(b'\0')
+ sha = b16encode(tree[0:20]).decode('utf-8').lower()
+ tree = tree[20:]
+ if not name or not sha:
+ return Result.Err()
+ is_dir = mode[0:1] != b'1'
+ res.append((is_dir, sha, path + b'/' + name))
+ return Result.Ok(res)
+
+def parse_blob(blob):
+ """Parses a git blob"""
+ leng, _, data = blob.partition(b'\0')
+ if not leng or not data:
+ return Result.Err()
+ return Result.Ok(data)
+
+def commit_head(blob):
+ if not blob[7:] == 'commit ':
+ return Result.Err()
+ l = blob.split('\n')[0]
+ cid, _, tid = l.partition('\0')
+ if not tid[0:5] == 'tree ':
+ return Result.Err()
+ return tid[5:]
+
+def parse_object(obj, tpath=b''):
+ """Parses a git object"""
+ if tpath is str:
+ tpath = tpath.encode('utf-8')
+ data = zlib.decompress(obj)
+ if data[0:5] == b'blob ':
+ return parse_blob(data[5:])
+ elif data[0:5] == b'tree ':
+ return parse_tree(data[5:], tpath)
+ return Result.Err('Unsupported object type')