summaryrefslogtreecommitdiff
path: root/lib/git/refs.py
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2009-10-23 00:13:09 +0200
committerSebastian Thiel <byronimo@gmail.com>2009-10-23 00:13:09 +0200
commitd1bd99c0a376dec63f0f050aeb0c40664260da16 (patch)
treef3de7739d34003a7356bd72769f212a47ebc8993 /lib/git/refs.py
parentb7a5c05875a760c0bf83af6617c68061bda6cfc5 (diff)
downloadgitpython-d1bd99c0a376dec63f0f050aeb0c40664260da16.tar.gz
SymbolicReferences can now change they references safely as I think and well controlled, including test.
Added commit method which will return the commit for detached symbolic refs or for normal symbolic refs which is quite convenient
Diffstat (limited to 'lib/git/refs.py')
-rw-r--r--lib/git/refs.py71
1 files changed, 65 insertions, 6 deletions
diff --git a/lib/git/refs.py b/lib/git/refs.py
index aeee0da1..a83628ce 100644
--- a/lib/git/refs.py
+++ b/lib/git/refs.py
@@ -7,7 +7,7 @@
Module containing all ref based objects
"""
import os
-from objects.base import Object
+from objects import Object, Commit
from objects.utils import get_object_type_by_name
from utils import LazyMixin, Iterable
@@ -214,13 +214,36 @@ class SymbolicReference(object):
def __hash__(self):
return hash(self.name)
+ def _get_path(self):
+ return os.path.join(self.repo.path, self.name)
+
@property
- def reference(self):
+ def commit(self):
+ """
+ Returns:
+ Commit object we point to, works for detached and non-detached
+ SymbolicReferences
+ """
+ # we partially reimplement it to prevent unnecessary file access
+ fp = open(self._get_path(), 'r')
+ value = fp.read().rstrip()
+ fp.close()
+ tokens = value.split(" ")
+
+ # it is a detached reference
+ if len(tokens) == 1 and len(tokens[0]) == 40:
+ return Commit(self.repo, tokens[0])
+
+ # must be a head ! Git does not allow symbol refs to other things than heads
+ # Otherwise it would have detached it
+ return Head(self.repo, tokens[1]).commit
+
+ def _get_reference(self):
"""
Returns
Reference Object we point to
"""
- fp = open(os.path.join(self.repo.path, self.name), 'r')
+ fp = open(self._get_path(), 'r')
try:
tokens = fp.readline().rstrip().split(' ')
if tokens[0] != 'ref:':
@@ -229,6 +252,41 @@ class SymbolicReference(object):
finally:
fp.close()
+ def _set_reference(self, ref):
+ """
+ Set ourselves to the given ref. It will stay a symbol if the ref is a Head.
+ Otherwise we try to get a commit from it using our interface.
+
+ Strings are allowed but will be checked to be sure we have a commit
+ """
+ write_value = None
+ if isinstance(ref, Head):
+ write_value = "ref: %s" % ref.path
+ elif isinstance(ref, Commit):
+ write_value = ref.id
+ else:
+ try:
+ write_value = ref.commit.id
+ except AttributeError:
+ sha = str(ref)
+ try:
+ obj = Object.new(self.repo, sha)
+ if obj.type != "commit":
+ raise TypeError("Invalid object type behind sha: %s" % sha)
+ write_value = obj.id
+ except Exception:
+ raise ValueError("Could not extract object from %s" % ref)
+ # END end try string
+ # END try commit attribute
+ fp = open(self._get_path(), "w")
+ try:
+ fp.write(write_value)
+ finally:
+ fp.close()
+ # END writing
+
+ reference = property(_get_reference, _set_reference, doc="Returns the Reference we point to")
+
# alias
ref = reference
@@ -251,11 +309,12 @@ class HEAD(SymbolicReference):
Special case of a Symbolic Reference as it represents the repository's
HEAD reference.
"""
+ _HEAD_NAME = 'HEAD'
__slots__ = tuple()
- def __init__(self, repo, name):
- if name != 'HEAD':
- raise ValueError("HEAD instance must point to 'HEAD', got %s" % name)
+ def __init__(self, repo, name=_HEAD_NAME):
+ if name != self._HEAD_NAME:
+ raise ValueError("HEAD instance must point to %r, got %r" % (self._HEAD_NAME, name))
super(HEAD, self).__init__(repo, name)