diff options
Diffstat (limited to 'lib/git')
-rw-r--r-- | lib/git/refs.py | 51 |
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): """ |