diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2010-07-06 10:46:02 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2010-07-06 10:46:02 +0200 |
commit | 1c6d7830d9b87f47a0bfe82b3b5424a32e3164ad (patch) | |
tree | 19d9d0de030d3701b8b99f56f9d54943e734d9bc | |
parent | f963881e53a9f0a2746a11cb9cdfa82eb1f90d8c (diff) | |
download | gitpython-1c6d7830d9b87f47a0bfe82b3b5424a32e3164ad.tar.gz |
RevParse now generally works, but there are still some more specialized tests missing
-rw-r--r-- | lib/git/refs.py | 4 | ||||
-rw-r--r-- | lib/git/repo.py | 50 | ||||
-rw-r--r-- | test/git/test_refs.py | 2 | ||||
-rw-r--r-- | test/git/test_repo.py | 24 |
4 files changed, 55 insertions, 25 deletions
diff --git a/lib/git/refs.py b/lib/git/refs.py index a466e419..23d45ed0 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -808,10 +808,6 @@ class TagReference(Reference): raise ValueError( "Tag %s points to a Blob or Tree - have never seen that before" % self ) @property - def tree(self): - return self.commit.tree - - @property def tag(self): """ :return: Tag object this tag ref points to or None in case diff --git a/lib/git/repo.py b/lib/git/repo.py index 8e97adee..5a1af920 100644 --- a/lib/git/repo.py +++ b/lib/git/repo.py @@ -750,12 +750,31 @@ class Repo(object): return Object.new_from_sha(self, hex_to_bin(hexsha)) # END object by name + def deref_tag(tag): + while True: + try: + tag = tag.object + except AttributeError: + break + # END dereference tag + return tag + + def to_commit(obj): + if obj.type == 'tag': + obj = deref_tag(obj) + + if obj.type != "commit": + raise ValueError("Cannot convert object %r to type commit" % obj) + # END verify type + return obj + # END commit converter + obj = None output_type = "commit" start = 0 parsed_to = 0 lr = len(rev) - while start < lr and start != -1: + while start < lr: if rev[start] not in "^~:": start += 1 continue @@ -781,17 +800,17 @@ class Repo(object): pass # default elif output_type == 'tree': try: - obj = obj.tree - except AttributeError: + obj = to_commit(obj).tree + except (AttributeError, ValueError): pass # error raised later # END exception handling elif output_type in ('', 'blob'): - while True: - try: - obj = obj.object - except AttributeError: - break - # END dereference tag + if obj.type == 'tag': + obj = deref_tag(tag) + else: + # cannot do anything for non-tags + pass + # END handle tag else: raise ValueError("Invalid output type: %s ( in %s )" % (output_type, rev)) # END handle output type @@ -808,17 +827,20 @@ class Repo(object): # try to parse a number num = 0 if token != ":": + found_digit = False while start < lr: if rev[start] in digits: num = num * 10 + int(rev[start]) start += 1 + found_digit = True else: break # END handle number # END number parse loop # no explicit number given, 1 is the default - if num == 0: + # It could be 0 though + if not found_digit: num = 1 # END set default num # END number parsing only if non-blob mode @@ -827,13 +849,15 @@ class Repo(object): parsed_to = start # handle hiererarchy walk try: + obj = to_commit(obj) if token == "~": for item in xrange(num): obj = obj.parents[0] # END for each history item to walk elif token == "^": # must be n'th parent - obj = obj.parents[num-1] + if num: + obj = obj.parents[num-1] elif token == ":": if obj.type != "tree": obj = obj.tree @@ -841,10 +865,10 @@ class Repo(object): obj = obj[rev[start:]] parsed_to = lr else: - raise "Invalid token: %r" % token + raise ValueError("Invalid token: %r" % token) # END end handle tag except (IndexError, AttributeError): - raise BadObject("Invalid Revision") + raise BadObject("Invalid Revision in %s" % rev) # END exception handling # END parse loop diff --git a/test/git/test_refs.py b/test/git/test_refs.py index 44a8ed95..b73d574b 100644 --- a/test/git/test_refs.py +++ b/test/git/test_refs.py @@ -40,8 +40,6 @@ class TestRefs(TestBase): assert isinstance( tagobj.tagger_tz_offset, int ) assert tagobj.message assert tag.object == tagobj - assert tag.tree.type == 'tree' - assert tag.tree == tag.commit.tree # can't assign the object self.failUnlessRaises(AttributeError, setattr, tag, 'object', tagobj) # END if we have a tag object diff --git a/test/git/test_repo.py b/test/git/test_repo.py index f1609266..89c7f6b5 100644 --- a/test/git/test_repo.py +++ b/test/git/test_repo.py @@ -394,7 +394,12 @@ class TestRepo(TestBase): """tries multiple different rev-parse syntaxes with the given name :return: parsed object""" rev_parse = self.rorepo.rev_parse - obj = rev_parse(name) + orig_obj = rev_parse(name) + if orig_obj.type == 'tag': + obj = orig_obj.object + else: + obj = orig_obj + # END deref tags by default # try history rev = name + "~" @@ -404,10 +409,9 @@ class TestRepo(TestBase): # history with number ni = 11 - history = list() - citer = obj.traverse() + history = [obj.parents[0]] for pn in range(ni): - history.append(citer.next()) + history.append(history[-1].parents[0]) # END get given amount of commits for pn in range(11): @@ -430,11 +434,14 @@ class TestRepo(TestBase): self._assert_rev_parse_types(rev, obj2) # END for each parent - return obj + return orig_obj def test_rev_parse(self): rev_parse = self.rorepo.rev_parse + # it works with tags ! + self._assert_rev_parse('0.1.4') + # start from reference num_resolved = 0 for ref in Reference.iter_items(self.rorepo): @@ -447,7 +454,6 @@ class TestRepo(TestBase): num_resolved += 1 except BadObject: print "failed on %s" % path_section - raise # is fine, in case we have something like 112, which belongs to remotes/rname/merge-requests/112 pass # END exception handling @@ -467,6 +473,12 @@ class TestRepo(TestBase): # dereference tag using ^{} notation + # ref^0 returns commit being pointed to, same with ref~0 + tag = rev_parse('0.1.4') + for token in ('~^'): + assert tag.object == rev_parse('0.1.4%s0' % token) + # END handle multiple tokens + # missing closing brace commit^{tree # missing starting brace |