def test_write_index(self): gitdir = repo_create(".") entries = [ GitIndexEntry( ctime_s=1593379228, ctime_n=200331013, mtime_s=1593379228, mtime_n=200331013, dev=16777220, ino=8610507, mode=33188, uid=501, gid=20, size=4, sha1= b"W\x16\xcaY\x87\xcb\xf9}k\xb5I \xbe\xa6\xad\xde$-\x87\xe6", flags=7, name="bar.txt", ), GitIndexEntry( ctime_s=1593379274, ctime_n=535850078, mtime_s=1593379274, mtime_n=535850078, dev=16777220, ino=8610550, mode=33188, uid=501, gid=20, size=7, sha1= b"\x9f5\x8aJ\xdd\xef\xca\xb2\x94\xb8>B\x82\xbf\xef\x1f\x96%\xa2I", flags=15, name="baz/numbers.txt", ), GitIndexEntry( ctime_s=1593379233, ctime_n=953396667, mtime_s=1593379233, mtime_n=953396667, dev=16777220, ino=8610515, mode=33188, uid=501, gid=20, size=4, sha1=b"%|\xc5d,\xb1\xa0T\xf0\x8c\xc8?-\x94>V\xfd>\xbe\x99", flags=7, name="foo.txt", ), ] write_index(gitdir, entries) index = gitdir / "index" with index.open(mode="rb") as f: index_data = f.read() expected_index_data = b"DIRC\x00\x00\x00\x02\x00\x00\x00\x03^\xf9\t\x9c\x0b\xf0\xcf\x05^\xf9\t\x9c\x0b\xf0\xcf\x05\x01\x00\x00\x04\x00\x83b\xcb\x00\x00\x81\xa4\x00\x00\x01\xf5\x00\x00\x00\x14\x00\x00\x00\x04W\x16\xcaY\x87\xcb\xf9}k\xb5I \xbe\xa6\xad\xde$-\x87\xe6\x00\x07bar.txt\x00\x00\x00^\xf9\t\xca\x1f\xf0l^^\xf9\t\xca\x1f\xf0l^\x01\x00\x00\x04\x00\x83b\xf6\x00\x00\x81\xa4\x00\x00\x01\xf5\x00\x00\x00\x14\x00\x00\x00\x07\x9f5\x8aJ\xdd\xef\xca\xb2\x94\xb8>B\x82\xbf\xef\x1f\x96%\xa2I\x00\x0fbaz/numbers.txt\x00\x00\x00^\xf9\t\xa18\xd3\xad\xbb^\xf9\t\xa18\xd3\xad\xbb\x01\x00\x00\x04\x00\x83b\xd3\x00\x00\x81\xa4\x00\x00\x01\xf5\x00\x00\x00\x14\x00\x00\x00\x04%|\xc5d,\xb1\xa0T\xf0\x8c\xc8?-\x94>V\xfd>\xbe\x99\x00\x07foo.txt\x00\x00\x00k\xd6q\xa7d\x10\x8e\x80\x93F]\x0c}+\x82\xfb\xc7:\xa8\x11" self.assertEqual(expected_index_data, index_data)
def test_unpack(self): pack = b"^\xf9\t\x9c\x0b\xf0\xcf\x05^\xf9\t\x9c\x0b\xf0\xcf\x05\x01\x00\x00\x04\x00\x83b\xcb\x00\x00\x81\xa4\x00\x00\x01\xf5\x00\x00\x00\x14\x00\x00\x00\x04W\x16\xcaY\x87\xcb\xf9}k\xb5I \xbe\xa6\xad\xde$-\x87\xe6\x00\x07bar.txt\x00\x00\x00" expected_entry = GitIndexEntry( ctime_s=1593379228, ctime_n=200331013, mtime_s=1593379228, mtime_n=200331013, dev=16777220, ino=8610507, mode=33188, uid=501, gid=20, size=4, sha1=b"W\x16\xcaY\x87\xcb\xf9}k\xb5I \xbe\xa6\xad\xde$-\x87\xe6", flags=7, name="bar.txt", ) self.assertEqual(expected_entry, GitIndexEntry.unpack(pack))
def write_tree(gitdir: pathlib.Path, index: tp.List[GitIndexEntry], dirname: str = "") -> str: # PUT YOUR CODE HERE files_list = [] for x in (gitdir.parent / dirname).glob("*"): files_list.append(x.absolute) to_add_dirs: tp.Dict[str, tp.List[GitIndexEntry]] to_add_dirs = dict() entries_to_format = [] for entry in index: if pathlib.Path(entry.name).absolute() in files_list: entries_to_format.append(entry) else: subdir_name = entry.name.lstrip(dirname).split("/", 1)[0] if subdir_name not in to_add_dirs: to_add_dirs[subdir_name] = [] to_add_dirs[subdir_name].append(entry) for subdir_name in to_add_dirs: st = (pathlib.Path(gitdir.parent) / dirname / subdir_name).stat() sha = write_tree( gitdir, to_add_dirs[subdir_name], dirname + "/" + subdir_name if dirname != "" else subdir_name, ) entries_to_format.append( GitIndexEntry( ctime_s=int(st.st_ctime), ctime_n=st.st_ctime_ns % len(str(int(st.st_ctime))), mtime_s=int(st.st_mtime), mtime_n=st.st_mtime_ns % len(str(int(st.st_mtime))), dev=st.st_dev, ino=st.st_ino, mode=0o40000, uid=st.st_uid, gid=st.st_gid, size=st.st_size, sha1=bytes.fromhex(sha), flags=7, name=str(pathlib.Path(gitdir.parent) / dirname / subdir_name), )) preformatted_data = b"".join( oct(entry.mode)[2:].encode() + b" " + pathlib.Path(entry.name).name.encode() + b"\00" + entry.sha1 for entry in sorted(entries_to_format, key=lambda x: x.name)) return hash_object(preformatted_data, "tree", write=True)
def write_tree(gitdir: pathlib.Path, index: tp.List[GitIndexEntry], dirname: str = "") -> str: # PUT YOUR CODE HERE path = gitdir.parent / dirname files = list(path.glob("*")) unhandled_dirs: tp.Dict[str, tp.List[GitIndexEntry]] unhandled_dirs = dict() enties_to_format = [] for entry in index: entry_file = pathlib.Path(entry.name) if entry_file in files: enties_to_format.append(entry) else: dir_name = entry.name.lstrip(dirname).split("/", 1)[0] if not dir_name in unhandled_dirs: unhandled_dirs[dir_name] = [] unhandled_dirs[dir_name].append(entry) for dir_name in unhandled_dirs: stat = (gitdir.parent / dirname / dir_name).stat() sha = write_tree(gitdir, unhandled_dirs[dir_name], dir_name) enties_to_format.append( GitIndexEntry( ctime_s=int(stat.st_ctime), ctime_n=0, mtime_s=int(stat.st_mtime), mtime_n=0, dev=stat.st_dev, ino=stat.st_ino, mode=0o40000, # mode for git tree uid=stat.st_uid, gid=stat.st_gid, size=stat.st_size, sha1=bytes.fromhex(sha), flags=len(dir_name), name=str(gitdir.parent / dirname / dir_name), ) ) preformatted_data = b"".join( oct(entry.mode)[2:].encode() + b" " + pathlib.Path(entry.name).name.encode() + b"\x00" + entry.sha1 for entry in sorted(enties_to_format, key=lambda x: x.name) ) return hash_object(preformatted_data, "tree", write=True)
def write_tree(gitdir: pathlib.Path, index: tp.List[GitIndexEntry], dirname: str = "") -> str: list_in_dir = [x.absolute() for x in (gitdir.parent / dirname).glob("*")] add_in_fut: tp.Dict[str, tp.List[GitIndexEntry]] add_in_fut = dict() toformat = [] for entry in index: if pathlib.Path(entry.name).absolute() in list_in_dir: toformat.append(entry) else: subdir_name = entry.name.lstrip(dirname).split("/", 1)[0] if subdir_name not in add_in_fut: add_in_fut[subdir_name] = [] add_in_fut[subdir_name].append(entry) for subdir_name in add_in_fut: st = (pathlib.Path(gitdir.parent) / dirname / subdir_name).stat() going_deeper = subdir_name if dirname == "" else dirname + "/" + subdir_name sha = write_tree(gitdir, add_in_fut[subdir_name], going_deeper) toformat.append( GitIndexEntry( ctime_s=int(st.st_ctime), ctime_n=st.st_ctime_ns % len(str(int(st.st_ctime))), mtime_s=int(st.st_mtime), mtime_n=st.st_mtime_ns % len(str(int(st.st_mtime))), dev=st.st_dev, ino=st.st_ino, mode=0o40000, uid=st.st_uid, gid=st.st_gid, size=st.st_size, sha1=bytes.fromhex(sha), flags=7, name=str(pathlib.Path(gitdir.parent) / dirname / subdir_name), )) data = b"".join( oct(entry.mode)[2:].encode() + b" " + pathlib.Path(entry.name).name.encode() + b"\00" + entry.sha1 for entry in sorted(toformat, key=lambda x: x.name)) return hash_object(data, "tree", write=True)