897
897
def lookup_revision(self, revision):
898
898
"""Return the revision identifier for a given revision information."""
899
revno, info = self.get_revision_info(revision)
899
revno, info = self._get_revision_info(revision)
902
902
def get_revision_info(self, revision):
907
907
revision can also be a string, in which case it is parsed for something like
908
908
'date:' or 'revid:' etc.
910
revno, rev_id = self._get_revision_info(revision)
912
raise bzrlib.errors.NoSuchRevision(self, revision)
915
def get_rev_id(self, revno, history=None):
916
"""Find the revision id of the specified revno."""
920
history = self.revision_history()
921
elif revno <= 0 or revno > len(history):
922
raise bzrlib.errors.NoSuchRevision(self, revision)
923
return history[revno - 1]
925
def _get_revision_info(self, revision):
926
"""Return (revno, revision id) for revision specifier.
928
revision can be an integer, in which case it is assumed to be revno
929
(though this will translate negative values into positive ones)
930
revision can also be a string, in which case it is parsed for something
931
like 'date:' or 'revid:' etc.
933
A revid is always returned. If it is None, the specifier referred to
934
the null revision. If the revid does not occur in the revision
935
history, revno will be None.
910
938
if revision is None:
917
945
revs = self.revision_history()
918
946
if isinstance(revision, int):
921
# Mabye we should do this first, but we don't need it if revision == 0
923
948
revno = len(revs) + revision + 1
951
rev_id = self.get_rev_id(revision, revs)
926
952
elif isinstance(revision, basestring):
927
953
for prefix, func in Branch.REVISION_NAMESPACES.iteritems():
928
954
if revision.startswith(prefix):
929
revno = func(self, revs, revision)
955
result = func(self, revs, revision)
957
revno, rev_id = result
960
rev_id = self.get_rev_id(revno, revs)
932
raise BzrError('No namespace registered for string: %r' % revision)
963
raise BzrError('No namespace registered for string: %r' %
966
raise TypeError('Unhandled revision type %s' % revision)
934
if revno is None or revno <= 0 or revno > len(revs):
935
raise BzrError("no such revision %s" % revision)
936
return revno, revs[revno-1]
970
raise bzrlib.errors.NoSuchRevision(self, revision)
938
973
def _namespace_revno(self, revs, revision):
939
974
"""Lookup a revision by revision number"""
940
975
assert revision.startswith('revno:')
942
return int(revision[6:])
977
return (int(revision[6:]),)
943
978
except ValueError:
945
980
REVISION_NAMESPACES['revno:'] = _namespace_revno
947
982
def _namespace_revid(self, revs, revision):
948
983
assert revision.startswith('revid:')
984
rev_id = revision[len('revid:'):]
950
return revs.index(revision[6:]) + 1
986
return revs.index(rev_id) + 1, rev_id
951
987
except ValueError:
953
989
REVISION_NAMESPACES['revid:'] = _namespace_revid
955
991
def _namespace_last(self, revs, revision):
958
994
offset = int(revision[5:])
959
995
except ValueError:
963
999
raise BzrError('You must supply a positive value for --revision last:XXX')
964
return len(revs) - offset + 1
1000
return (len(revs) - offset + 1,)
965
1001
REVISION_NAMESPACES['last:'] = _namespace_last
967
1003
def _namespace_tag(self, revs, revision):
1042
1078
# TODO: Handle timezone.
1043
1079
dt = datetime.datetime.fromtimestamp(r.timestamp)
1044
1080
if first >= dt and (last is None or dt >= last):
1047
1083
for i in range(len(revs)):
1048
1084
r = self.get_revision(revs[i])
1049
1085
# TODO: Handle timezone.
1050
1086
dt = datetime.datetime.fromtimestamp(r.timestamp)
1051
1087
if first <= dt and (last is None or dt <= last):
1053
1089
REVISION_NAMESPACES['date:'] = _namespace_date
1055
1091
def revision_tree(self, revision_id):