summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYobmod <yobmod@gmail.com>2021-07-24 19:46:52 +0100
committerYobmod <yobmod@gmail.com>2021-07-24 19:46:52 +0100
commit2bc2ac02e270404fcb609eeacc4feea6146b9d2e (patch)
tree9aff529055b02c196aba1ca76b4ddb547090ddc0
parent4b6430bad60ff491239fe06c41a43b498e0c883f (diff)
downloadgitpython-2bc2ac02e270404fcb609eeacc4feea6146b9d2e.tar.gz
Use BaseIndexEntry named access in index/fun.py
-rw-r--r--git/index/fun.py17
-rw-r--r--git/index/typ.py81
2 files changed, 38 insertions, 60 deletions
diff --git a/git/index/fun.py b/git/index/fun.py
index 3b963a2b..49e3f2c5 100644
--- a/git/index/fun.py
+++ b/git/index/fun.py
@@ -57,6 +57,7 @@ from git.types import PathLike
if TYPE_CHECKING:
from .base import IndexFile
+ from git.db import GitCmdObjectDB
from git.objects.tree import TreeCacheTup
# from git.objects.fun import EntryTupOrNone
@@ -149,15 +150,15 @@ def write_cache(entries: Sequence[Union[BaseIndexEntry, 'IndexEntry']], stream:
# body
for entry in entries:
beginoffset = tell()
- write(entry[4]) # ctime
- write(entry[5]) # mtime
- path_str: str = entry[3]
+ write(entry.ctime_bytes) # ctime
+ write(entry.mtime_bytes) # mtime
+ path_str = str(entry.path)
path: bytes = force_bytes(path_str, encoding=defenc)
plen = len(path) & CE_NAMEMASK # path length
- assert plen == len(path), "Path %s too long to fit into index" % entry[3]
- flags = plen | (entry[2] & CE_NAMEMASK_INV) # clear possible previous values
- write(pack(">LLLLLL20sH", entry[6], entry[7], entry[0],
- entry[8], entry[9], entry[10], entry[1], flags))
+ 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", entry.dev, entry.inode, entry.mode,
+ entry.uid, entry.gid, entry.size, entry.binsha, flags))
write(path)
real_size = ((tell() - beginoffset + 8) & ~7)
write(b"\0" * ((beginoffset + real_size) - tell()))
@@ -311,7 +312,7 @@ def _tree_entry_to_baseindexentry(tree_entry: 'TreeCacheTup', stage: int) -> Bas
return BaseIndexEntry((tree_entry[1], tree_entry[0], stage << CE_STAGESHIFT, tree_entry[2]))
-def aggressive_tree_merge(odb, tree_shas: Sequence[bytes]) -> List[BaseIndexEntry]:
+def aggressive_tree_merge(odb: 'GitCmdObjectDB', tree_shas: Sequence[bytes]) -> List[BaseIndexEntry]:
"""
:return: list of BaseIndexEntries representing the aggressive merge of the given
trees. All valid entries are on stage 0, whereas the conflicting ones are left
diff --git a/git/index/typ.py b/git/index/typ.py
index bb1a0384..5b2ad5f6 100644
--- a/git/index/typ.py
+++ b/git/index/typ.py
@@ -11,7 +11,7 @@ from git.objects import Blob
# typing ----------------------------------------------------------------------
-from typing import (List, Sequence, TYPE_CHECKING, Tuple, cast)
+from typing import (NamedTuple, Sequence, TYPE_CHECKING, Tuple, Union, cast)
from git.types import PathLike
@@ -59,7 +59,23 @@ class BlobFilter(object):
return False
-class BaseIndexEntry(tuple):
+class BaseIndexEntryHelper(NamedTuple):
+ """Typed namedtuple to provide named attribute access for BaseIndexEntry.
+ Needed to allow overriding __new__ in child class to preserve backwards compat."""
+ mode: int
+ binsha: bytes
+ flags: int
+ path: PathLike
+ ctime_bytes: bytes = pack(">LL", 0, 0)
+ mtime_bytes: bytes = pack(">LL", 0, 0)
+ dev: int = 0
+ inode: int = 0
+ uid: int = 0
+ gid: int = 0
+ size: int = 0
+
+
+class BaseIndexEntry(BaseIndexEntryHelper):
"""Small Brother of an index entry which can be created to describe changes
done to the index in which case plenty of additional information is not required.
@@ -68,6 +84,12 @@ class BaseIndexEntry(tuple):
expecting a BaseIndexEntry can also handle full IndexEntries even if they
use numeric indices for performance reasons. """
+ 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 compatibility """
+ return super().__new__(cls, *inp_tuple)
+
def __str__(self) -> str:
return "%o %s %i\t%s" % (self.mode, self.hexsha, self.stage, self.path)
@@ -75,19 +97,9 @@ class BaseIndexEntry(tuple):
return "(%o, %s, %i, %s)" % (self.mode, self.hexsha, self.stage, self.path)
@property
- def mode(self) -> int:
- """ File Mode, compatible to stat module constants """
- return self[0]
-
- @property
- def binsha(self) -> bytes:
- """binary sha of the blob """
- return self[1]
-
- @property
def hexsha(self) -> str:
"""hex version of our sha"""
- return b2a_hex(self[1]).decode('ascii')
+ return b2a_hex(self.binsha).decode('ascii')
@property
def stage(self) -> int:
@@ -100,17 +112,7 @@ class BaseIndexEntry(tuple):
:note: For more information, see http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html
"""
- return (self[2] & CE_STAGEMASK) >> CE_STAGESHIFT
-
- @property
- def path(self) -> str:
- """:return: our path relative to the repository working tree root"""
- return self[3]
-
- @property
- def flags(self) -> List[str]:
- """:return: flags stored with this entry"""
- return self[2]
+ return (self.flags & CE_STAGEMASK) >> CE_STAGESHIFT
@classmethod
def from_blob(cls, blob: Blob, stage: int = 0) -> 'BaseIndexEntry':
@@ -136,40 +138,15 @@ class IndexEntry(BaseIndexEntry):
:return:
Tuple(int_time_seconds_since_epoch, int_nano_seconds) of the
file's creation time"""
- return cast(Tuple[int, int], unpack(">LL", self[4]))
+ return cast(Tuple[int, int], unpack(">LL", self.ctime_bytes))
@property
def mtime(self) -> Tuple[int, int]:
"""See ctime property, but returns modification time """
- return cast(Tuple[int, int], unpack(">LL", self[5]))
-
- @property
- def dev(self) -> int:
- """ Device ID """
- return self[6]
-
- @property
- def inode(self) -> int:
- """ Inode ID """
- return self[7]
-
- @property
- def uid(self) -> int:
- """ User ID """
- return self[8]
-
- @property
- def gid(self) -> int:
- """ Group ID """
- return self[9]
-
- @property
- def size(self) -> int:
- """:return: Uncompressed size of the blob """
- return self[10]
+ return cast(Tuple[int, int], unpack(">LL", self.mtime_bytes))
@classmethod
- def from_base(cls, base):
+ def from_base(cls, base: 'BaseIndexEntry') -> 'IndexEntry':
"""
:return:
Minimal entry as created from the given BaseIndexEntry instance.