def write_object(data: str) -> str: oid, obj = hash_object(data) dir = git_dir().joinpath('objects', oid[:2]) dir.mkdir(parents=True, exist_ok=True) with dir.joinpath(oid[2:]).open('wb') as f: f.write(zlib.compress(obj)) return oid
def add(patterns: List[str]) -> None: obj = parse_index()[0] if git_dir().joinpath( 'index').exists() else IndexObject() for path in glob(patterns): # path = Path(file) if not path.exists(): print(f'@File not found ({path})') continue with path.open(mode='r') as f: data = f.read() write_object(data) obj.update(path) update_index(obj)
def parse_index() -> Tuple[IndexObject, str]: with git_dir().joinpath('index').open(mode='rb') as f: def read(format: str) -> Union[Tuple, Any]: d = struct.unpack(format, f.read(struct.calcsize(format))) return d if len(d) else d[0] data_type, version, entry_num = read('>4sII') entries = {} for _ in range(entry_num): format = '>IIIIIIIIII20sH' entry_size = struct.calcsize(format) ct, ctns, mt, mtns, dev, ino, mode, uid, gid, size, hash, flag = read( format) asmflg = (flag >> 15) & 0x01 extflg = (flag >> 14) & 0x01 if extflg: extoptflg = read('>H') rsvflg = (extoptflg >> 15) & 0x01 skpflg = (extoptflg >> 14) & 0x01 addflg = (extoptflg >> 13) & 0x01 else: rsvflg = skpflg = addflg = 0 fname = '' if (fn_len := int(flag & 0xFFF)) < 0xFFF: fname = f.read(fn_len) entry_size += fn_len else: while (char := f.read(1)) != b'\x00': fname += char entry_size += 1 f.read((8 - (entry_size % 8)) or 8) entries[fname.decode()] = IndexEntry( ct, ctns, mt, mtns, dev, ino, mode, uid, gid, size, hash.hex(), asmflg, extflg, rsvflg, skpflg, addflg, fname.decode("utf-8", "replace"))
def update_index(obj: IndexObject) -> None: print(obj) print('@ update_index') with git_dir().joinpath('index').open(mode='wb') as f: f.write(obj.binary_data())
def update_ref(ref: str, value: str): print('@ update_ref', value) with open(git_dir().joinpath(ref), 'w') as f: f.write(f'ref: {value}')