diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2009-11-03 17:44:13 +0100 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2009-11-03 17:44:13 +0100 |
commit | 572ace094208c28ab1a8641aedb038456d13f70b (patch) | |
tree | 9bb6197273dc9976bce5bd789a657f408fc1b77e | |
parent | 0c4269a21b9edf8477f2fee139d5c1b260ebc4f8 (diff) | |
download | gitpython-572ace094208c28ab1a8641aedb038456d13f70b.tar.gz |
Now using git-update-ref and git-symbolic-ref to update references with reflog support. This should be manually implemented though for more performance, what it does is relatively easy
-rw-r--r-- | TODO | 12 | ||||
-rw-r--r-- | lib/git/refs.py | 38 | ||||
-rw-r--r-- | test/git/test_refs.py | 6 |
3 files changed, 26 insertions, 30 deletions
@@ -80,11 +80,12 @@ Index Refs ----- -* When adjusting the reference of a symbolic reference, the ref log might need - adjustments as well. This is not critical, but would make things totally 'right' - - same with adjusting references directly - !! - Could simply rewrite it using git-update-ref which works nicely for symbolic - and for normal refs !! +* For performance reasons it would be good to reimplement git-update-ref to be + fully equivalent to what the command does. Currently it does some checking and + handles symbolic refs as well as normal refs, updating the reflog if required. +* I have read that refs can be symbolic refs as well which would imply the need + to possibly dereference them. This makes sense as they originally where possibly + a symbolic link * Check whether we are the active reference HEAD.reference == this_ref - NO: The reference dosnt need to know - in fact it does not know about the main HEAD, so it may not use it. This is to be done in client code only. @@ -92,6 +93,7 @@ Refs * Reference.from_path may return a symbolic reference although it is not related to the reference type. Split that up into two from_path on each of the types, and provide a general method outside of the type that tries both. +* Making the reflog available might be useful actually. Remote ------ diff --git a/lib/git/refs.py b/lib/git/refs.py index 84347057..cd36a052 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -13,7 +13,8 @@ from utils import LazyMixin, Iterable class Reference(LazyMixin, Iterable): """ - Represents a named reference to any object + Represents a named reference to any object. Subclasses may apply restrictions though, + i.e. Heads can only point to commits. """ __slots__ = ("repo", "path") _common_path_default = "refs" @@ -75,30 +76,16 @@ class Reference(LazyMixin, Iterable): # Our path will be resolved to the hexsha which will be used accordingly return Object.new(self.repo, self.path) - def _set_object(self, ref, type=None): + def _set_object(self, ref): """ Set our reference to point to the given ref. It will be converted to a specific hexsha. - ``type`` - If not None, string type of that the object must have, other we raise - a type error. Only used internally - - Returns - Object we have set. This is used internally only to reduce the amount - of calls to the git command + Note: + TypeChecking is done by the git command """ - obj = Object.new(self.repo, ref) - if type is not None and obj.type != type: - raise TypeError("Reference %r cannot point to object of type %r" % (self,obj.type)) - - full_ref_path = os.path.join(self.repo.path, self.path) - fp = open(full_ref_path, "w") - try: - fp.write(str(obj)) - finally: - fp.close() - return obj + # do it safely by specifying the old value + self.repo.git.update_ref(self.path, ref, self._get_object().sha) object = property(_get_object, _set_object, doc="Return the object our ref currently refers to") @@ -109,7 +96,7 @@ class Reference(LazyMixin, Iterable): Raise ValueError if commit does not actually point to a commit """ - self._set_object(commit, type="commit") + self._set_object(commit) def _get_commit(self): """ @@ -327,6 +314,15 @@ class SymbolicReference(object): raise ValueError("Could not extract object from %s" % ref) # END end try string # END try commit attribute + + # if we are writing a ref, use symbolic ref to get the reflog and more + # checking + # Otherwise we detach it and have to do it manually + if write_value.startswith('ref:'): + self.repo.git.symbolic_ref(self.name, write_value[5:]) + return + # END non-detached handling + fp = open(self._get_path(), "w") try: fp.write(write_value) diff --git a/test/git/test_refs.py b/test/git/test_refs.py index 0a70af1f..f7f4f71a 100644 --- a/test/git/test_refs.py +++ b/test/git/test_refs.py @@ -200,11 +200,9 @@ class TestRefs(TestBase): # setting a non-commit as commit fails, but succeeds as object head_tree = head.commit.tree - self.failUnlessRaises(TypeError, setattr, head, 'commit', head_tree) + self.failUnlessRaises(GitCommandError, setattr, head, 'commit', head_tree) assert head.commit == old_commit # and the ref did not change - head.object = head_tree - assert head.object == head_tree - self.failUnlessRaises(TypeError, getattr, head, 'commit') # object is a tree, not a commit + self.failUnlessRaises(GitCommandError, setattr, head, 'object', head_tree) # set the commit directly using the head. This would never detach the head assert not cur_head.is_detached |