summaryrefslogtreecommitdiff
path: root/lib/git
diff options
context:
space:
mode:
Diffstat (limited to 'lib/git')
-rw-r--r--lib/git/refs.py4
-rw-r--r--lib/git/repo.py50
2 files changed, 37 insertions, 17 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