summaryrefslogtreecommitdiff
path: root/lib/git/objects/base.py
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2009-11-04 19:53:42 +0100
committerSebastian Thiel <byronimo@gmail.com>2009-11-04 19:53:42 +0100
commitd884adc80c80300b4cc05321494713904ef1df2d (patch)
tree3878d5e0282531596d42505d8725482dde002c20 /lib/git/objects/base.py
parent05d2687afcc78cd192714ee3d71fdf36a37d110f (diff)
parentace1fed6321bb8dd6d38b2f58d7cf815fa16db7a (diff)
downloadgitpython-d884adc80c80300b4cc05321494713904ef1df2d.tar.gz
Merge branch 'improvements'
Diffstat (limited to 'lib/git/objects/base.py')
-rw-r--r--lib/git/objects/base.py103
1 files changed, 76 insertions, 27 deletions
diff --git a/lib/git/objects/base.py b/lib/git/objects/base.py
index 3b48e066..b0989a43 100644
--- a/lib/git/objects/base.py
+++ b/lib/git/objects/base.py
@@ -15,22 +15,16 @@ class Object(LazyMixin):
This Object also serves as a constructor for instances of the correct type::
- inst = Object(repo,id)
+ inst = Object.new(repo,id)
+ inst.sha # objects sha in hex
+ inst.size # objects uncompressed data size
+ inst.data # byte string containing the whole data of the object
"""
+ NULL_HEX_SHA = '0'*40
TYPES = ("blob", "tree", "commit", "tag")
- __slots__ = ("repo", "id", "size", "data" )
+ __slots__ = ("repo", "sha", "size", "data" )
type = None # to be set by subclass
- def __new__(cls, repo, id, *args, **kwargs):
- if cls is Object:
- hexsha, typename, size = repo.git.get_object_header(id)
- obj_type = utils.get_object_type_by_name(typename)
- inst = super(Object,cls).__new__(obj_type, repo, hexsha, *args, **kwargs)
- inst.size = size
- return inst
- else:
- return super(Object,cls).__new__(cls, repo, id, *args, **kwargs)
-
def __init__(self, repo, id):
"""
Initialize an object by identifying it by its id. All keyword arguments
@@ -44,8 +38,26 @@ class Object(LazyMixin):
"""
super(Object,self).__init__()
self.repo = repo
- self.id = id
-
+ self.sha = id
+
+ @classmethod
+ def new(cls, repo, id):
+ """
+ Return
+ New Object instance of a type appropriate to the object type behind
+ id. The id of the newly created object will be a hexsha even though
+ the input id may have been a Reference or Rev-Spec
+
+ Note
+ This cannot be a __new__ method as it would always call __init__
+ with the input id which is not necessarily a hexsha.
+ """
+ hexsha, typename, size = repo.git.get_object_header(id)
+ obj_type = utils.get_object_type_by_name(typename)
+ inst = obj_type(repo, hexsha)
+ inst.size = size
+ return inst
+
def _set_self_from_args_(self, args_dict):
"""
Initialize attributes on self from the given dict that was retrieved
@@ -64,11 +76,11 @@ class Object(LazyMixin):
Retrieve object information
"""
if attr == "size":
- hexsha, typename, self.size = self.repo.git.get_object_header(self.id)
- assert typename == self.type, _assertion_msg_format % (self.id, typename, self.type)
+ hexsha, typename, self.size = self.repo.git.get_object_header(self.sha)
+ assert typename == self.type, _assertion_msg_format % (self.sha, typename, self.type)
elif attr == "data":
- hexsha, typename, self.size, self.data = self.repo.git.get_object_data(self.id)
- assert typename == self.type, _assertion_msg_format % (self.id, typename, self.type)
+ hexsha, typename, self.size, self.data = self.repo.git.get_object_data(self.sha)
+ assert typename == self.type, _assertion_msg_format % (self.sha, typename, self.type)
else:
super(Object,self)._set_cache_(attr)
@@ -77,36 +89,57 @@ class Object(LazyMixin):
Returns
True if the objects have the same SHA1
"""
- return self.id == other.id
+ return self.sha == other.sha
def __ne__(self, other):
"""
Returns
True if the objects do not have the same SHA1
"""
- return self.id != other.id
+ return self.sha != other.sha
def __hash__(self):
"""
Returns
Hash of our id allowing objects to be used in dicts and sets
"""
- return hash(self.id)
+ return hash(self.sha)
def __str__(self):
"""
Returns
string of our SHA1 as understood by all git commands
"""
- return self.id
+ return self.sha
def __repr__(self):
"""
Returns
string with pythonic representation of our object
"""
- return '<git.%s "%s">' % (self.__class__.__name__, self.id)
+ return '<git.%s "%s">' % (self.__class__.__name__, self.sha)
+
+ @property
+ def data_stream(self):
+ """
+ Returns
+ File Object compatible stream to the uncompressed raw data of the object
+ """
+ proc = self.repo.git.cat_file(self.type, self.sha, as_process=True)
+ return utils.ProcessStreamAdapter(proc, "stdout")
+ def stream_data(self, ostream):
+ """
+ Writes our data directly to the given output stream
+
+ ``ostream``
+ File object compatible stream object.
+
+ Returns
+ self
+ """
+ self.repo.git.cat_file(self.type, self.sha, output_stream=ostream)
+ return self
class IndexObject(Object):
"""
@@ -115,13 +148,13 @@ class IndexObject(Object):
"""
__slots__ = ("path", "mode")
- def __init__(self, repo, id, mode=None, path=None):
+ def __init__(self, repo, sha, mode=None, path=None):
"""
Initialize a newly instanced IndexObject
``repo``
is the Repo we are located in
- ``id`` : string
+ ``sha`` : string
is the git object id as hex sha
``mode`` : int
@@ -135,7 +168,7 @@ class IndexObject(Object):
Path may not be set of the index object has been created directly as it cannot
be retrieved without knowing the parent tree.
"""
- super(IndexObject, self).__init__(repo, id)
+ super(IndexObject, self).__init__(repo, sha)
self._set_self_from_args_(locals())
if isinstance(mode, basestring):
self.mode = self._mode_str_to_int(mode)
@@ -162,5 +195,21 @@ class IndexObject(Object):
mode += int(char) << iteration*3
# END for each char
return mode
-
+
+ @property
+ def name(self):
+ """
+ Returns
+ Name portion of the path, effectively being the basename
+ """
+ return os.path.basename(self.path)
+
+ @property
+ def abspath(self):
+ """
+ Returns
+ Absolute path to this index object in the file system ( as opposed to the
+ .path field which is a path relative to the git repository )
+ """
+ return os.path.join(self.repo.git.git_dir, self.path)