877
877
def lookup_revision(self, revision):
878
878
"""Return the revision identifier for a given revision information."""
879
revno, info = self.get_revision_info(revision)
879
revno, info = self._get_revision_info(revision)
897
897
revision can also be a string, in which case it is parsed for something like
898
898
'date:' or 'revid:' etc.
900
revno, rev_id = self._get_revision_info(revision)
902
raise bzrlib.errors.NoSuchRevision(self, revision)
905
def get_rev_id(self, revno, history=None):
906
"""Find the revision id of the specified revno."""
910
history = self.revision_history()
911
elif revno <= 0 or revno > len(history):
912
raise bzrlib.errors.NoSuchRevision(self, revno)
913
return history[revno - 1]
915
def _get_revision_info(self, revision):
916
"""Return (revno, revision id) for revision specifier.
918
revision can be an integer, in which case it is assumed to be revno
919
(though this will translate negative values into positive ones)
920
revision can also be a string, in which case it is parsed for something
921
like 'date:' or 'revid:' etc.
923
A revid is always returned. If it is None, the specifier referred to
924
the null revision. If the revid does not occur in the revision
925
history, revno will be None.
900
928
if revision is None:
907
935
revs = self.revision_history()
908
936
if isinstance(revision, int):
911
# Mabye we should do this first, but we don't need it if revision == 0
913
938
revno = len(revs) + revision + 1
941
rev_id = self.get_rev_id(revno, revs)
916
942
elif isinstance(revision, basestring):
917
943
for prefix, func in Branch.REVISION_NAMESPACES.iteritems():
918
944
if revision.startswith(prefix):
919
revno = func(self, revs, revision)
945
result = func(self, revs, revision)
947
revno, rev_id = result
950
rev_id = self.get_rev_id(revno, revs)
922
raise BzrError('No namespace registered for string: %r' % revision)
953
raise BzrError('No namespace registered for string: %r' %
956
raise TypeError('Unhandled revision type %s' % revision)
924
if revno is None or revno <= 0 or revno > len(revs):
925
raise BzrError("no such revision %s" % revision)
926
return revno, revs[revno-1]
960
raise bzrlib.errors.NoSuchRevision(self, revision)
928
963
def _namespace_revno(self, revs, revision):
929
964
"""Lookup a revision by revision number"""
930
965
assert revision.startswith('revno:')
932
return int(revision[6:])
967
return (int(revision[6:]),)
933
968
except ValueError:
935
970
REVISION_NAMESPACES['revno:'] = _namespace_revno
937
972
def _namespace_revid(self, revs, revision):
938
973
assert revision.startswith('revid:')
974
rev_id = revision[len('revid:'):]
940
return revs.index(revision[6:]) + 1
976
return revs.index(rev_id) + 1, rev_id
941
977
except ValueError:
943
979
REVISION_NAMESPACES['revid:'] = _namespace_revid
945
981
def _namespace_last(self, revs, revision):
948
984
offset = int(revision[5:])
949
985
except ValueError:
953
989
raise BzrError('You must supply a positive value for --revision last:XXX')
954
return len(revs) - offset + 1
990
return (len(revs) - offset + 1,)
955
991
REVISION_NAMESPACES['last:'] = _namespace_last
957
993
def _namespace_tag(self, revs, revision):
1032
1068
# TODO: Handle timezone.
1033
1069
dt = datetime.datetime.fromtimestamp(r.timestamp)
1034
1070
if first >= dt and (last is None or dt >= last):
1037
1073
for i in range(len(revs)):
1038
1074
r = self.get_revision(revs[i])
1039
1075
# TODO: Handle timezone.
1040
1076
dt = datetime.datetime.fromtimestamp(r.timestamp)
1041
1077
if first <= dt and (last is None or dt <= last):
1043
1079
REVISION_NAMESPACES['date:'] = _namespace_date
1045
1081
def revision_tree(self, revision_id):
1351
def check_revno(self, revno):
1353
Check whether a revno corresponds to any revision.
1354
Zero (the NULL revision) is considered valid.
1357
self.check_real_revno(revno)
1359
def check_real_revno(self, revno):
1361
Check whether a revno corresponds to a real revision.
1362
Zero (the NULL revision) is considered invalid
1364
if revno < 1 or revno > self.revno():
1365
raise InvalidRevisionNumber(revno)