diff options
-rw-r--r-- | lib/git/base.py | 69 | ||||
-rw-r--r-- | lib/git/blob.py | 31 | ||||
-rw-r--r-- | lib/git/commit.py | 13 | ||||
-rw-r--r-- | lib/git/tag.py | 6 | ||||
-rw-r--r-- | lib/git/tree.py | 17 | ||||
-rw-r--r-- | test/git/test_base.py | 36 |
6 files changed, 132 insertions, 40 deletions
diff --git a/lib/git/base.py b/lib/git/base.py index 5e470181..687fb50a 100644 --- a/lib/git/base.py +++ b/lib/git/base.py @@ -1,4 +1,4 @@ -# lazy.py +# base.py # Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors # # This module is part of GitPython and is released under @@ -30,3 +30,70 @@ class LazyMixin(object): def __bake_it__(self): self.__baked__ = True + + +class Object(LazyMixin): + """ + Implements an Object which may be Blobs, Trees, Commits and Tags + """ + TYPES = ("blob", "tree", "commit", "tag") + __slots__ = ("repo", "id", "size") + type = None # to be set by subclass + + def __init__(self, repo, id, size=None): + """ + Initialize an object by identifying it by its id. All keyword arguments + will be set on demand if None. + + ``repo`` + repository this object is located in + ``id`` + SHA1 or ref suitable for git-rev-parse + ``size`` + Size of the object's data in bytes + """ + super(Object,self).__init__() + self.repo = repo + self.id = id + self.size = size + + def __bake__(self): + """ + Retrieve object information + """ + self.size = int(self.repo.git.cat_file(self.id, s=True).rstrip()) + + def __eq__(self, other): + """ + Returns + True if the objects have the same SHA1 + """ + return self.id == other.id + + def __ne__(self, other): + """ + Returns + True if the objects do not have the same SHA1 + """ + return self.id != other.id + + def __hash__(self): + """ + Returns + Hash of our id allowing objects to be used in dicts and sets + """ + return hash(self.id) + + def __str__(self): + """ + Returns + string of our SHA1 as understood by all git commands + """ + return self.id + + def __repr__(self): + """ + Returns + string with pythonic representation of our object + """ + return '<git.%s "%s">' % (self.__class__.__name__, self.id) diff --git a/lib/git/blob.py b/lib/git/blob.py index 1e8aa12b..3ecd3a38 100644 --- a/lib/git/blob.py +++ b/lib/git/blob.py @@ -10,10 +10,13 @@ import re import time from actor import Actor from commit import Commit +import base -class Blob(object): +class Blob(base.Object): """A Blob encapsulates a git blob object""" DEFAULT_MIME_TYPE = "text/plain" + type = "blob" + __slots__ = ("mode", "path", "_data_stored") # precompiled regex re_whitespace = re.compile(r'\s+') @@ -40,28 +43,10 @@ class Blob(object): Returns git.Blob """ - self.repo = repo - self.id = id + super(Blob,self).__init__(repo, id, "blob") self.mode = mode self.path = path - - self._size = None - self.data_stored = None - - @property - def size(self): - """ - The size of this blob in bytes - - Returns - int - - NOTE - The size will be cached after the first access - """ - if self._size is None: - self._size = int(self.repo.git.cat_file(self.id, s=True).rstrip()) - return self._size + self._data_stored = None @property def data(self): @@ -74,8 +59,8 @@ class Blob(object): NOTE The data will be cached after the first access. """ - self.data_stored = self.data_stored or self.repo.git.cat_file(self.id, p=True, with_raw_output=True) - return self.data_stored + self._data_stored = self._data_stored or self.repo.git.cat_file(self.id, p=True, with_raw_output=True) + return self._data_stored @property def mime_type(self): diff --git a/lib/git/commit.py b/lib/git/commit.py index 14e1ba68..73fb8e7a 100644 --- a/lib/git/commit.py +++ b/lib/git/commit.py @@ -8,12 +8,12 @@ import re import time from actor import Actor -from base import LazyMixin from tree import Tree import diff import stats +import base -class Commit(LazyMixin): +class Commit(base.Object): """ Wraps a git Commit object. @@ -23,6 +23,9 @@ class Commit(LazyMixin): # precompiled regex re_actor_epoch = re.compile(r'^.+? (.*) (\d+) .*$') + # object configuration + type = "commit" + def __init__(self, repo, id, tree=None, author=None, authored_date=None, committer=None, committed_date=None, message=None, parents=None): """ @@ -58,10 +61,7 @@ class Commit(LazyMixin): Returns git.Commit """ - LazyMixin.__init__(self) - - self.repo = repo - self.id = id + super(Commit,self).__init__(repo, id, "commit") self.parents = None self.tree = None self.author = author @@ -87,6 +87,7 @@ class Commit(LazyMixin): Called by LazyMixin superclass when the first uninitialized member needs to be set as it is queried. """ + super(Commit, self).__bake__() temp = Commit.find_all(self.repo, self.id, max_count=1)[0] self.parents = temp.parents self.tree = temp.tree diff --git a/lib/git/tag.py b/lib/git/tag.py index 8413ce73..df3158a6 100644 --- a/lib/git/tag.py +++ b/lib/git/tag.py @@ -7,6 +7,12 @@ from commit import Commit class Tag(object): + """ + Class representing a tag reference which either points to a commit + or to a tag object. In the latter case additional information, like the signature + or the tag-creator, is available. + """ + def __init__(self, name, commit): """ Initialize a newly instantiated Tag diff --git a/lib/git/tree.py b/lib/git/tree.py index 06c1a158..6215f875 100644 --- a/lib/git/tree.py +++ b/lib/git/tree.py @@ -5,25 +5,22 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php import os -from base import LazyMixin import blob +import base -class Tree(LazyMixin): +class Tree(base.Object): + + type = "tree" + def __init__(self, repo, id, mode=None, path=None): - LazyMixin.__init__(self) - self.repo = repo - self.id = id + super(Tree, self).__init__(repo, id) self.mode = mode self.path = path self._contents = None def __bake__(self): - # Ensure the treeish references directly a tree - treeish = self.id - if not treeish.endswith(':'): - treeish = treeish + ':' - # Read the tree contents. + super(Tree, self).__bake__() self._contents = {} for line in self.repo.git.ls_tree(self.id).splitlines(): obj = self.content_from_string(self.repo, line) diff --git a/test/git/test_base.py b/test/git/test_base.py new file mode 100644 index 00000000..46869f63 --- /dev/null +++ b/test/git/test_base.py @@ -0,0 +1,36 @@ +# test_base.py +# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors +# +# This module is part of GitPython and is released under +# the BSD License: http://www.opensource.org/licenses/bsd-license.php + +import time +from test.testlib import * +from git import * + +class TestBase(object): + + type_tuples = ( ("blob", "8741fc1d09d61f02ffd8cded15ff603eff1ec070"), + ("tree", "3a6a5e3eeed3723c09f1ef0399f81ed6b8d82e79"), + ("commit", "4251bd59fb8e11e40c40548cba38180a9536118c") ) + + def setup(self): + self.repo = Repo(GIT_REPO) + + def test_base(self): + # test interface of base classes + fcreators = (self.repo.blob, self.repo.tree, self.repo.commit ) + assert len(fcreators) == len(self.type_tuples) + for fcreator, (typename, hexsha) in zip(fcreators, self.type_tuples): + item = fcreator(hexsha) + assert item.id == hexsha + assert item.type == typename + assert item.size + # END for each object type to create + + assert False,"TODO: Test for all types" + + def test_tags(self): + # tag refs can point to tag objects or to commits + assert False, "TODO: Tag handling" + |