56 lines
1.2 KiB
Python
56 lines
1.2 KiB
Python
from pathlib import Path, PurePath
|
|
|
|
import hashlib
|
|
import os
|
|
|
|
GIT_DIR = ".ugit"
|
|
|
|
|
|
def init():
|
|
Path.mkdir(GIT_DIR)
|
|
Path.mkdir(f"{GIT_DIR}/objects")
|
|
|
|
|
|
def update_ref(ref, oid):
|
|
ref_path = f"{GIT_DIR}/{ref}"
|
|
Path.mkdir(ref_path, exist_ok=True)
|
|
with open(ref_path, "w") as f:
|
|
f.write(oid)
|
|
|
|
|
|
def get_ref(ref):
|
|
ref_path = f"{GIT_DIR}/{ref}"
|
|
if Path.is_file(ref_path):
|
|
with open(ref_path) as f:
|
|
return f.read().strip()
|
|
|
|
|
|
def iter_refs():
|
|
refs = ["HEAD"]
|
|
for root, _, filenames in Path.walk(f"{GIT_DIR}/refs"):
|
|
root = PurePath.relative_to(root, GIT_DIR)
|
|
refs.extend(f"{root}/{name}" for name in filenames)
|
|
|
|
for refname in refs:
|
|
yield refname, get_ref(refname)
|
|
|
|
|
|
def hash_object(data, type_="blob"):
|
|
obj = type_.encode() + b"\x00" + data
|
|
oid = hashlib.sha1(obj).hexdigest()
|
|
with open(f"{GIT_DIR}/objects/{oid}", "wb") as out:
|
|
out.write(obj)
|
|
return oid
|
|
|
|
|
|
def get_object(oid, expected="blob"):
|
|
with open(f"{GIT_DIR}/objects/{oid}", "rb") as f:
|
|
obj = f.read()
|
|
|
|
type_, _, content = obj.partition(b"\x00")
|
|
type_ = type_.decode()
|
|
|
|
if expected is not None:
|
|
assert type_ == expected, f"Expected {expected}, got {type_}"
|
|
return content
|