/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/revisionspec.py

  • Committer: Andrew Bennetts
  • Date: 2011-02-25 03:00:35 UTC
  • mto: This revision was merged to the branch mainline in revision 5695.
  • Revision ID: andrew.bennetts@canonical.com-20110225030035-12360oih60fxxa1t
Rename a variable, update a docstring.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
""")
25
25
 
26
26
from bzrlib import (
 
27
    branch as _mod_branch,
27
28
    errors,
28
29
    osutils,
29
30
    registry,
30
31
    revision,
31
32
    symbol_versioning,
32
33
    trace,
 
34
    workingtree,
33
35
    )
34
36
 
35
37
 
166
168
                         spectype.__name__, spec)
167
169
            return spectype(spec, _internal=True)
168
170
        else:
169
 
            for spectype in SPEC_TYPES:
170
 
                if spec.startswith(spectype.prefix):
171
 
                    trace.mutter('Returning RevisionSpec %s for %s',
172
 
                                 spectype.__name__, spec)
173
 
                    return spectype(spec, _internal=True)
174
171
            # Otherwise treat it as a DWIM, build the RevisionSpec object and
175
172
            # wait for _match_on to be called.
176
173
            return RevisionSpec_dwim(spec, _internal=True)
444
441
 
445
442
 
446
443
 
447
 
class RevisionSpec_revid(RevisionSpec):
 
444
class RevisionIDSpec(RevisionSpec):
 
445
 
 
446
    def _match_on(self, branch, revs):
 
447
        revision_id = self.as_revision_id(branch)
 
448
        return RevisionInfo.from_revision_id(branch, revision_id, revs)
 
449
 
 
450
 
 
451
class RevisionSpec_revid(RevisionIDSpec):
448
452
    """Selects a revision using the revision id."""
449
453
 
450
454
    help_txt = """Selects a revision using the revision id.
459
463
 
460
464
    prefix = 'revid:'
461
465
 
462
 
    def _match_on(self, branch, revs):
 
466
    def _as_revision_id(self, context_branch):
463
467
        # self.spec comes straight from parsing the command line arguments,
464
468
        # so we expect it to be a Unicode string. Switch it to the internal
465
469
        # representation.
466
 
        revision_id = osutils.safe_revision_id(self.spec, warn=False)
467
 
        return RevisionInfo.from_revision_id(branch, revision_id, revs)
468
 
 
469
 
    def _as_revision_id(self, context_branch):
470
470
        return osutils.safe_revision_id(self.spec, warn=False)
471
471
 
472
472
 
813
813
        revision_b = other_branch.last_revision()
814
814
        if revision_b in (None, revision.NULL_REVISION):
815
815
            raise errors.NoCommits(other_branch)
816
 
        # pull in the remote revisions so we can diff
817
 
        branch.fetch(other_branch, revision_b)
 
816
        if branch is None:
 
817
            branch = other_branch
 
818
        else:
 
819
            try:
 
820
                # pull in the remote revisions so we can diff
 
821
                branch.fetch(other_branch, revision_b)
 
822
            except errors.ReadOnlyError:
 
823
                branch = other_branch
818
824
        try:
819
825
            revno = branch.revision_id_to_revno(revision_b)
820
826
        except errors.NoSuchRevision:
840
846
            raise errors.NoCommits(other_branch)
841
847
        return other_branch.repository.revision_tree(last_revision)
842
848
 
 
849
    def needs_branch(self):
 
850
        return False
 
851
 
 
852
    def get_branch(self):
 
853
        return self.spec
 
854
 
843
855
 
844
856
 
845
857
class RevisionSpec_submit(RevisionSpec_ancestor):
884
896
            self._get_submit_location(context_branch))
885
897
 
886
898
 
 
899
class RevisionSpec_annotate(RevisionIDSpec):
 
900
 
 
901
    prefix = 'annotate:'
 
902
 
 
903
    help_txt = """Select the revision that last modified the specified line.
 
904
 
 
905
    Select the revision that last modified the specified line.  Line is
 
906
    specified as path:number.  Path is a relative path to the file.  Numbers
 
907
    start at 1, and are relative to the current version, not the last-
 
908
    committed version of the file.
 
909
    """
 
910
 
 
911
    def _raise_invalid(self, numstring, context_branch):
 
912
        raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
 
913
            'No such line: %s' % numstring)
 
914
 
 
915
    def _as_revision_id(self, context_branch):
 
916
        path, numstring = self.spec.rsplit(':', 1)
 
917
        try:
 
918
            index = int(numstring) - 1
 
919
        except ValueError:
 
920
            self._raise_invalid(numstring, context_branch)
 
921
        tree, file_path = workingtree.WorkingTree.open_containing(path)
 
922
        tree.lock_read()
 
923
        try:
 
924
            file_id = tree.path2id(file_path)
 
925
            if file_id is None:
 
926
                raise errors.InvalidRevisionSpec(self.user_spec,
 
927
                    context_branch, "File '%s' is not versioned." %
 
928
                    file_path)
 
929
            revision_ids = [r for (r, l) in tree.annotate_iter(file_id)]
 
930
        finally:
 
931
            tree.unlock()
 
932
        try:
 
933
            revision_id = revision_ids[index]
 
934
        except IndexError:
 
935
            self._raise_invalid(numstring, context_branch)
 
936
        if revision_id == revision.CURRENT_REVISION:
 
937
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
 
938
                'Line %s has not been committed.' % numstring)
 
939
        return revision_id
 
940
 
 
941
 
 
942
class RevisionSpec_mainline(RevisionIDSpec):
 
943
 
 
944
    help_txt = """Select mainline revision that merged the specified revision.
 
945
 
 
946
    Select the revision that merged the specified revision into mainline.
 
947
    """
 
948
 
 
949
    prefix = 'mainline:'
 
950
 
 
951
    def _as_revision_id(self, context_branch):
 
952
        revspec = RevisionSpec.from_string(self.spec)
 
953
        if revspec.get_branch() is None:
 
954
            spec_branch = context_branch
 
955
        else:
 
956
            spec_branch = _mod_branch.Branch.open(revspec.get_branch())
 
957
        revision_id = revspec.as_revision_id(spec_branch)
 
958
        graph = context_branch.repository.get_graph()
 
959
        result = graph.find_lefthand_merger(revision_id,
 
960
                                            context_branch.last_revision())
 
961
        if result is None:
 
962
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch)
 
963
        return result
 
964
 
 
965
 
887
966
# The order in which we want to DWIM a revision spec without any prefix.
888
967
# revno is always tried first and isn't listed here, this is used by
889
968
# RevisionSpec_dwim._match_on
908
987
_register_revspec(RevisionSpec_ancestor)
909
988
_register_revspec(RevisionSpec_branch)
910
989
_register_revspec(RevisionSpec_submit)
911
 
 
912
 
# classes in this list should have a "prefix" attribute, against which
913
 
# string specs are matched
914
 
SPEC_TYPES = symbol_versioning.deprecated_list(
915
 
    symbol_versioning.deprecated_in((1, 12, 0)), "SPEC_TYPES", [])
 
990
_register_revspec(RevisionSpec_annotate)
 
991
_register_revspec(RevisionSpec_mainline)