884
884
def lookup_revision(self, revision):
885
885
"""Return the revision identifier for a given revision information."""
886
revno, info = self.get_revision_info(revision)
886
revno, info = self._get_revision_info(revision)
904
904
revision can also be a string, in which case it is parsed for something like
905
905
'date:' or 'revid:' etc.
907
revno, rev_id = self._get_revision_info(revision)
909
raise bzrlib.errors.NoSuchRevision(self, revision)
912
def get_rev_id(self, revno, history=None):
913
"""Find the revision id of the specified revno."""
917
history = self.revision_history()
918
elif revno <= 0 or revno > len(history):
919
raise bzrlib.errors.NoSuchRevision(self, revno)
920
return history[revno - 1]
922
def _get_revision_info(self, revision):
923
"""Return (revno, revision id) for revision specifier.
925
revision can be an integer, in which case it is assumed to be revno
926
(though this will translate negative values into positive ones)
927
revision can also be a string, in which case it is parsed for something
928
like 'date:' or 'revid:' etc.
930
A revid is always returned. If it is None, the specifier referred to
931
the null revision. If the revid does not occur in the revision
932
history, revno will be None.
907
935
if revision is None:
914
942
revs = self.revision_history()
915
943
if isinstance(revision, int):
918
# Mabye we should do this first, but we don't need it if revision == 0
920
945
revno = len(revs) + revision + 1
948
rev_id = self.get_rev_id(revno, revs)
923
949
elif isinstance(revision, basestring):
924
950
for prefix, func in Branch.REVISION_NAMESPACES.iteritems():
925
951
if revision.startswith(prefix):
926
revno = func(self, revs, revision)
952
result = func(self, revs, revision)
954
revno, rev_id = result
957
rev_id = self.get_rev_id(revno, revs)
929
raise BzrError('No namespace registered for string: %r' % revision)
960
raise BzrError('No namespace registered for string: %r' %
963
raise TypeError('Unhandled revision type %s' % revision)
931
if revno is None or revno <= 0 or revno > len(revs):
932
raise BzrError("no such revision %s" % revision)
933
return revno, revs[revno-1]
967
raise bzrlib.errors.NoSuchRevision(self, revision)
935
970
def _namespace_revno(self, revs, revision):
936
971
"""Lookup a revision by revision number"""
937
972
assert revision.startswith('revno:')
939
return int(revision[6:])
974
return (int(revision[6:]),)
940
975
except ValueError:
942
977
REVISION_NAMESPACES['revno:'] = _namespace_revno
944
979
def _namespace_revid(self, revs, revision):
945
980
assert revision.startswith('revid:')
981
rev_id = revision[len('revid:'):]
947
return revs.index(revision[6:]) + 1
983
return revs.index(rev_id) + 1, rev_id
948
984
except ValueError:
950
986
REVISION_NAMESPACES['revid:'] = _namespace_revid
952
988
def _namespace_last(self, revs, revision):
955
991
offset = int(revision[5:])
956
992
except ValueError:
960
996
raise BzrError('You must supply a positive value for --revision last:XXX')
961
return len(revs) - offset + 1
997
return (len(revs) - offset + 1,)
962
998
REVISION_NAMESPACES['last:'] = _namespace_last
964
1000
def _namespace_tag(self, revs, revision):
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):
1044
1080
for i in range(len(revs)):
1045
1081
r = self.get_revision(revs[i])
1046
1082
# TODO: Handle timezone.
1047
1083
dt = datetime.datetime.fromtimestamp(r.timestamp)
1048
1084
if first <= dt and (last is None or dt <= last):
1050
1086
REVISION_NAMESPACES['date:'] = _namespace_date
1052
1088
def revision_tree(self, revision_id):