/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: Jelmer Vernooij
  • Date: 2011-02-25 15:24:22 UTC
  • mto: This revision was merged to the branch mainline in revision 5690.
  • Revision ID: jelmer@samba.org-20110225152422-d1pjdfnzsw5ufe2x
Fix tests on Debian GNU/kFreeBSD by treating it like other FreeBSD-kernel-based systems.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
lazy_import(globals(), """
22
22
import bisect
23
23
import datetime
 
24
 
 
25
from bzrlib import (
 
26
    workingtree,
 
27
    )
24
28
""")
25
29
 
26
30
from bzrlib import (
 
31
    branch as _mod_branch,
27
32
    errors,
28
33
    osutils,
29
34
    registry,
30
35
    revision,
31
36
    symbol_versioning,
32
37
    trace,
 
38
    workingtree,
33
39
    )
34
40
 
35
41
 
166
172
                         spectype.__name__, spec)
167
173
            return spectype(spec, _internal=True)
168
174
        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
175
            # Otherwise treat it as a DWIM, build the RevisionSpec object and
175
176
            # wait for _match_on to be called.
176
177
            return RevisionSpec_dwim(spec, _internal=True)
302
303
    # each revspec we try.
303
304
    wants_revision_history = False
304
305
 
 
306
    # The revspecs to try
 
307
    _possible_revspecs = []
 
308
 
305
309
    def _try_spectype(self, rstype, branch):
306
310
        rs = rstype(self.spec, _internal=True)
307
311
        # Hit in_history to find out if it exists, or we need to try the
322
326
                pass
323
327
 
324
328
        # Next see what has been registered
 
329
        for objgetter in self._possible_revspecs:
 
330
            rs_class = objgetter.get_obj()
 
331
            try:
 
332
                return self._try_spectype(rs_class, branch)
 
333
            except rs_class.dwim_catchable_exceptions:
 
334
                pass
 
335
 
 
336
        # Try the old (deprecated) dwim list:
325
337
        for rs_class in dwim_revspecs:
326
338
            try:
327
339
                return self._try_spectype(rs_class, branch)
333
345
        # really relevant.
334
346
        raise errors.InvalidRevisionSpec(self.spec, branch)
335
347
 
 
348
    @classmethod
 
349
    def append_possible_revspec(cls, revspec):
 
350
        """Append a possible DWIM revspec.
 
351
 
 
352
        :param revspec: Revision spec to try.
 
353
        """
 
354
        cls._possible_revspecs.append(registry._ObjectGetter(revspec))
 
355
 
 
356
    @classmethod
 
357
    def append_possible_lazy_revspec(cls, module_name, member_name):
 
358
        """Append a possible lazily loaded DWIM revspec.
 
359
 
 
360
        :param module_name: Name of the module with the revspec
 
361
        :param member_name: Name of the revspec within the module
 
362
        """
 
363
        cls._possible_revspecs.append(
 
364
            registry._LazyObjectGetter(module_name, member_name))
 
365
 
336
366
 
337
367
class RevisionSpec_revno(RevisionSpec):
338
368
    """Selects a revision using a number."""
444
474
 
445
475
 
446
476
 
447
 
class RevisionSpec_revid(RevisionSpec):
 
477
class RevisionIDSpec(RevisionSpec):
 
478
 
 
479
    def _match_on(self, branch, revs):
 
480
        revision_id = self.as_revision_id(branch)
 
481
        return RevisionInfo.from_revision_id(branch, revision_id, revs)
 
482
 
 
483
 
 
484
class RevisionSpec_revid(RevisionIDSpec):
448
485
    """Selects a revision using the revision id."""
449
486
 
450
487
    help_txt = """Selects a revision using the revision id.
459
496
 
460
497
    prefix = 'revid:'
461
498
 
462
 
    def _match_on(self, branch, revs):
 
499
    def _as_revision_id(self, context_branch):
463
500
        # self.spec comes straight from parsing the command line arguments,
464
501
        # so we expect it to be a Unicode string. Switch it to the internal
465
502
        # 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
503
        return osutils.safe_revision_id(self.spec, warn=False)
471
504
 
472
505
 
813
846
        revision_b = other_branch.last_revision()
814
847
        if revision_b in (None, revision.NULL_REVISION):
815
848
            raise errors.NoCommits(other_branch)
816
 
        # pull in the remote revisions so we can diff
817
 
        branch.fetch(other_branch, revision_b)
 
849
        if branch is None:
 
850
            branch = other_branch
 
851
        else:
 
852
            try:
 
853
                # pull in the remote revisions so we can diff
 
854
                branch.fetch(other_branch, revision_b)
 
855
            except errors.ReadOnlyError:
 
856
                branch = other_branch
818
857
        try:
819
858
            revno = branch.revision_id_to_revno(revision_b)
820
859
        except errors.NoSuchRevision:
840
879
            raise errors.NoCommits(other_branch)
841
880
        return other_branch.repository.revision_tree(last_revision)
842
881
 
 
882
    def needs_branch(self):
 
883
        return False
 
884
 
 
885
    def get_branch(self):
 
886
        return self.spec
 
887
 
843
888
 
844
889
 
845
890
class RevisionSpec_submit(RevisionSpec_ancestor):
884
929
            self._get_submit_location(context_branch))
885
930
 
886
931
 
 
932
class RevisionSpec_annotate(RevisionIDSpec):
 
933
 
 
934
    prefix = 'annotate:'
 
935
 
 
936
    help_txt = """Select the revision that last modified the specified line.
 
937
 
 
938
    Select the revision that last modified the specified line.  Line is
 
939
    specified as path:number.  Path is a relative path to the file.  Numbers
 
940
    start at 1, and are relative to the current version, not the last-
 
941
    committed version of the file.
 
942
    """
 
943
 
 
944
    def _raise_invalid(self, numstring, context_branch):
 
945
        raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
 
946
            'No such line: %s' % numstring)
 
947
 
 
948
    def _as_revision_id(self, context_branch):
 
949
        path, numstring = self.spec.rsplit(':', 1)
 
950
        try:
 
951
            index = int(numstring) - 1
 
952
        except ValueError:
 
953
            self._raise_invalid(numstring, context_branch)
 
954
        tree, file_path = workingtree.WorkingTree.open_containing(path)
 
955
        tree.lock_read()
 
956
        try:
 
957
            file_id = tree.path2id(file_path)
 
958
            if file_id is None:
 
959
                raise errors.InvalidRevisionSpec(self.user_spec,
 
960
                    context_branch, "File '%s' is not versioned." %
 
961
                    file_path)
 
962
            revision_ids = [r for (r, l) in tree.annotate_iter(file_id)]
 
963
        finally:
 
964
            tree.unlock()
 
965
        try:
 
966
            revision_id = revision_ids[index]
 
967
        except IndexError:
 
968
            self._raise_invalid(numstring, context_branch)
 
969
        if revision_id == revision.CURRENT_REVISION:
 
970
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
 
971
                'Line %s has not been committed.' % numstring)
 
972
        return revision_id
 
973
 
 
974
 
 
975
class RevisionSpec_mainline(RevisionIDSpec):
 
976
 
 
977
    help_txt = """Select mainline revision that merged the specified revision.
 
978
 
 
979
    Select the revision that merged the specified revision into mainline.
 
980
    """
 
981
 
 
982
    prefix = 'mainline:'
 
983
 
 
984
    def _as_revision_id(self, context_branch):
 
985
        revspec = RevisionSpec.from_string(self.spec)
 
986
        if revspec.get_branch() is None:
 
987
            spec_branch = context_branch
 
988
        else:
 
989
            spec_branch = _mod_branch.Branch.open(revspec.get_branch())
 
990
        revision_id = revspec.as_revision_id(spec_branch)
 
991
        graph = context_branch.repository.get_graph()
 
992
        result = graph.find_lefthand_merger(revision_id,
 
993
                                            context_branch.last_revision())
 
994
        if result is None:
 
995
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch)
 
996
        return result
 
997
 
 
998
 
887
999
# The order in which we want to DWIM a revision spec without any prefix.
888
1000
# revno is always tried first and isn't listed here, this is used by
889
1001
# RevisionSpec_dwim._match_on
890
 
dwim_revspecs = [
891
 
    RevisionSpec_tag, # Let's try for a tag
892
 
    RevisionSpec_revid, # Maybe it's a revid?
893
 
    RevisionSpec_date, # Perhaps a date?
894
 
    RevisionSpec_branch, # OK, last try, maybe it's a branch
895
 
    ]
 
1002
dwim_revspecs = symbol_versioning.deprecated_list(
 
1003
    symbol_versioning.deprecated_in((2, 4, 0)), "dwim_revspecs", [])
896
1004
 
 
1005
RevisionSpec_dwim.append_possible_revspec(RevisionSpec_tag)
 
1006
RevisionSpec_dwim.append_possible_revspec(RevisionSpec_revid)
 
1007
RevisionSpec_dwim.append_possible_revspec(RevisionSpec_date)
 
1008
RevisionSpec_dwim.append_possible_revspec(RevisionSpec_branch)
897
1009
 
898
1010
revspec_registry = registry.Registry()
899
1011
def _register_revspec(revspec):
908
1020
_register_revspec(RevisionSpec_ancestor)
909
1021
_register_revspec(RevisionSpec_branch)
910
1022
_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", [])
 
1023
_register_revspec(RevisionSpec_annotate)
 
1024
_register_revspec(RevisionSpec_mainline)