def test_cat_tree_file(self): gitdir = repo.repo_create(".") mode100644 = stat.S_IFREG | stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH quote = pathlib.Path("quote.txt") self.fs.create_file(quote, contents="that's what she said", st_mode=mode100644) letters = pathlib.Path("alphabeta") / "letters.txt" self.fs.create_file(letters, contents="abcdefg", st_mode=mode100644) digits = pathlib.Path("numbers") / "digits.txt" self.fs.create_file(digits, contents="1234567890", st_mode=mode100644) index.update_index(gitdir, [quote, letters, digits], write=True) entries = index.read_index(gitdir) sha = tree.write_tree(gitdir, entries) self.assertEqual("a9cde03408c68cbb205b038140b4c3a38aa1d01a", sha) expected_output = "\n".join( [ "040000 tree 7926bf494dcdb82261e1ca113116610f8d05470b\talphabeta", "040000 tree 32ad3641a773ce34816dece1ce63cc24c8a514d0\tnumbers", "100644 blob 7e774cf533c51803125d4659f3488bd9dffc41a6\tquote.txt", ] ) with patch("sys.stdout", new=io.StringIO()) as out: objects.cat_file(sha, pretty=True) self.assertEqual(expected_output, out.getvalue().strip())
def test_write_tree_subdirs(self): gitdir = repo_create(".") mode100644 = stat.S_IFREG | stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH quote = pathlib.Path("quote.txt") self.fs.create_file(quote, contents="that's what she said", st_mode=mode100644) letters = pathlib.Path("alphabeta") / "letters.txt" self.fs.create_file(letters, contents="abcdefg", st_mode=mode100644) digits = pathlib.Path("numbers") / "digits.txt" self.fs.create_file(digits, contents="1234567890", st_mode=mode100644) update_index(gitdir, [quote, letters, digits], write=True) entries = read_index(gitdir) sha = write_tree(gitdir, entries) self.assertEqual("a9cde03408c68cbb205b038140b4c3a38aa1d01a", sha) alphabeta_tree_sha = "7926bf494dcdb82261e1ca113116610f8d05470b" alphabeta_tree_obj = gitdir / "objects" / alphabeta_tree_sha[: 2] / alphabeta_tree_sha[ 2:] self.assertTrue(alphabeta_tree_obj.exists()) numbers_tree_sha = "32ad3641a773ce34816dece1ce63cc24c8a514d0" numbers_tree_obj = gitdir / "objects" / numbers_tree_sha[: 2] / numbers_tree_sha[ 2:] self.assertTrue(numbers_tree_obj.exists())
def checkout(gitdir: pathlib.Path, obj_name: str) -> None: for entry in read_index(gitdir): try: os.remove(entry.name) except FileNotFoundError: pass commit_que = [commit_parse(read_object(obj_name, gitdir)[1])] while len(commit_que) != 0: comm = commit_que.pop() if "parent" in comm: commit_que.append(commit_parse((read_object(comm["parent"], gitdir)[1]))) tree_que: tp.List[tp.Tuple[pathlib.Path, tp.List[tp.Tuple[int, str, str]]]] tree_que = [(gitdir.parent, read_tree(read_object(comm["tree"], gitdir)[1]))] while len(tree_que) != 0: tree_path, tree_content = tree_que.pop() for file_data in tree_content: fmt, data = read_object(file_data[2], gitdir) if fmt == "tree": tree_que.append((tree_path / file_data[1], read_tree(data))) try: (tree_path / file_data[1]).mkdir() except FileExistsError: pass else: if not (tree_path / file_data[1]).exists(): with (tree_path / file_data[1]).open("wb") as f: f.write(data) (tree_path / file_data[1]).chmod(file_data[0]) for dir in filter(lambda x: x != gitdir and x.is_dir(), gitdir.parent.glob("*")): dir_remover(dir)
def commit(gitdir: pathlib.Path, message: str, author: tp.Optional[str] = None) -> str: index = read_index(gitdir) return commit_tree( gitdir=gitdir, tree=write_tree(gitdir, index), message=message, author=author)
def checkout(gitdir: pathlib.Path, obj_name: str) -> None: # PUT YOUR CODE HERE update_ref(gitdir, "HEAD", obj_name) hash = commit_parse(read_object(obj_name, gitdir)[1]) files = find_tree_files(hash, gitdir) index = read_index(gitdir) names = [] for i in index: names.append(i.name) update_index(gitdir, [pathlib.Path(i[1]) for i in files], write=True) for i in names: first = i.split("/")[0] if pathlib.Path(first).is_dir(): shutil.rmtree(first) else: if pathlib.Path(first).exists(): os.remove(first) for i in files: isFound = i[1].find("/") if isFound != -1: elem1 = os.path.split(i[1])[0] if pathlib.Path(elem1).exists() == False: os.makedirs(elem1) with open(i[1], "wb") as f: f.write(read_object(i[0], gitdir)[1])
def checkout(gitdir: pathlib.Path, obj_name: str) -> None: for i in read_index(gitdir): if pathlib.Path(i.name).exists(): os.remove(i.name) commit = commit_parse(read_object(obj_name, gitdir)[1]) q = True while q: trees: tp.List[tp.Tuple[tp.List[tp.Tuple[int, str, str]], pathlib.Path]] = [ (read_tree(read_object(commit["tree"], gitdir)[1]), gitdir.parent) ] while trees: tree_content, tree_path = trees.pop() for i in tree_content: fmt, data = read_object(i[2], gitdir) if fmt != "tree": if not (tree_path / i[1]).exists(): with (tree_path / i[1]).open("wb") as f: f.write(data) (tree_path / i[1]).chmod(int(str(i[0]), 8)) f.close() else: if not (tree_path / i[1]).exists(): (tree_path / i[1]).mkdir() trees.append((read_tree(data), tree_path / i[1])) if "parent" in commit: commit = commit_parse((read_object(commit["parent"], gitdir)[1])) else: q = not q for i in gitdir.parent.glob("*"): if i.is_dir() and i != gitdir: try: os.removedirs(i) except OSError: continue
def commit(gitdir: pathlib.Path, message: str, author: tp.Optional[str] = None) -> str: tree = write_tree(gitdir, read_index(gitdir), str(gitdir.parent)) parent_commit = resolve_head(gitdir) commit_hash = commit_tree(gitdir, tree, message, parent_commit, author) return commit_hash
def checkout(gitdir: pathlib.Path, obj_name: str) -> None: for entry in read_index(gitdir): try: os.remove(entry.name) except FileNotFoundError: pass com = commit_parse(read_object(obj_name, gitdir)[1]) finished = False while not finished: trees: tp.List[tp.Tuple[pathlib.Path, tp.List[tp.Tuple[int, str, str]]]] trees = [(gitdir.parent, read_tree(read_object(com["tree"], gitdir)[1]))] while trees: tree_path, tree_content = trees[-1] del trees[-1] for file_data in tree_content: fmt, data = read_object(file_data[2], gitdir) if fmt == "tree": trees.append((tree_path / file_data[1], read_tree(data))) if not (tree_path / file_data[1]).exists(): (tree_path / file_data[1]).mkdir() else: if not (tree_path / file_data[1]).exists(): with (tree_path / file_data[1]).open("wb") as f: f.write(data) (tree_path / file_data[1]).chmod(int(str(file_data[0]), 8)) if "parent" in com: com.append(commit_parse((read_object(com["parent"], gitdir)[1]))) else: finished = True for dir in gitdir.parent.glob("*"): if dir != gitdir and dir.is_dir(): try: os.removedirs(dir) except OSError: continue
def checkout(gitdir: pathlib.Path, obj_name: str) -> None: if is_detached(gitdir) and get_ref(gitdir) == obj_name: return elif get_ref(gitdir).split("/")[2] == obj_name: return elif resolve_head(gitdir) == obj_name: return elif (gitdir / 'refs' / 'heads' / obj_name).exists(): with open(gitdir / 'refs' / 'heads' / obj_name, 'r') as file: obj_name = file.read() index = read_index(gitdir) for entry in index: if pathlib.Path(entry.name).exists(): if '/' in entry.name: shutil.rmtree(entry.name[:entry.name.find('/')]) else: os.remove(entry.name) path_to_commit = gitdir / "objects" / obj_name[:2] / obj_name[2:] if path_to_commit: with open(path_to_commit, 'rb') as file: raw = file.read() data = commit_parse(raw) tree_sha = data[data.find(b'tree ') + 5:data.find(b'\n')].decode() for file in find_tree_files(tree_sha, gitdir): if '/' in file[0]: dir_name = file[0][:file[0].find('/')] os.mkdir(dir_name) with open(file[0], 'w') as new_file: header, content = read_object(file[1], gitdir) new_file.write(content.decode())
def checkout(gitdir: pathlib.Path, obj_name: str) -> None: if is_detached(gitdir) and get_ref(gitdir) == obj_name: return elif get_ref(gitdir).split("/")[2] == obj_name: return elif resolve_head(gitdir) == obj_name: return elif (gitdir / "refs" / "heads" / obj_name).exists(): with open(gitdir / "refs" / "heads" / obj_name, "r") as f1: obj_name = f1.read() index = read_index(gitdir) for entry in index: if os.path.exists(entry.name): if "/" in entry.name: shutil.rmtree(entry.name[:entry.name.find("/")]) else: os.remove(entry.name) with open(gitdir / "objects" / obj_name[:2] / obj_name[2:], "rb") as f2: commit_content = f2.read() tree_sha = commit_parse(commit_content).decode() for file in find_tree_files(tree_sha, gitdir): if "/" in file[0]: dir_name = file[0][:file[0].find("/")] os.mkdir(dir_name) with open(file[0], "w") as f3: header, content = read_object(file[1], gitdir) f3.write(content.decode())
def commit(gitdir: pathlib.Path, message: str, author: tp.Optional[str] = None) -> str: hash_commit = commit_tree( gitdir, write_tree(gitdir, read_index(gitdir), str(gitdir.parent)), message, resolve_head(gitdir), author) return hash_commit
def commit(gitdir: pathlib.Path, message: str, author: tp.Optional[str] = None) -> str: # PUT YOUR CODE HERE tree = write_tree(gitdir, read_index(gitdir)) commit = commit_tree(gitdir, tree, message, author=author) return commit
def checkout(gitdir: pathlib.Path, obj_name: str) -> None: head_route = gitdir / "refs" / "heads" / obj_name if head_route.exists(): with head_route.open(mode="r") as f1: obj_name = f1.read() index = read_index(gitdir) for entry in index: if pathlib.Path(entry.name).is_file(): if "/" in entry.name: shutil.rmtree(entry.name[:entry.name.find("/")]) else: # os.umask(777) os.chmod(entry.name, 777) # time.sleep(2) os.remove(entry.name) object_all_path = gitdir / "objects" / obj_name[:2] / obj_name[2:] with object_all_path.open(mode="rb") as f2: commit_content = f2.read() tree_sha = commit_parse(commit_content).decode() for file in find_tree_files(tree_sha, gitdir): if "/" in file[0]: dir_name = file[0][:file[0].find("/")] os.mkdir(dir_name) with open(file[0], "w") as f3: header, content = read_object(file[1], gitdir) f3.write(content.decode())
def commit(gitdir: pathlib.Path, message: str, author: tp.Optional[str] = None) -> str: # PUT YOUR CODE HERE parent = resolve_head(gitdir) tree = write_tree(gitdir, read_index(gitdir), str(gitdir.parent)) com = commit_tree(gitdir, tree, message, parent, author) return com
def test_read_index(self): gitdir = repo_create(".") raw_index = 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.fs.create_file(gitdir / "index", contents=raw_index) entries = read_index(gitdir) self.assertEqual(3, len(entries)) # TODO: Add sha self.assertEqual(["bar.txt", "baz/numbers.txt", "foo.txt"], [e.name for e in entries])
def commit(gitdir: pathlib.Path, message: str, author: tp.Optional[str] = None) -> str: commit_sha = commit_tree(gitdir, write_tree(gitdir, read_index(gitdir)), message, author=author) if is_detached(gitdir): ref = gitdir / "HEAD" else: ref = pathlib.Path(get_ref(gitdir)) f = open(gitdir / ref, "w") f.write(commit_sha) f.close() return commit_sha
def checkout(gitdir: pathlib.Path, obj_name: str) -> None: # PUT YOUR CODE HERE indexes = [index.name for index in read_index(gitdir)] catalog = gitdir.parent for obj in catalog.iterdir(): if obj in [gitdir.name]: continue if obj.name in indexes: os.remove(obj) commit = read_object(obj_name, gitdir)[1].decode() tree = commit.split()[1] #разделяет по всем нечитаемым символам
def test_write_tree(self): gitdir = repo_create(".") animals = pathlib.Path("animals.txt") mode100644 = stat.S_IFREG | stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH self.fs.create_file( animals, contents="Big blue basilisks bawl in the basement\n", st_mode=mode100644, ) update_index(gitdir, [animals], write=True) entries = read_index(gitdir) sha = write_tree(gitdir, entries) self.assertEqual("dc6b8ea09fb7573a335c5fb953b49b85bb6ca985", sha)
def test_update_index(self): gitdir = repo_create(".") index = gitdir / "index" quote = pathlib.Path("quote.txt") self.fs.create_file(quote, contents="that's what she said") self.assertFalse(index.exists()) update_index(gitdir, [quote]) self.assertTrue(index.exists()) entries = read_index(gitdir) self.assertEqual(1, len(entries)) expected_sha = "7e774cf533c51803125d4659f3488bd9dffc41a6" obj_path = gitdir / "objects" / expected_sha[:2] / expected_sha[2:] self.assertTrue(obj_path.exists())
def commit(gitdir: pathlib.Path, message: str, author: tp.Optional[str] = None) -> str: # делаем сам коммит files_in_index = read_index(gitdir) tree_hash = write_tree(gitdir, files_in_index) parent = resolve_head(gitdir) commit_sha = commit_tree(gitdir, tree_hash, message, parent=parent, author=author) update_ref(gitdir, get_ref(gitdir), commit_sha) return commit_sha
def test_update_index_many(self): gitdir = repo_create(".") index = gitdir / "index" letters = pathlib.Path("letters.txt") self.fs.create_file(letters, contents="abcdefg") digits = pathlib.Path("digits.txt") self.fs.create_file(digits, contents="1234567890") self.assertFalse(index.exists()) update_index(gitdir, [letters, digits]) self.assertTrue(index.exists()) entries = read_index(gitdir) self.assertEqual(2, len(entries)) names = [e.name for e in entries] self.assertEqual(["digits.txt", "letters.txt"], names)
def test_update_index_subdirs(self): gitdir = repo_create(".") index = gitdir / "index" quote = pathlib.Path("quote.txt") self.fs.create_file(quote, contents="that's what she said") letters = pathlib.Path("alphabeta") / "letters.txt" self.fs.create_file(letters, contents="abcdefg") digits = pathlib.Path("numbers") / "digits.txt" self.fs.create_file(digits, contents="1234567890") self.assertFalse(index.exists()) update_index(gitdir, [quote, letters, digits]) self.assertTrue(index.exists()) entries = read_index(gitdir) self.assertEqual(3, len(entries)) names = [e.name for e in entries] self.assertEqual(["alphabeta/letters.txt", "numbers/digits.txt", "quote.txt"], names)
def checkout(gitdir: pathlib.Path, obj_name: str) -> None: index = read_index(gitdir) for entry in index: if pathlib.Path(entry.name).exists(): os.remove(entry.name) commit_data = commit_parse(read_object(obj_name, gitdir)[1]) end = False while not end: trees: tp.List[tp.Tuple[pathlib.Path, tp.List[tp.Tuple[int, str, str]]]] = [ (gitdir.parent, read_tree( read_object(commit_data["tree"], gitdir)[1])) ] while trees: tree_path, tree_content = trees.pop() for file_data in tree_content: fmt, data = read_object(file_data[1], gitdir) if fmt == "tree": trees.append((tree_path / file_data[2], read_tree(data))) if not (tree_path / file_data[2]).exists(): (tree_path / file_data[2]).mkdir() else: if not (tree_path / file_data[2]).exists(): with (tree_path / file_data[2]).open("wb") as f: f.write(data) (tree_path / file_data[2]).chmod( int(str(file_data[0]), 8)) if "parent" in commit_data: commit_data = commit_parse((read_object(commit_data["parent"], gitdir)[1])) else: end = True dirs = gitdir.parent.glob("*") for dir in dirs: if dir != gitdir and dir.is_dir(): try: os.removedirs(dir) except OSError: continue
def checkout(gitdir: pathlib.Path, obj_name: str) -> None: update_ref(gitdir, "HEAD", obj_name) index_names = [entry.name for entry in read_index(gitdir)] _, commit_data = read_object(obj_name, gitdir) tree_hash = commit_parse(commit_data) files = find_tree_files(tree_hash, gitdir) to_be_updated = [pathlib.Path(i[1]) for i in files] update_index(gitdir, to_be_updated, write=True) for name in index_names: nodes = name.split("\\") if pathlib.Path(nodes[0]).is_dir(): shutil.rmtree(nodes[0]) else: if pathlib.Path(nodes[0]).exists(): os.remove(nodes[0]) for sha, name in files: if name.find("\\") != -1: prefix, _ = os.path.split(name) if not pathlib.Path(prefix).exists(): os.makedirs(prefix) _, content = read_object(sha, gitdir) with open(name, "wb") as file_obj: file_obj.write(content)
def checkout(gitdir: pathlib.Path, obj_name: str) -> None: # PUT YOUR CODE HERE for entry in read_index(gitdir): if pathlib.Path(entry.name).exists(): os.remove(entry.name) commit_data = commit_parse(read_object(obj_name, gitdir)[1]) doing = True while doing: trees: tp.List[tp.Tuple[tp.List[tp.Tuple[int, str, str]], pathlib.Path]] = [(read_tree( read_object(commit_data["tree"], gitdir)[1]), gitdir.parent)] while trees: tree_content, tree_path = trees.pop() for file_data in tree_content: fmt, data = read_object(file_data[2], gitdir) if fmt != "tree": if not (tree_path / file_data[1]).exists(): with (tree_path / file_data[1]).open("wb") as file: file.write(data) (tree_path / file_data[1]).chmod( int(str(file_data[0]), 8)) else: if not (tree_path / file_data[1]).exists(): (tree_path / file_data[1]).mkdir() trees.append((read_tree(data), tree_path / file_data[1])) if "parent" in commit_data: commit_data = commit_parse((read_object(commit_data["parent"], gitdir)[1])) else: doing = not doing for dir in gitdir.parent.glob("*"): if dir.is_dir() and dir != gitdir: try: os.removedirs(dir) except OSError: continue
def cmd_write_tree(args: argparse.Namespace) -> None: gitdir = repo_find() entries = read_index(gitdir) sha = write_tree(gitdir, entries) print(sha)
def commit(gitdir: pathlib.Path, message: str, author: tp.Optional[str] = None) -> str: tree = write_tree(gitdir, read_index(gitdir)) return commit_tree(gitdir, tree, message, parent=None, author=author)
def test_read_index_when_index_doesnt_exist(self): gitdir = repo_create(".") entries = read_index(gitdir) self.assertEqual(0, len(entries)) self.assertEqual([], entries)