summaryrefslogtreecommitdiff
path: root/git/index/typ.py
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2010-11-25 18:10:33 +0100
committerSebastian Thiel <byronimo@gmail.com>2010-11-25 18:18:15 +0100
commitf8ce24a835cae8c623e2936bec2618a8855c605b (patch)
treed4c1d392579e24285381613a4ac1b7cc2d6b6fae /git/index/typ.py
parent65747a216c67c3101c6ae2edaa8119d786b793cb (diff)
parent9004e3a1cf33110f2cbc458f1dc3259c930ad9b4 (diff)
downloadgitpython-f8ce24a835cae8c623e2936bec2618a8855c605b.tar.gz
-#######->WARNING<-####### Directory structure changed, see commit message
If you use git-python as a submodule of your own project, which alters the sys.path to import it, you will have to adjust your code to take the changed directory structure into consideration. Previously, you would put the path ./git-python/lib into your syspath. All modules moved one level up into the 'git' subdirectory, which means that the 'git-python' directory now contains the 'git' root package. To allow git to be found, add ./git-python into your path. To finalize your update, run the following commands git submodule update --init --recursive As there will be left-over directories, consider running git-clean
Diffstat (limited to 'git/index/typ.py')
-rw-r--r--git/index/typ.py173
1 files changed, 173 insertions, 0 deletions
diff --git a/git/index/typ.py b/git/index/typ.py
new file mode 100644
index 00000000..ad988285
--- /dev/null
+++ b/git/index/typ.py
@@ -0,0 +1,173 @@
+"""Module with additional types used by the index"""
+
+from util import (
+ pack,
+ unpack
+ )
+
+from binascii import (
+ b2a_hex,
+ )
+
+from git.objects import Blob
+__all__ = ('BlobFilter', 'BaseIndexEntry', 'IndexEntry')
+
+#{ Invariants
+CE_NAMEMASK = 0x0fff
+CE_STAGEMASK = 0x3000
+CE_EXTENDED = 0x4000
+CE_VALID = 0x8000
+CE_STAGESHIFT = 12
+
+#} END invariants
+
+class BlobFilter(object):
+ """
+ Predicate to be used by iter_blobs allowing to filter only return blobs which
+ match the given list of directories or files.
+
+ The given paths are given relative to the repository.
+ """
+ __slots__ = 'paths'
+
+ def __init__(self, paths):
+ """:param paths:
+ tuple or list of paths which are either pointing to directories or
+ to files relative to the current repository
+ """
+ self.paths = paths
+
+ def __call__(self, stage_blob):
+ path = stage_blob[1].path
+ for p in self.paths:
+ if path.startswith(p):
+ return True
+ # END for each path in filter paths
+ return False
+
+
+class BaseIndexEntry(tuple):
+ """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 requried.
+
+ As the first 4 data members match exactly to the IndexEntry type, methods
+ expecting a BaseIndexEntry can also handle full IndexEntries even if they
+ use numeric indices for performance reasons. """
+
+ def __str__(self):
+ return "%o %s %i\t%s" % (self.mode, self.hexsha, self.stage, self.path)
+
+ def __repr__(self):
+ return "(%o, %s, %i, %s)" % (self.mode, self.hexsha, self.stage, self.path)
+
+ @property
+ def mode(self):
+ """ File Mode, compatible to stat module constants """
+ return self[0]
+
+ @property
+ def binsha(self):
+ """binary sha of the blob """
+ return self[1]
+
+ @property
+ def hexsha(self):
+ """hex version of our sha"""
+ return b2a_hex(self[1])
+
+ @property
+ def stage(self):
+ """Stage of the entry, either:
+
+ * 0 = default stage
+ * 1 = stage before a merge or common ancestor entry in case of a 3 way merge
+ * 2 = stage of entries from the 'left' side of the merge
+ * 3 = stage of entries from the right side of the merge
+
+ :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):
+ """:return: our path relative to the repository working tree root"""
+ return self[3]
+
+ @property
+ def flags(self):
+ """:return: flags stored with this entry"""
+ return self[2]
+
+ @classmethod
+ def from_blob(cls, blob, stage = 0):
+ """:return: Fully equipped BaseIndexEntry at the given stage"""
+ return cls((blob.mode, blob.binsha, stage << CE_STAGESHIFT, blob.path))
+
+ def to_blob(self, repo):
+ """:return: Blob using the information of this index entry"""
+ return Blob(repo, self.binsha, self.mode, self.path)
+
+
+class IndexEntry(BaseIndexEntry):
+ """Allows convenient access to IndexEntry data without completely unpacking it.
+
+ Attributes usully accessed often are cached in the tuple whereas others are
+ unpacked on demand.
+
+ See the properties for a mapping between names and tuple indices. """
+ @property
+ def ctime(self):
+ """
+ :return:
+ Tuple(int_time_seconds_since_epoch, int_nano_seconds) of the
+ file's creation time"""
+ return unpack(">LL", self[4])
+
+ @property
+ def mtime(self):
+ """See ctime property, but returns modification time """
+ return unpack(">LL", self[5])
+
+ @property
+ def dev(self):
+ """ Device ID """
+ return self[6]
+
+ @property
+ def inode(self):
+ """ Inode ID """
+ return self[7]
+
+ @property
+ def uid(self):
+ """ User ID """
+ return self[8]
+
+ @property
+ def gid(self):
+ """ Group ID """
+ return self[9]
+
+ @property
+ def size(self):
+ """:return: Uncompressed size of the blob """
+ return self[10]
+
+ @classmethod
+ def from_base(cls, base):
+ """
+ :return:
+ Minimal entry as created from the given BaseIndexEntry instance.
+ Missing values will be set to null-like values
+
+ :param base: Instance of type BaseIndexEntry"""
+ time = pack(">LL", 0, 0)
+ return IndexEntry((base.mode, base.binsha, base.flags, base.path, time, time, 0, 0, 0, 0, 0))
+
+ @classmethod
+ def from_blob(cls, blob, stage = 0):
+ """:return: Minimal entry resembling the given blob object"""
+ time = pack(">LL", 0, 0)
+ return IndexEntry((blob.mode, blob.binsha, stage << CE_STAGESHIFT, blob.path, time, time, 0, 0, 0, 0, blob.size))
+
+