◐ Shell
reader mode source ↗
Skip to content
Merged
Show file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
16 changes: 11 additions & 5 deletions git/index/fun.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
)
from git.util import IndexFileSHA1Writer, finalize_process

from .typ import BaseIndexEntry, IndexEntry, CE_NAMEMASK, CE_STAGESHIFT
from .util import pack, unpack

# typing -----------------------------------------------------------------------------
Expand Down Expand Up @@ -158,7 +158,7 @@ def write_cache(
write = stream_sha.write

# Header
version = 2
write(b"DIRC")
write(pack(">LL", version, len(entries)))

Expand All @@ -172,6 +172,8 @@ def write_cache(
plen = len(path) & CE_NAMEMASK # Path length
assert plen == len(path), "Path %s too long to fit into index" % entry.path
flags = plen | (entry.flags & CE_NAMEMASK_INV) # Clear possible previous values.
write(
pack(
">LLLLLL20sH",
Expand All @@ -185,6 +187,8 @@ def write_cache(
flags,
)
)
write(path)
real_size = (tell() - beginoffset + 8) & ~7
write(b"\0" * ((beginoffset + real_size) - tell()))
Expand All @@ -206,8 +210,7 @@ def read_header(stream: IO[bytes]) -> Tuple[int, int]:
unpacked = cast(Tuple[int, int], unpack(">LL", stream.read(4 * 2)))
version, num_entries = unpacked

# TODO: Handle version 3: extended data, see read-cache.c.
assert version in (1, 2), "Unsupported git index version %i, only 1 and 2 are supported" % version
return version, num_entries


Expand Down Expand Up @@ -260,12 +263,15 @@ def read_cache(
ctime = unpack(">8s", read(8))[0]
mtime = unpack(">8s", read(8))[0]
(dev, ino, mode, uid, gid, size, sha, flags) = unpack(">LLLLLL20sH", read(20 + 4 * 6 + 2))
path_size = flags & CE_NAMEMASK
path = read(path_size).decode(defenc)

real_size = (tell() - beginoffset + 8) & ~7
read((beginoffset + real_size) - tell())
entry = IndexEntry((mode, sha, flags, path, ctime, mtime, dev, ino, uid, gid, size))
# entry_key would be the method to use, but we save the effort.
entries[(path, entry.stage)] = entry
count += 1
Expand Down
15 changes: 14 additions & 1 deletion git/index/typ.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
CE_VALID = 0x8000
CE_STAGESHIFT = 12

# } END invariants


Expand Down Expand Up @@ -87,6 +90,8 @@ class BaseIndexEntryHelper(NamedTuple):
uid: int = 0
gid: int = 0
size: int = 0


class BaseIndexEntry(BaseIndexEntryHelper):
Expand All @@ -102,7 +107,7 @@ def __new__(
cls,
inp_tuple: Union[
Tuple[int, bytes, int, PathLike],
Tuple[int, bytes, int, PathLike, bytes, bytes, int, int, int, int, int],
],
) -> "BaseIndexEntry":
"""Override ``__new__`` to allow construction from a tuple for backwards
Expand Down Expand Up @@ -134,6 +139,14 @@ def stage(self) -> int:
"""
return (self.flags & CE_STAGEMASK) >> CE_STAGESHIFT

@classmethod
def from_blob(cls, blob: Blob, stage: int = 0) -> "BaseIndexEntry":
""":return: Fully equipped BaseIndexEntry at the given stage"""
Expand Down
42 changes: 42 additions & 0 deletions test/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,48 @@ def test_index_add_non_normalized_path(self, rw_repo):

rw_repo.index.add(non_normalized_path)


class TestIndexUtils:
@pytest.mark.parametrize("file_path_type", [str, Path])
Loading
Toggle all file notes Toggle all file annotations