summaryrefslogtreecommitdiff
path: root/lib/git
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2010-05-26 22:34:40 +0200
committerSebastian Thiel <byronimo@gmail.com>2010-05-26 22:40:31 +0200
commitde84cbdd0f9ef97fcd3477b31b040c57192e28d9 (patch)
treefa871654c7fe5c4f2fcf48795bef5cebcb60e73f /lib/git
parent17af1f64d5f1e62d40e11b75b1dd48e843748b49 (diff)
downloadgitpython-de84cbdd0f9ef97fcd3477b31b040c57192e28d9.tar.gz
refs: a Reference can now be created by assigning a commit or object (for convenience)
Diffstat (limited to 'lib/git')
-rw-r--r--lib/git/refs.py51
1 files changed, 40 insertions, 11 deletions
diff --git a/lib/git/refs.py b/lib/git/refs.py
index d88a2331..6c57eb07 100644
--- a/lib/git/refs.py
+++ b/lib/git/refs.py
@@ -51,7 +51,7 @@ class SymbolicReference(object):
"""
return self.path
- def _get_path(self):
+ def _abs_path(self):
return join_path_native(self.repo.git_dir, self.path)
@classmethod
@@ -97,7 +97,7 @@ class SymbolicReference(object):
point to, or None"""
tokens = None
try:
- fp = open(self._get_path(), 'r')
+ fp = open(self._abs_path(), 'r')
value = fp.read().rstrip()
fp.close()
tokens = value.split(" ")
@@ -143,8 +143,15 @@ class SymbolicReference(object):
def _set_commit(self, commit):
"""
Set our commit, possibly dereference our symbolic reference first.
+ If the reference does not exist, it will be created
"""
- if self.is_detached:
+ is_detached = True
+ try:
+ is_detached = self.is_detached
+ except ValueError:
+ pass
+ # END handle non-existing ones
+ if is_detached:
return self._set_reference(commit)
# set the commit on our reference
@@ -197,7 +204,7 @@ class SymbolicReference(object):
return
# END non-detached handling
- path = self._get_path()
+ path = self._abs_path()
directory = os.path.dirname(path)
if not os.path.isdir(directory):
os.makedirs(directory)
@@ -533,12 +540,28 @@ class Reference(SymbolicReference, LazyMixin, Iterable):
"""
Set our reference to point to the given ref. It will be converted
to a specific hexsha.
+ If the reference does not exist, it will be created.
Note:
TypeChecking is done by the git command
"""
+ # check for existence, touch it if required
+ abs_path = self._abs_path()
+ existed = True
+ if not os.path.isfile(abs_path):
+ existed = False
+ open(abs_path, 'wb').write(Object.NULL_HEX_SHA)
+ # END quick create
+
# do it safely by specifying the old value
- self.repo.git.update_ref(self.path, ref, self._get_object().sha)
+ try:
+ self.repo.git.update_ref(self.path, ref, (existed and self._get_object().sha) or None)
+ except:
+ if not existed:
+ os.remove(abs_path)
+ # END remove file on error if it didn't exist before
+ raise
+ # END exception handling
object = property(_get_object, _set_object, doc="Return the object our ref currently refers to")
@@ -813,11 +836,12 @@ class TagReference(Reference):
Returns
Commit object the tag ref points to
"""
- if self.object.type == "commit":
- return self.object
- elif self.object.type == "tag":
+ obj = self.object
+ if obj.type == "commit":
+ return obj
+ elif obj.type == "tag":
# it is a tag object which carries the commit as an object - we can point to anything
- return self.object.object
+ return obj.object
else:
raise ValueError( "Tag %s points to a Blob or Tree - have never seen that before" % self )
@@ -828,10 +852,15 @@ class TagReference(Reference):
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
+ obj = self.object
+ if obj.type == "tag":
+ return obj
return None
+ # make object read-only
+ # It should be reasonably hard to adjust an existing tag
+ object = property(Reference._get_object)
+
@classmethod
def create(cls, repo, path, ref='HEAD', message=None, force=False, **kwargs):
"""