~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

merge from abentley

Show diffs side-by-side

added added

removed removed

Lines of Context:
883
883
 
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)
887
887
        return info
888
888
 
889
889
 
904
904
        revision can also be a string, in which case it is parsed for something like
905
905
            'date:' or 'revid:' etc.
906
906
        """
 
907
        revno, rev_id = self._get_revision_info(revision)
 
908
        if revno is None:
 
909
            raise bzrlib.errors.NoSuchRevision(self, revision)
 
910
        return revno, rev_id
 
911
 
 
912
    def get_rev_id(self, revno, history=None):
 
913
        """Find the revision id of the specified revno."""
 
914
        if revno == 0:
 
915
            return None
 
916
        if history is None:
 
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]
 
921
 
 
922
    def _get_revision_info(self, revision):
 
923
        """Return (revno, revision id) for revision specifier.
 
924
 
 
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.
 
929
 
 
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.
 
933
        """
 
934
        
907
935
        if revision is None:
908
936
            return 0, None
909
937
        revno = None
913
941
            pass
914
942
        revs = self.revision_history()
915
943
        if isinstance(revision, int):
916
 
            if revision == 0:
917
 
                return 0, None
918
 
            # Mabye we should do this first, but we don't need it if revision == 0
919
944
            if revision < 0:
920
945
                revno = len(revs) + revision + 1
921
946
            else:
922
947
                revno = revision
 
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)
 
953
                    if len(result) > 1:
 
954
                        revno, rev_id = result
 
955
                    else:
 
956
                        revno = result[0]
 
957
                        rev_id = self.get_rev_id(revno, revs)
927
958
                    break
928
959
            else:
929
 
                raise BzrError('No namespace registered for string: %r' % revision)
 
960
                raise BzrError('No namespace registered for string: %r' %
 
961
                               revision)
 
962
        else:
 
963
            raise TypeError('Unhandled revision type %s' % revision)
930
964
 
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]
 
965
        if revno is None:
 
966
            if rev_id is None:
 
967
                raise bzrlib.errors.NoSuchRevision(self, revision)
 
968
        return revno, rev_id
934
969
 
935
970
    def _namespace_revno(self, revs, revision):
936
971
        """Lookup a revision by revision number"""
937
972
        assert revision.startswith('revno:')
938
973
        try:
939
 
            return int(revision[6:])
 
974
            return (int(revision[6:]),)
940
975
        except ValueError:
941
976
            return None
942
977
    REVISION_NAMESPACES['revno:'] = _namespace_revno
943
978
 
944
979
    def _namespace_revid(self, revs, revision):
945
980
        assert revision.startswith('revid:')
 
981
        rev_id = revision[len('revid:'):]
946
982
        try:
947
 
            return revs.index(revision[6:]) + 1
 
983
            return revs.index(rev_id) + 1, rev_id
948
984
        except ValueError:
949
 
            return None
 
985
            return None, rev_id
950
986
    REVISION_NAMESPACES['revid:'] = _namespace_revid
951
987
 
952
988
    def _namespace_last(self, revs, revision):
954
990
        try:
955
991
            offset = int(revision[5:])
956
992
        except ValueError:
957
 
            return None
 
993
            return (None,)
958
994
        else:
959
995
            if offset <= 0:
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
963
999
 
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):
1042
 
                    return i+1
 
1078
                    return (i+1,)
1043
1079
        else:
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):
1049
 
                    return i+1
 
1085
                    return (i+1,)
1050
1086
    REVISION_NAMESPACES['date:'] = _namespace_date
1051
1087
 
1052
1088
    def revision_tree(self, revision_id):