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.
928
900
if revision is None:
935
907
revs = self.revision_history()
936
908
if isinstance(revision, int):
911
# Mabye we should do this first, but we don't need it if revision == 0
938
913
revno = len(revs) + revision + 1
941
rev_id = self.get_rev_id(revno, revs)
942
916
elif isinstance(revision, basestring):
943
917
for prefix, func in Branch.REVISION_NAMESPACES.iteritems():
944
918
if revision.startswith(prefix):
945
result = func(self, revs, revision)
947
revno, rev_id = result
950
rev_id = self.get_rev_id(revno, revs)
919
revno = func(self, revs, revision)
953
raise BzrError('No namespace registered for string: %r' %
956
raise TypeError('Unhandled revision type %s' % revision)
922
raise BzrError('No namespace registered for string: %r' % revision)
960
raise bzrlib.errors.NoSuchRevision(self, 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]
963
928
def _namespace_revno(self, revs, revision):
964
929
"""Lookup a revision by revision number"""
965
930
assert revision.startswith('revno:')
967
return (int(revision[6:]),)
932
return int(revision[6:])
968
933
except ValueError:
970
935
REVISION_NAMESPACES['revno:'] = _namespace_revno
972
937
def _namespace_revid(self, revs, revision):
973
938
assert revision.startswith('revid:')
974
rev_id = revision[len('revid:'):]
976
return revs.index(rev_id) + 1, rev_id
940
return revs.index(revision[6:]) + 1
977
941
except ValueError:
979
943
REVISION_NAMESPACES['revid:'] = _namespace_revid
981
945
def _namespace_last(self, revs, revision):
984
948
offset = int(revision[5:])
985
949
except ValueError:
989
953
raise BzrError('You must supply a positive value for --revision last:XXX')
990
return (len(revs) - offset + 1,)
954
return len(revs) - offset + 1
991
955
REVISION_NAMESPACES['last:'] = _namespace_last
993
957
def _namespace_tag(self, revs, revision):
1068
1032
# TODO: Handle timezone.
1069
1033
dt = datetime.datetime.fromtimestamp(r.timestamp)
1070
1034
if first >= dt and (last is None or dt >= last):
1073
1037
for i in range(len(revs)):
1074
1038
r = self.get_revision(revs[i])
1075
1039
# TODO: Handle timezone.
1076
1040
dt = datetime.datetime.fromtimestamp(r.timestamp)
1077
1041
if first <= dt and (last is None or dt <= last):
1079
1043
REVISION_NAMESPACES['date:'] = _namespace_date
1081
1045
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)