예제 #1
0
def resolve_object(obj_name: str, gitdir: pathlib.Path) -> tp.List[str]:
    if 4 > len(obj_name) or len(obj_name) > 40:
        raise Exception(f"Not a valid object name {obj_name}")
    objects = repo_find() / "objects"
    obj_list = []
    for file in (objects / obj_name[:2]).glob("*"):
        cur_obj_name = file.parent.name + file.name
        if obj_name == cur_obj_name[:len(obj_name)]:
            obj_list.append(cur_obj_name)
    if not obj_list:
        raise Exception(f"Not a valid object name {obj_name}")
    return obj_list
예제 #2
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    sha = hashlib.sha1((fmt + " " + str(len(data))).encode() + b"\00" +
                       data).hexdigest()
    if write:
        obj_dir = repo_find() / "objects" / sha[:2]
        if not obj_dir.exists():
            obj_dir.mkdir()
        with (obj_dir / sha[2:]).open("wb") as file:
            file.write(
                zlib.compress((fmt + " " + str(len(data))).encode() + b"\00" +
                              data))
    return sha
예제 #3
0
def cat_file(obj_name: str, pretty: bool = True) -> None:
    gitdir = repo_find()
    fmt, file_content = read_object(obj_name, gitdir)
    blob_or_commit_tuple = ("blob", "commit")
    if fmt in blob_or_commit_tuple:
        print(file_content.decode())
    else:
        for tree in read_tree(file_content):
            if tree[0] != 40000:
                print(f"{tree[0]:06}", "blob", tree[2] + "\t" + tree[1])
            else:
                print(f"{tree[0]:06}", "tree", tree[2] + "\t" + tree[1])
예제 #4
0
def read_index(gitdir: pathlib.Path) -> tp.List[GitIndexEntry]:
    repo = repo_find() / "index"
    entries = []

    if repo.exists():
        with open(repo, "rb") as f:
            _ = f.read(8)
            num_entries = struct.unpack("!I", f.read(4))[0]
            for entry in range(num_entries):
                indexEntry = {}

                indexEntry['ctime_s'] = struct.unpack(
                    "!I", f.read(struct.calcsize("I")))[0]
                indexEntry['ctime_n'] = struct.unpack(
                    "!I", f.read(struct.calcsize("I")))[0]
                indexEntry['mtime_s'] = struct.unpack(
                    "!I", f.read(struct.calcsize("I")))[0]
                indexEntry['mtime_n'] = struct.unpack(
                    "!I", f.read(struct.calcsize("I")))[0]
                indexEntry['dev'] = struct.unpack("!I",
                                                  f.read(
                                                      struct.calcsize("I")))[0]
                indexEntry['ino'] = struct.unpack("!I",
                                                  f.read(
                                                      struct.calcsize("I")))[0]
                indexEntry['mode'] = struct.unpack(
                    "!I", f.read(struct.calcsize("I")))[0]
                indexEntry['uid'] = struct.unpack("!I",
                                                  f.read(
                                                      struct.calcsize("I")))[0]
                indexEntry['gid'] = struct.unpack("!I",
                                                  f.read(
                                                      struct.calcsize("I")))[0]
                indexEntry['size'] = struct.unpack(
                    "!I", f.read(struct.calcsize("I")))[0]

                indexEntry['sha1'] = struct.unpack(
                    "!20s", f.read(struct.calcsize("20s")))[0]
                indexEntry['flags'] = struct.unpack(
                    "!H", f.read(struct.calcsize("H")))[0]
                namelen = indexEntry['flags'] & 0xFFF
                indexEntry['name'] = struct.unpack(
                    "!" + str(namelen) + "s",
                    f.read(struct.calcsize("!" + str(namelen) +
                                           "s")))[0].decode()

                entries.append(GitIndexEntry(**indexEntry))
                nuls = 3
                _ = f.read(nuls)

    entries.sort(key=lambda x: x.name)
    return entries
예제 #5
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    # PUT YOUR CODE HERE
    header = f"{fmt} {len(data)}\0".encode()
    store = header + data
    res = hashlib.sha1(store).hexdigest()
    if write:
        path = repo_find() / "objects" / res[:2]
        path.mkdir(exist_ok=True)
        with (path / res[2:]).open("wb") as f:
            new_data = (fmt + " " + str(len(data))).encode()
            new_data = new_data + b"\00" + data
            f.write(zlib.compress(new_data))
    return res
예제 #6
0
def resolve_object(obj_name: str, gitdir: pathlib.Path) -> tp.List[str]:
    if len(obj_name) < 4 or len(obj_name) > 40:
        raise Exception(f"Not a valid object name {obj_name}")

    result = []
    path = repo_find(gitdir) / "objects" / obj_name[:2]
    for root, dir, files in os.walk(path):
        for filename in files:
            if filename.startswith(obj_name[2:]):
                result.append(obj_name[:2] + filename)
            else:
                raise Exception(f"Not a valid object name {obj_name}")
    return result
예제 #7
0
def cat_file(obj_name: str, pretty: bool = True) -> None:
    gitdir = repo_find()
    obj_type, content = read_object(obj_name, gitdir)
    if obj_type == "blob":
        if pretty:
            result = content.decode("ascii")
            print(result)
        else:
            result = str(content)
            print(result)
    elif obj_type == "tree":
        tree_entries = read_tree(content)
        result = ""
        for entry in tree_entries:
            mode = str(entry[0])
            if len(mode) != 6:
                mode = "0" + mode
            tree_pointer_type, _ = read_object(entry[1], gitdir)
            print(f"{mode} {tree_pointer_type} {entry[1]}\t{entry[2]}")
    else:
        _, content = read_object(resolve_object(obj_name, repo_find())[0], repo_find())
        print(content.decode())
예제 #8
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    # PUT YOUR CODE HERE
    formatted_data = (fmt + f" {len(data)}\0").encode() + data
    hash_str = hashlib.sha1(formatted_data).hexdigest()
    if write:
        dir_path = repo_find(".") / "objects"
        try:
            dir_path /= hash_str[:2]
            dir_path.mkdir()
        except FileExistsError:
            pass
        with (dir_path / hash_str[2:]).open("wb") as f:
            f.write(zlib.compress(formatted_data))
    return hash_str
예제 #9
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    header = f'{fmt} {len(data)}\0'.encode()
    store = header + data
    sha1 = hashlib.sha1(store).hexdigest()

    if write:
        gitdir = repo_find()
        blob_folder = gitdir.joinpath(f'objects/{sha1[:2]}')
        blob_folder.mkdir(parents=False, exist_ok=True)
        with open(blob_folder.joinpath(sha1[2:]), 'wb') as blob_file:
            zipped_store = zlib.compress(store)
            blob_file.write(zipped_store)

    return sha1
예제 #10
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    header = f"{fmt} {len(data)}\0".encode()
    store = header + data
    obj_hash = hashlib.sha1(store).hexdigest()
    obj = zlib.compress(store)
    if write:
        gitdir = repo_find()
        obj_dir = pathlib.Path(str(gitdir) + "/objects/" + obj_hash[:2])
        if not obj_dir.is_dir():
            os.makedirs(obj_dir)
        obj_name = obj_dir / obj_hash[2:]
        with open(obj_name, "wb") as obj_file:
            obj_file.write(obj)
    return obj_hash
예제 #11
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    # PUT YOUR CODE HERE
    objects = "objects"
    sha = hashlib.sha1((fmt + " " + str(len(data))).encode() + b"\00" +
                       data).hexdigest()
    if write:
        gitdir = repo_find()
        if not (gitdir / objects / sha[:2]).exists():
            (gitdir / objects / sha[:2]).mkdir()
        with (gitdir / objects / sha[:2] / sha[2:]).open("wb") as file:
            file.write(
                zlib.compress((fmt + " " + str(len(data))).encode() + b"\00" +
                              data))
    return sha
예제 #12
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:

    header = f"{fmt} {len(data)}\0"
    store = header.encode() + data
    res = hashlib.sha1(store).hexdigest()
    if write:
        obj_dir = repo_find() / "objects" / res[0:2]
        if not obj_dir.exists():
            obj_dir.mkdir()
        with (obj_dir / res[2:]).open("wb") as file:
            file.write(
                zlib.compress((fmt + " " + str(len(data))).encode() + b"\00" +
                              data))
    return res
예제 #13
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    header = f"{fmt} {len(data)}\0"
    store = header.encode() + data
    result = hashlib.sha1(store).hexdigest()
    if write:
        gitdir = repo_find(os.getcwd())
        os.makedirs(gitdir / "objects" / result[0:2], exist_ok=True)
        pathlib.Path(gitdir / "objects" / result[0:2] / result[2:]).touch()
        cur_file = open(gitdir / "objects" / result[0:2] / result[2:], "wb")
        level = -1
        if fmt == "tree":
            level = 1
        cur_file.write(zlib.compress(store, level))
        cur_file.close()
    return result
예제 #14
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    header = (fmt + f" {len(data)}\0").encode()
    store = header + data
    hash_obj = hashlib.sha1(store).hexdigest()

    if write:
        repo = repo_find()
        objects = repo / "objects" / hash_obj[:2]
        if not objects.exists():
            objects.mkdir()

        with open(objects / hash_obj[2:], "wb") as f:
            compressed = zlib.compress(store)
            f.write(compressed)

    return hash_obj
예제 #15
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    header = f"{fmt} {len(data)}\0".encode()
    line = header + data
    sha = hashlib.sha1(line).hexdigest()
    if write:
        dir_name = sha[:2]
        file_name = sha[2:]

        path = repo_find() / 'objects' / dir_name
        if not path.exists():
            path.mkdir()

            with open(str(path / file_name), 'wb+') as file:
                file.write(zlib.compress(line))

    return sha
예제 #16
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    header = f"{fmt} {len(data)}\0"
    store = header.encode() + data
    hash_name = hashlib.sha1(store).hexdigest()

    if write:
        path = repo_find() / "objects" / hash_name[:2]

        if os.path.exists(path / hash_name[2:]):
            return hash_name

        os.mkdir(path)
        with open(path / hash_name[2:], "wb") as f:
            f.write(zlib.compress(store))

    return hash_name
예제 #17
0
파일: objects.py 프로젝트: Sofshik/cs102
def resolve_object(obj_name: str, gitdir: pathlib.Path) -> tp.List[str]:
    objects = "objects"
    if not 4 < len(obj_name) < 40:
        raise Exception(f"Not a valid object name {obj_name}")
    gitdir = repo_find()
    obj_list = []
    for dir in (gitdir / objects).glob("*"):
        if not dir.is_dir():
            continue
        for file in dir.glob("*"):
            cur_obj_name = file.parent.name + file.name
            if obj_name == cur_obj_name[:len(obj_name)]:
                obj_list.append(cur_obj_name)
    if not obj_list:
        raise Exception(f"Not a valid object name {obj_name}")
    return obj_list
예제 #18
0
def cat_file(obj_name: str, pretty: bool = True) -> None:
    gitdir = repo_find()
    fmt, content = read_object(obj_name, gitdir)
    if fmt == "blob":
        print(content.decode("ascii") if pretty else str(content))
    elif fmt == "tree":
        tree = read_tree(content)
        for i in tree:
            mode = i[0]
            mode = str(mode)
            lenght, value = len(mode), 6
            if lenght != value:
                mode = "0" + mode
            print(f"{mode} {read_object(i[1], gitdir)[0]} {i[1]}\t{i[2]}")
    else:
        obj_name1 = resolve_object(obj_name, gitdir)[0]
        print(read_object(obj_name1, gitdir)[1].decode())
예제 #19
0
def resolve_object(obj_name: str, gitdir: pathlib.Path) -> tp.List[str]:
    if len(obj_name) < 4 or len(obj_name) > 40:
        raise Exception(f"Not a valid object name {obj_name}")

    repo = repo_find()
    obj_path = repo / "objects" / obj_name[:2]
    objects = []

    if obj_path.exists() and obj_path.is_dir():
        for child in obj_path.iterdir():
            if child.name[:3] == obj_name[2:]:
                objects.append(obj_name[:2] + child.name)

    if len(objects) == 0:
        raise Exception(f"Not a valid object name {obj_name}")

    return objects
예제 #20
0
def cat_file(obj_name: str, pretty: bool = True) -> None:
    repo = repo_find()

    read_obj = read_object(obj_name, repo)
    if read_obj[0] == "blob":
        print(read_object(obj_name, repo)[1].decode())
    elif read_obj[0] == "tree":
        objs = read_tree(read_obj[1])
        s = ""
        for obj in objs:
            if obj[0] == 40000:
                s += f"0{obj[0]} tree {obj[2]}\t{obj[1]}\n"
            else:
                s += f"{obj[0]} blob {obj[2]}\t{obj[1]}\n"
        print(s)
    elif read_obj[0] == "commit":
        print(read_obj[1].decode())
예제 #21
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    header = f"{fmt} {len(data)}\0"
    store = header.encode() + data
    result = hashlib.sha1(store).hexdigest()
    content = zlib.compress(store)

    if write:
        workdir = pathlib.Path(".").absolute()
        gitdir = repo_find(workdir)

        if not pathlib.Path.exists(gitdir / "objects" / result[0:2]):
            (gitdir / "objects" / result[0:2]).mkdir()
        if not pathlib.Path.exists(
                gitdir / "objects" / result[0:2] / result[:2]):
            (gitdir / "objects" / result[0:2] /
             result[2:]).write_bytes(content)

    return result
예제 #22
0
def read_tree(data: bytes) -> tp.List[tp.Tuple[int, str, str]]:
    tree_entries: tp.List[tp.Tuple[int, str, str]] = []
    while len(data):
        sha = bytes.hex(data[-20:])
        data = data[:-21]
        obj_type, _ = read_object(sha, repo_find())
        space_pos = data.rfind(b" ")
        name = data[space_pos + 1 :].decode("ascii")
        data = data[:space_pos]
        if obj_type == "tree":
            mode = "40000"
        else:
            mode = data[-6:].decode("ascii")
        mode_len = -1 * len(mode)
        data = data[:mode_len]
        mode_int = int(mode)
        tree_entries.insert(0, (mode_int, sha, name))
    return tree_entries
예제 #23
0
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    if fmt == "blob":
        content = data.decode()
        header = f"{fmt} {len(content)}\0"
        store = header + content
        hash_object = hashlib.sha1(store.encode())
        hex_dig = hash_object.hexdigest()
    if fmt == "tree" or fmt == "commit":
        header = f"{fmt} {len(data)}\0"
        store = header.encode() + data
        hash_object = hashlib.sha1(store)
        hex_dig = hash_object.hexdigest()
    if write == True:
        path = repo_find()
        paths = pathlib.Path(path, "objects")
        if fmt == "tree":
            content = data
            header = f"{fmt} {len(content)}\0"
            store = header.encode() + content
            hash_object = hashlib.sha1(store)
        else:
            content = data.decode()
            header = f"{fmt} {len(content)}\0"
            store = header + content
            hash_object = hashlib.sha1(store.encode())
        hex_dig = hash_object.hexdigest()
        start = hex_dig[0:2]
        continues = hex_dig[2:]
        if not os.path.exists(pathlib.Path(paths / start)):
            os.mkdir(pathlib.Path(paths / start))
        if not os.path.exists(pathlib.Path(paths / start / continues)):
            pathlib.Path(paths / start / continues).touch()
        lib = pathlib.Path(paths / start / continues)
        with lib.open(mode="wb") as f:
            if fmt == "blob" or fmt == "commit":
                a = zlib.compress(store.encode(), -1)
            if fmt == "tree":
                a = zlib.compress(store, 1)
            f.write(a)
            f.close()
    return hex_dig
예제 #24
0
파일: objects.py 프로젝트: toofnf/dementiy
def cat_file(obj_name: str, pretty: bool = True) -> None:
    """
    :version: 0.3.0 + 0.6.0

    Вывод файлов, аналог функции cat

    :param obj_name:
    :param pretty:
    :return:
    """
    gitdir = repo_find()
    fmt, data = read_object(obj_name, gitdir)
    if fmt in ("blob", "commit"):
        print(data.decode() if pretty else data)
    else:
        for tree in read_tree(data):
            print(
                f"{tree[0]:06}",
                "tree" if tree[0] == 40000 else "blob",
                tree[2] + "\t" + tree[1]
            )
예제 #25
0
파일: objects.py 프로젝트: toofnf/dementiy
def hash_object(data: bytes, fmt: str, write: bool = False) -> str:
    """
    Вычисление хэш-суммы

    :version: 0.2.0

    :param data:
    :param fmt:
    :param write:
    :return:
    """
    store = f"{fmt} {len(data)}\0".encode() + data
    hash_sum = hashlib.sha1(store).hexdigest()
    if write:
        folder_name, file_name = hash_sum[:2], hash_sum[2:]
        obj_dir = repo_find() / "objects" / folder_name
        if not obj_dir.exists():
            obj_dir.mkdir()

        with open(obj_dir / file_name, "wb") as f:
            f.write(zlib.compress(store))
    return hash_sum
예제 #26
0
def cat_file(obj_name: str, pretty: bool = True) -> None:
    # PUT YOUR CODE HERE
    data = read_object(obj_name, repo_find("."))
    if data[0] in ("blob", "commit"):
        out = data[1].decode()
        if pretty:
            print(out)
        else:
            print(data[0], out)
    elif data[0] == "tree":
        out1 = read_tree(data[1])
        if pretty:
            print(
                *[f'{x[0]:06} {"tree" if x[0] == 40000 else "blob"} {x[2]}\t{x[1]}' for x in out1],
                sep="\n",
            )
        else:
            print(
                data[0],
                "\n".join(
                    f'{x[0]:06} {"tree" if x[0] == 40000 else "blob"} {x[2]}\t{x[1]}' for x in out1
                ),
            )
예제 #27
0
def read_tree(data: bytes) -> tp.List[tp.Tuple[int, str, str]]:
    tree = []
    while len(data) > 0:
        border = -21
        sha = bytes.hex(data[border+1:])
        data = data[:border]

        gitdir = repo_find()
        fmt, content = read_object(sha, gitdir)

        border = data.rfind(b" ")
        name = data[border+1:].decode("ascii")
        data = data[:border]

        border = -6
        mode = "40000" if fmt == "tree" else data[border:].decode("ascii")
        border = len(mode)
        mode = int(mode)
        data = data[:-border]

        tuple = mode, sha, name
        tree.insert(0, tuple)
    return tree
예제 #28
0
def cat_file(obj_name: str, pretty: bool = True) -> None:
    gitdir = repo_find()
    shas = resolve_object(obj_name, gitdir)
    if len(shas) > 1:
        raise Exception('specify longer name')
    sha = shas[0]
    object_type, object_content_bytes = read_object(sha, gitdir)
    if object_type == 'tree':
        permissions, shas, names = read_tree(object_content_bytes)
        resulting_string = ''
        for i in range(len(shas)):

            perm = permissions[i]
            sha = shas[i]
            name = names[i]
            type = 'tree' if perm == '040000' else 'blob'
            resulting_string += f'{perm} {type} {sha}\t{name}\n'

        if pretty:
            print(resulting_string)
    else:
        object_content_decoded = object_content_bytes.decode('ascii')
        if pretty:
            print(object_content_decoded)
예제 #29
0
 def test_repo_not_found(self):
     with self.assertRaises(Exception) as ctx:
         _ = repo.repo_find()
     self.assertEqual("Not a git repository", str(ctx.exception))
예제 #30
0
파일: objects.py 프로젝트: tashareva/cs1024
def read_object(sha: str, gitdir: pathlib.Path) -> tp.Tuple[str, bytes]:
    objects = repo_find() / "objects"
    with (objects / sha[:2] / sha[2:]).open("rb") as f:
        data = zlib.decompress(f.read())
    return (data.split(b"\00")[0].split(b" ")[0].decode(),
            data.split(b"\00", maxsplit=1)[1])