diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2009-10-12 17:03:01 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2009-10-12 17:10:33 +0200 |
commit | 4c73e9cd66c77934f8a262b0c1bab9c2f15449ba (patch) | |
tree | fc132d15729e8d5e3abbc5fcf80f28b5ab9fe118 /lib/git | |
parent | 637eadce54ca8bbe536bcf7c570c025e28e47129 (diff) | |
download | gitpython-4c73e9cd66c77934f8a262b0c1bab9c2f15449ba.tar.gz |
refs now take repo as first argument and derive from LazyMixin to allow them to dynamically retrieve their objects
Improved way commits are returned by refs as they now use the path to be sure they always point to the ref even if it changes - previously it would use the sha intead so it would not update after being cached on the ref object
Diffstat (limited to 'lib/git')
-rw-r--r-- | lib/git/objects/base.py | 25 | ||||
-rw-r--r-- | lib/git/objects/commit.py | 2 | ||||
-rw-r--r-- | lib/git/refs.py | 94 | ||||
-rw-r--r-- | lib/git/utils.py | 25 |
4 files changed, 68 insertions, 78 deletions
diff --git a/lib/git/objects/base.py b/lib/git/objects/base.py index 43aa8dd1..5007f3a1 100644 --- a/lib/git/objects/base.py +++ b/lib/git/objects/base.py @@ -4,30 +4,7 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php import os - -class LazyMixin(object): - lazy_properties = [] - __slots__ = tuple() - - def __getattr__(self, attr): - """ - Whenever an attribute is requested that we do not know, we allow it - to be created and set. Next time the same attribute is reqeusted, it is simply - returned from our dict/slots. - """ - self._set_cache_(attr) - # will raise in case the cache was not created - return object.__getattribute__(self, attr) - - def _set_cache_(self, attr): - """ This method should be overridden in the derived class. - It should check whether the attribute named by attr can be created - and cached. Do nothing if you do not know the attribute or call your subclass - - The derived class may create as many additional attributes as it deems - necessary in case a git command returns more information than represented - in the single attribute.""" - pass +from git.utils import LazyMixin class Object(LazyMixin): diff --git a/lib/git/objects/commit.py b/lib/git/objects/commit.py index c3e97bf9..f1f878d7 100644 --- a/lib/git/objects/commit.py +++ b/lib/git/objects/commit.py @@ -37,7 +37,7 @@ class Commit(base.Object): The parameter documentation indicates the type of the argument after a colon ':'. ``id`` - is the sha id of the commit + is the sha id of the commit or a ref ``parents`` : tuple( Commit, ... ) is a tuple of commit ids or actual Commits diff --git a/lib/git/refs.py b/lib/git/refs.py index 820150d3..bc5cc005 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -8,16 +8,19 @@ Module containing all ref based objects """ from objects.base import Object from objects.util import get_object_type_by_name +from utils import LazyMixin -class Ref(object): +class Ref(LazyMixin): """ Represents a named reference to any object """ - __slots__ = ("path", "object") + __slots__ = ("repo", "path", "object") - def __init__(self, path, object = None): + def __init__(self, repo, path, object = None): """ Initialize this instance + ``repo`` + Our parent repository ``path`` Path relative to the .git/ directory pointing to the ref in question, i.e. @@ -26,8 +29,19 @@ class Ref(object): ``object`` Object instance, will be retrieved on demand if None """ + self.repo = repo self.path = path - self.object = object + if object is not None: + self.object = object + + def _set_cache_(self, attr): + if attr == "object": + # have to be dynamic here as we may be a tag which can point to anything + # it uses our path to stay dynamic + type_string = self.repo.git.cat_file(self.path, t=True).rstrip() + self.object = get_object_type_by_name(type_string)(self.repo, self.path) + else: + super(Ref, self)._set_cache_(attr) def __str__(self): return self.name @@ -92,19 +106,8 @@ class Ref(object): @classmethod def _list_from_string(cls, repo, text): - """ - Parse out ref information into a list of Ref compatible objects - - ``repo`` - is the Repo - ``text`` - is the text output from the git-for-each-ref command - - Returns - git.Ref[] - - list of Ref objects - """ + """ Parse out ref information into a list of Ref compatible objects + Returns git.Ref[] list of Ref objects """ heads = [] for line in text.splitlines(): @@ -114,28 +117,16 @@ class Ref(object): @classmethod def _from_string(cls, repo, line): - """ - Create a new Ref instance from the given string. - - ``repo`` - is the Repo - - ``line`` - is the formatted ref information - - Format:: - + """ Create a new Ref instance from the given string. + Format name: [a-zA-Z_/]+ <null byte> id: [0-9A-Fa-f]{40} - - Returns - git.Head - """ + Returns git.Head """ full_path, hexsha, type_name, object_size = line.split("\x00") obj = get_object_type_by_name(type_name)(repo, hexsha) obj.size = object_size - return cls(full_path, obj) + return cls(repo, full_path, obj) class Head(Ref): @@ -196,24 +187,7 @@ class TagRef(Ref): print tagref.tag.message """ - __slots__ = "tag" - - def __init__(self, path, commit_or_tag): - """ - Initialize a newly instantiated Tag - - ``path`` - is the full path to the tag - - ``commit_or_tag`` - is the Commit or TagObject that this tag ref points to - """ - super(TagRef, self).__init__(path, commit_or_tag) - self.tag = None - - if commit_or_tag.type == "tag": - self.tag = commit_or_tag - # END tag object handling + __slots__ = tuple() @property def commit(self): @@ -223,8 +197,22 @@ class TagRef(Ref): """ if self.object.type == "commit": return self.object - # it is a tag object - return self.object.object + elif self.object.type == "tag": + # it is a tag object which carries the commit as an object - we can point to anything + return self.object.object + else: + raise ValueError( "Tag %s points to a Blob or Tree - have never seen that before" % self ) + + @property + def tag(self): + """ + Returns + Tag object this tag ref points to or None in case + we are a light weight tag + """ + if self.object.type == "tag": + return self.object + return None @classmethod def find_all(cls, repo, common_path = "refs/tags", **kwargs): diff --git a/lib/git/utils.py b/lib/git/utils.py index c204c432..39994bd5 100644 --- a/lib/git/utils.py +++ b/lib/git/utils.py @@ -24,3 +24,28 @@ def is_git_dir(d): (os.path.islink(headref) and os.readlink(headref).startswith('refs')) return False + + +class LazyMixin(object): + __slots__ = tuple() + + def __getattr__(self, attr): + """ + Whenever an attribute is requested that we do not know, we allow it + to be created and set. Next time the same attribute is reqeusted, it is simply + returned from our dict/slots. + """ + self._set_cache_(attr) + # will raise in case the cache was not created + return object.__getattribute__(self, attr) + + def _set_cache_(self, attr): + """ This method should be overridden in the derived class. + It should check whether the attribute named by attr can be created + and cached. Do nothing if you do not know the attribute or call your subclass + + The derived class may create as many additional attributes as it deems + necessary in case a git command returns more information than represented + in the single attribute.""" + pass + |