Skip to content

Commit 1c6d783

Browse files
committed
RevParse now generally works, but there are still some more specialized tests missing
1 parent f963881 commit 1c6d783

File tree

4 files changed

+55
-25
lines changed

4 files changed

+55
-25
lines changed

lib/git/refs.py

-4
Original file line numberDiff line numberDiff line change
@@ -807,10 +807,6 @@ def commit(self):
807807
else:
808808
raise ValueError( "Tag %s points to a Blob or Tree - have never seen that before" % self )
809809

810-
@property
811-
def tree(self):
812-
return self.commit.tree
813-
814810
@property
815811
def tag(self):
816812
"""

lib/git/repo.py

+37-13
Original file line numberDiff line numberDiff line change
@@ -750,12 +750,31 @@ def name_to_object(name):
750750
return Object.new_from_sha(self, hex_to_bin(hexsha))
751751
# END object by name
752752

753+
def deref_tag(tag):
754+
while True:
755+
try:
756+
tag = tag.object
757+
except AttributeError:
758+
break
759+
# END dereference tag
760+
return tag
761+
762+
def to_commit(obj):
763+
if obj.type == 'tag':
764+
obj = deref_tag(obj)
765+
766+
if obj.type != "commit":
767+
raise ValueError("Cannot convert object %r to type commit" % obj)
768+
# END verify type
769+
return obj
770+
# END commit converter
771+
753772
obj = None
754773
output_type = "commit"
755774
start = 0
756775
parsed_to = 0
757776
lr = len(rev)
758-
while start < lr and start != -1:
777+
while start < lr:
759778
if rev[start] not in "^~:":
760779
start += 1
761780
continue
@@ -781,17 +800,17 @@ def name_to_object(name):
781800
pass # default
782801
elif output_type == 'tree':
783802
try:
784-
obj = obj.tree
785-
except AttributeError:
803+
obj = to_commit(obj).tree
804+
except (AttributeError, ValueError):
786805
pass # error raised later
787806
# END exception handling
788807
elif output_type in ('', 'blob'):
789-
while True:
790-
try:
791-
obj = obj.object
792-
except AttributeError:
793-
break
794-
# END dereference tag
808+
if obj.type == 'tag':
809+
obj = deref_tag(tag)
810+
else:
811+
# cannot do anything for non-tags
812+
pass
813+
# END handle tag
795814
else:
796815
raise ValueError("Invalid output type: %s ( in %s )" % (output_type, rev))
797816
# END handle output type
@@ -808,17 +827,20 @@ def name_to_object(name):
808827
# try to parse a number
809828
num = 0
810829
if token != ":":
830+
found_digit = False
811831
while start < lr:
812832
if rev[start] in digits:
813833
num = num * 10 + int(rev[start])
814834
start += 1
835+
found_digit = True
815836
else:
816837
break
817838
# END handle number
818839
# END number parse loop
819840

820841
# no explicit number given, 1 is the default
821-
if num == 0:
842+
# It could be 0 though
843+
if not found_digit:
822844
num = 1
823845
# END set default num
824846
# END number parsing only if non-blob mode
@@ -827,24 +849,26 @@ def name_to_object(name):
827849
parsed_to = start
828850
# handle hiererarchy walk
829851
try:
852+
obj = to_commit(obj)
830853
if token == "~":
831854
for item in xrange(num):
832855
obj = obj.parents[0]
833856
# END for each history item to walk
834857
elif token == "^":
835858
# must be n'th parent
836-
obj = obj.parents[num-1]
859+
if num:
860+
obj = obj.parents[num-1]
837861
elif token == ":":
838862
if obj.type != "tree":
839863
obj = obj.tree
840864
# END get tree type
841865
obj = obj[rev[start:]]
842866
parsed_to = lr
843867
else:
844-
raise "Invalid token: %r" % token
868+
raise ValueError("Invalid token: %r" % token)
845869
# END end handle tag
846870
except (IndexError, AttributeError):
847-
raise BadObject("Invalid Revision")
871+
raise BadObject("Invalid Revision in %s" % rev)
848872
# END exception handling
849873
# END parse loop
850874

test/git/test_refs.py

-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ def test_tag_base(self):
4040
assert isinstance( tagobj.tagger_tz_offset, int )
4141
assert tagobj.message
4242
assert tag.object == tagobj
43-
assert tag.tree.type == 'tree'
44-
assert tag.tree == tag.commit.tree
4543
# can't assign the object
4644
self.failUnlessRaises(AttributeError, setattr, tag, 'object', tagobj)
4745
# END if we have a tag object

test/git/test_repo.py

+18-6
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,12 @@ def _assert_rev_parse(self, name):
394394
"""tries multiple different rev-parse syntaxes with the given name
395395
:return: parsed object"""
396396
rev_parse = self.rorepo.rev_parse
397-
obj = rev_parse(name)
397+
orig_obj = rev_parse(name)
398+
if orig_obj.type == 'tag':
399+
obj = orig_obj.object
400+
else:
401+
obj = orig_obj
402+
# END deref tags by default
398403

399404
# try history
400405
rev = name + "~"
@@ -404,10 +409,9 @@ def _assert_rev_parse(self, name):
404409

405410
# history with number
406411
ni = 11
407-
history = list()
408-
citer = obj.traverse()
412+
history = [obj.parents[0]]
409413
for pn in range(ni):
410-
history.append(citer.next())
414+
history.append(history[-1].parents[0])
411415
# END get given amount of commits
412416

413417
for pn in range(11):
@@ -430,11 +434,14 @@ def _assert_rev_parse(self, name):
430434
self._assert_rev_parse_types(rev, obj2)
431435
# END for each parent
432436

433-
return obj
437+
return orig_obj
434438

435439
def test_rev_parse(self):
436440
rev_parse = self.rorepo.rev_parse
437441

442+
# it works with tags !
443+
self._assert_rev_parse('0.1.4')
444+
438445
# start from reference
439446
num_resolved = 0
440447
for ref in Reference.iter_items(self.rorepo):
@@ -447,7 +454,6 @@ def test_rev_parse(self):
447454
num_resolved += 1
448455
except BadObject:
449456
print "failed on %s" % path_section
450-
raise
451457
# is fine, in case we have something like 112, which belongs to remotes/rname/merge-requests/112
452458
pass
453459
# END exception handling
@@ -467,6 +473,12 @@ def test_rev_parse(self):
467473

468474
# dereference tag using ^{} notation
469475

476+
# ref^0 returns commit being pointed to, same with ref~0
477+
tag = rev_parse('0.1.4')
478+
for token in ('~^'):
479+
assert tag.object == rev_parse('0.1.4%s0' % token)
480+
# END handle multiple tokens
481+
470482
# missing closing brace commit^{tree
471483

472484
# missing starting brace

0 commit comments

Comments
 (0)