~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/revisionspec.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-08-16 06:46:17 UTC
  • mfrom: (5375.1.6 chk-canonicalizer-613698)
  • Revision ID: pqm@pqm.ubuntu.com-20100816064617-wizstoapjbffkj05
(spiv) Add hidden option 'bzr reconcile --canonicalize-chks' to repair repos
 affected by bug 522637. (Andrew Bennetts)

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,
28
27
    errors,
29
28
    osutils,
30
29
    registry,
31
30
    revision,
32
31
    symbol_versioning,
33
32
    trace,
34
 
    workingtree,
35
33
    )
36
34
 
37
35
 
446
444
 
447
445
 
448
446
 
449
 
class RevisionIDSpec(RevisionSpec):
450
 
 
451
 
    def _match_on(self, branch, revs):
452
 
        revision_id = self.as_revision_id(branch)
453
 
        return RevisionInfo.from_revision_id(branch, revision_id, revs)
454
 
 
455
 
 
456
 
class RevisionSpec_revid(RevisionIDSpec):
 
447
class RevisionSpec_revid(RevisionSpec):
457
448
    """Selects a revision using the revision id."""
458
449
 
459
450
    help_txt = """Selects a revision using the revision id.
468
459
 
469
460
    prefix = 'revid:'
470
461
 
471
 
    def _as_revision_id(self, context_branch):
 
462
    def _match_on(self, branch, revs):
472
463
        # self.spec comes straight from parsing the command line arguments,
473
464
        # so we expect it to be a Unicode string. Switch it to the internal
474
465
        # 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):
475
470
        return osutils.safe_revision_id(self.spec, warn=False)
476
471
 
477
472
 
901
896
            self._get_submit_location(context_branch))
902
897
 
903
898
 
904
 
class RevisionSpec_annotate(RevisionIDSpec):
905
 
 
906
 
    prefix = 'annotate:'
907
 
 
908
 
    help_txt = """Select the revision that last modified the specified line.
909
 
 
910
 
    Select the revision that last modified the specified line.  Line is
911
 
    specified as path:number.  Path is a relative path to the file.  Numbers
912
 
    start at 1, and are relative to the current version, not the last-
913
 
    committed version of the file.
914
 
    """
915
 
 
916
 
    def _raise_invalid(self, numstring, context_branch):
917
 
        raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
918
 
            'No such line: %s' % numstring)
919
 
 
920
 
    def _as_revision_id(self, context_branch):
921
 
        path, numstring = self.spec.rsplit(':', 1)
922
 
        try:
923
 
            index = int(numstring) - 1
924
 
        except ValueError:
925
 
            self._raise_invalid(numstring, context_branch)
926
 
        tree, file_path = workingtree.WorkingTree.open_containing(path)
927
 
        tree.lock_read()
928
 
        try:
929
 
            file_id = tree.path2id(file_path)
930
 
            if file_id is None:
931
 
                raise errors.InvalidRevisionSpec(self.user_spec,
932
 
                    context_branch, "File '%s' is not versioned." %
933
 
                    file_path)
934
 
            revision_ids = [r for (r, l) in tree.annotate_iter(file_id)]
935
 
        finally:
936
 
            tree.unlock()
937
 
        try:
938
 
            revision_id = revision_ids[index]
939
 
        except IndexError:
940
 
            self._raise_invalid(numstring, context_branch)
941
 
        if revision_id == revision.CURRENT_REVISION:
942
 
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
943
 
                'Line %s has not been committed.' % numstring)
944
 
        return revision_id
945
 
 
946
 
 
947
 
class RevisionSpec_mainline(RevisionIDSpec):
948
 
 
949
 
    help_txt = """Select mainline revision that merged the specified revision.
950
 
 
951
 
    Select the revision that merged the specified revision into mainline.
952
 
    """
953
 
 
954
 
    prefix = 'mainline:'
955
 
 
956
 
    def _as_revision_id(self, context_branch):
957
 
        revspec = RevisionSpec.from_string(self.spec)
958
 
        if revspec.get_branch() is None:
959
 
            spec_branch = context_branch
960
 
        else:
961
 
            spec_branch = _mod_branch.Branch.open(revspec.get_branch())
962
 
        revision_id = revspec.as_revision_id(spec_branch)
963
 
        graph = context_branch.repository.get_graph()
964
 
        result = graph.find_lefthand_merger(revision_id,
965
 
                                            context_branch.last_revision())
966
 
        if result is None:
967
 
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch)
968
 
        return result
969
 
 
970
 
 
971
899
# The order in which we want to DWIM a revision spec without any prefix.
972
900
# revno is always tried first and isn't listed here, this is used by
973
901
# RevisionSpec_dwim._match_on
992
920
_register_revspec(RevisionSpec_ancestor)
993
921
_register_revspec(RevisionSpec_branch)
994
922
_register_revspec(RevisionSpec_submit)
995
 
_register_revspec(RevisionSpec_annotate)
996
 
_register_revspec(RevisionSpec_mainline)
997
923
 
998
924
# classes in this list should have a "prefix" attribute, against which
999
925
# string specs are matched