diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2009-10-23 16:07:45 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2009-10-23 16:07:45 +0200 |
commit | 9b9776e88f7abb59cebac8733c04cccf6eee1c60 (patch) | |
tree | f7bc7af48ddb55eafde1d1c91d8014ec595208fa | |
parent | 1047b41e2e925617474e2e7c9927314f71ce7365 (diff) | |
download | gitpython-9b9776e88f7abb59cebac8733c04cccf6eee1c60.tar.gz |
Refs can now set the reference they are pointing to in a controlled fashion by writing their ref file directly
-rw-r--r-- | TODO | 10 | ||||
-rw-r--r-- | lib/git/refs.py | 48 | ||||
-rw-r--r-- | test/git/test_refs.py | 18 |
3 files changed, 60 insertions, 16 deletions
@@ -67,15 +67,7 @@ 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' -* Reference Objects should be able to set the commit they are pointing to, making - the commit property read-write. Tags are a special case of this and would need - to be handled as well ! -* Ability to create new heads and tags in the Repository ( but using the respective - Reference Type ), i.e. Head.create(repo, name, commit = 'HEAD') or - TagReference.create(repo, name -* Ability to rename references and tagsre -* Ability to remove references and tags -* Ability to checkout a reference - + - same with adjusting references directly * Check whether we are the active reference HEAD.commit == self.commit Remote diff --git a/lib/git/refs.py b/lib/git/refs.py index 0efee52e..47c37af6 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -65,8 +65,7 @@ class Reference(LazyMixin, Iterable): return '/'.join(tokens[2:]) - @property - def object(self): + def _get_object(self): """ Returns The object our ref currently refers to. Refs can be cached, they will @@ -76,17 +75,54 @@ class Reference(LazyMixin, Iterable): # Our path will be resolved to the hexsha which will be used accordingly return Object.new(self.repo, self.path) - @property - def commit(self): + def _set_object(self, ref, type=None): """ + 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 - Commit object the head points to + Object we have set. This is used internally only to reduce the amount + of calls to 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 + + object = property(_get_object, _set_object, doc="Return the object our ref currently refers to") + + def _set_commit(self, commit): + """ + Set ourselves to point to the given commit. + + Raise + ValueError if commit does not actually point to a commit + """ + self._set_object(commit, type="commit") + + def _get_commit(self): + """ + Returns + Commit object the reference points to """ commit = self.object if commit.type != "commit": raise TypeError("Object of reference %s did not point to a commit" % self) return commit + commit = property(_get_commit, _set_commit, doc="Return Commit object the reference points to") + @classmethod def iter_items(cls, repo, common_path = None, **kwargs): """ @@ -244,7 +280,7 @@ class SymbolicReference(object): try: tokens = fp.readline().rstrip().split(' ') if tokens[0] != 'ref:': - raise TypeError("%s is a detached symbolic reference as it points to %r" % tokens[0]) + raise TypeError("%s is a detached symbolic reference as it points to %r" % (self, tokens[0])) return Reference.from_path(self.repo, tokens[1]) finally: fp.close() diff --git a/test/git/test_refs.py b/test/git/test_refs.py index 88e8a21a..696b95c7 100644 --- a/test/git/test_refs.py +++ b/test/git/test_refs.py @@ -181,4 +181,20 @@ class TestRefs(TestBase): self.failUnlessRaises(AssertionError, getattr, remote, 'refs') # END for each remote - self.fail("set commit using ref.commit = that") + # change where the active head points to + if cur_head.is_detached: + cur_head.reference = rw_repo.heads[0] + + head = cur_head.reference + old_commit = head.commit + head.commit = old_commit.parents[0] + assert head.commit == old_commit.parents[0] + assert head.commit == cur_head.commit + head.commit = old_commit + + # setting a non-commit as commit fails, but succeeds as object + head_tree = head.commit.tree + self.failUnlessRaises(TypeError, 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 |