Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/git/index/typ.py: 71%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This module is part of GitPython and is released under the
2# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/
4"""Additional types used by the index."""
6__all__ = ["BlobFilter", "BaseIndexEntry", "IndexEntry", "StageType"]
8from binascii import b2a_hex
9from pathlib import Path
11from git.objects import Blob
13from .util import pack, unpack
15# typing ----------------------------------------------------------------------
17from typing import NamedTuple, Sequence, TYPE_CHECKING, Tuple, Union, cast
19from git.types import PathLike
21if TYPE_CHECKING:
22 from git.repo import Repo
24StageType = int
26# ---------------------------------------------------------------------------------
28# { Invariants
29CE_NAMEMASK = 0x0FFF
30CE_STAGEMASK = 0x3000
31CE_EXTENDED = 0x4000
32CE_VALID = 0x8000
33CE_STAGESHIFT = 12
35# } END invariants
38class BlobFilter:
39 """Predicate to be used by
40 :meth:`IndexFile.iter_blobs <git.index.base.IndexFile.iter_blobs>` allowing to
41 filter only return blobs which match the given list of directories or files.
43 The given paths are given relative to the repository.
44 """
46 __slots__ = ("paths",)
48 def __init__(self, paths: Sequence[PathLike]) -> None:
49 """
50 :param paths:
51 Tuple or list of paths which are either pointing to directories or to files
52 relative to the current repository.
53 """
54 self.paths = paths
56 def __call__(self, stage_blob: Tuple[StageType, Blob]) -> bool:
57 blob_pathlike: PathLike = stage_blob[1].path
58 blob_path: Path = blob_pathlike if isinstance(blob_pathlike, Path) else Path(blob_pathlike)
59 for pathlike in self.paths:
60 path: Path = pathlike if isinstance(pathlike, Path) else Path(pathlike)
61 # TODO: Change to use `PosixPath.is_relative_to` once Python 3.8 is no
62 # longer supported.
63 filter_parts = path.parts
64 blob_parts = blob_path.parts
65 if len(filter_parts) > len(blob_parts):
66 continue
67 if all(i == j for i, j in zip(filter_parts, blob_parts)):
68 return True
69 return False
72class BaseIndexEntryHelper(NamedTuple):
73 """Typed named tuple to provide named attribute access for :class:`BaseIndexEntry`.
75 This is needed to allow overriding ``__new__`` in child class to preserve backwards
76 compatibility.
77 """
79 mode: int
80 binsha: bytes
81 flags: int
82 path: PathLike
83 ctime_bytes: bytes = pack(">LL", 0, 0)
84 mtime_bytes: bytes = pack(">LL", 0, 0)
85 dev: int = 0
86 inode: int = 0
87 uid: int = 0
88 gid: int = 0
89 size: int = 0
92class BaseIndexEntry(BaseIndexEntryHelper):
93 R"""Small brother of an index entry which can be created to describe changes
94 done to the index in which case plenty of additional information is not required.
96 As the first 4 data members match exactly to the :class:`IndexEntry` type, methods
97 expecting a :class:`BaseIndexEntry` can also handle full :class:`IndexEntry`\s even
98 if they use numeric indices for performance reasons.
99 """
101 def __new__(
102 cls,
103 inp_tuple: Union[
104 Tuple[int, bytes, int, PathLike],
105 Tuple[int, bytes, int, PathLike, bytes, bytes, int, int, int, int, int],
106 ],
107 ) -> "BaseIndexEntry":
108 """Override ``__new__`` to allow construction from a tuple for backwards
109 compatibility."""
110 return super().__new__(cls, *inp_tuple)
112 def __str__(self) -> str:
113 return "%o %s %i\t%s" % (self.mode, self.hexsha, self.stage, self.path)
115 def __repr__(self) -> str:
116 return "(%o, %s, %i, %s)" % (self.mode, self.hexsha, self.stage, self.path)
118 @property
119 def hexsha(self) -> str:
120 """hex version of our sha"""
121 return b2a_hex(self.binsha).decode("ascii")
123 @property
124 def stage(self) -> int:
125 """Stage of the entry, either:
127 * 0 = default stage
128 * 1 = stage before a merge or common ancestor entry in case of a 3 way merge
129 * 2 = stage of entries from the 'left' side of the merge
130 * 3 = stage of entries from the 'right' side of the merge
132 :note:
133 For more information, see :manpage:`git-read-tree(1)`.
134 """
135 return (self.flags & CE_STAGEMASK) >> CE_STAGESHIFT
137 @classmethod
138 def from_blob(cls, blob: Blob, stage: int = 0) -> "BaseIndexEntry":
139 """:return: Fully equipped BaseIndexEntry at the given stage"""
140 return cls((blob.mode, blob.binsha, stage << CE_STAGESHIFT, blob.path))
142 def to_blob(self, repo: "Repo") -> Blob:
143 """:return: Blob using the information of this index entry"""
144 return Blob(repo, self.binsha, self.mode, self.path)
147class IndexEntry(BaseIndexEntry):
148 """Allows convenient access to index entry data as defined in
149 :class:`BaseIndexEntry` without completely unpacking it.
151 Attributes usually accessed often are cached in the tuple whereas others are
152 unpacked on demand.
154 See the properties for a mapping between names and tuple indices.
155 """
157 @property
158 def ctime(self) -> Tuple[int, int]:
159 """
160 :return:
161 Tuple(int_time_seconds_since_epoch, int_nano_seconds) of the
162 file's creation time
163 """
164 return cast(Tuple[int, int], unpack(">LL", self.ctime_bytes))
166 @property
167 def mtime(self) -> Tuple[int, int]:
168 """See :attr:`ctime` property, but returns modification time."""
169 return cast(Tuple[int, int], unpack(">LL", self.mtime_bytes))
171 @classmethod
172 def from_base(cls, base: "BaseIndexEntry") -> "IndexEntry":
173 """
174 :return:
175 Minimal entry as created from the given :class:`BaseIndexEntry` instance.
176 Missing values will be set to null-like values.
178 :param base:
179 Instance of type :class:`BaseIndexEntry`.
180 """
181 time = pack(">LL", 0, 0)
182 return IndexEntry((base.mode, base.binsha, base.flags, base.path, time, time, 0, 0, 0, 0, 0))
184 @classmethod
185 def from_blob(cls, blob: Blob, stage: int = 0) -> "IndexEntry":
186 """:return: Minimal entry resembling the given blob object"""
187 time = pack(">LL", 0, 0)
188 return IndexEntry(
189 (
190 blob.mode,
191 blob.binsha,
192 stage << CE_STAGESHIFT,
193 blob.path,
194 time,
195 time,
196 0,
197 0,
198 0,
199 0,
200 blob.size,
201 )
202 )