~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/revisionspec.py

Merge pt1 hooks branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
 
 
18
import re
 
19
 
18
20
from bzrlib.lazy_import import lazy_import
19
21
lazy_import(globals(), """
20
22
import bisect
21
23
import datetime
 
24
""")
22
25
 
23
26
from bzrlib import (
24
27
    branch as _mod_branch,
 
28
    errors,
25
29
    osutils,
 
30
    registry,
26
31
    revision,
27
32
    symbol_versioning,
 
33
    trace,
28
34
    workingtree,
29
35
    )
30
 
from bzrlib.i18n import gettext
31
 
""")
32
 
 
33
 
from bzrlib import (
34
 
    errors,
35
 
    lazy_regex,
36
 
    registry,
37
 
    trace,
38
 
    )
39
36
 
40
37
 
41
38
_marker = []
118
115
        return RevisionInfo(branch, revno, revision_id)
119
116
 
120
117
 
 
118
_revno_regex = None
 
119
 
 
120
 
121
121
class RevisionSpec(object):
122
122
    """A parsed revision specification."""
123
123
 
168
168
                         spectype.__name__, spec)
169
169
            return spectype(spec, _internal=True)
170
170
        else:
 
171
            for spectype in SPEC_TYPES:
 
172
                if spec.startswith(spectype.prefix):
 
173
                    trace.mutter('Returning RevisionSpec %s for %s',
 
174
                                 spectype.__name__, spec)
 
175
                    return spectype(spec, _internal=True)
171
176
            # Otherwise treat it as a DWIM, build the RevisionSpec object and
172
177
            # wait for _match_on to be called.
173
178
            return RevisionSpec_dwim(spec, _internal=True)
299
304
    # each revspec we try.
300
305
    wants_revision_history = False
301
306
 
302
 
    _revno_regex = lazy_regex.lazy_compile(r'^(?:(\d+(\.\d+)*)|-\d+)(:.*)?$')
303
 
 
304
 
    # The revspecs to try
305
 
    _possible_revspecs = []
306
 
 
307
307
    def _try_spectype(self, rstype, branch):
308
308
        rs = rstype(self.spec, _internal=True)
309
309
        # Hit in_history to find out if it exists, or we need to try the
314
314
        """Run the lookup and see what we can get."""
315
315
 
316
316
        # First, see if it's a revno
317
 
        if self._revno_regex.match(self.spec) is not None:
 
317
        global _revno_regex
 
318
        if _revno_regex is None:
 
319
            _revno_regex = re.compile(r'^(?:(\d+(\.\d+)*)|-\d+)(:.*)?$')
 
320
        if _revno_regex.match(self.spec) is not None:
318
321
            try:
319
322
                return self._try_spectype(RevisionSpec_revno, branch)
320
323
            except RevisionSpec_revno.dwim_catchable_exceptions:
321
324
                pass
322
325
 
323
326
        # Next see what has been registered
324
 
        for objgetter in self._possible_revspecs:
325
 
            rs_class = objgetter.get_obj()
326
 
            try:
327
 
                return self._try_spectype(rs_class, branch)
328
 
            except rs_class.dwim_catchable_exceptions:
329
 
                pass
330
 
 
331
 
        # Try the old (deprecated) dwim list:
332
327
        for rs_class in dwim_revspecs:
333
328
            try:
334
329
                return self._try_spectype(rs_class, branch)
340
335
        # really relevant.
341
336
        raise errors.InvalidRevisionSpec(self.spec, branch)
342
337
 
343
 
    @classmethod
344
 
    def append_possible_revspec(cls, revspec):
345
 
        """Append a possible DWIM revspec.
346
 
 
347
 
        :param revspec: Revision spec to try.
348
 
        """
349
 
        cls._possible_revspecs.append(registry._ObjectGetter(revspec))
350
 
 
351
 
    @classmethod
352
 
    def append_possible_lazy_revspec(cls, module_name, member_name):
353
 
        """Append a possible lazily loaded DWIM revspec.
354
 
 
355
 
        :param module_name: Name of the module with the revspec
356
 
        :param member_name: Name of the revspec within the module
357
 
        """
358
 
        cls._possible_revspecs.append(
359
 
            registry._LazyObjectGetter(module_name, member_name))
360
 
 
361
338
 
362
339
class RevisionSpec_revno(RevisionSpec):
363
340
    """Selects a revision using a number."""
686
663
                                   August 14th, 2006 at 5:10pm.
687
664
    """
688
665
    prefix = 'date:'
689
 
    _date_regex = lazy_regex.lazy_compile(
 
666
    _date_re = re.compile(
690
667
            r'(?P<date>(?P<year>\d\d\d\d)-(?P<month>\d\d)-(?P<day>\d\d))?'
691
668
            r'(,|T)?\s*'
692
669
            r'(?P<time>(?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d))?)?'
710
687
        elif self.spec.lower() == 'tomorrow':
711
688
            dt = today + datetime.timedelta(days=1)
712
689
        else:
713
 
            m = self._date_regex.match(self.spec)
 
690
            m = self._date_re.match(self.spec)
714
691
            if not m or (not m.group('date') and not m.group('time')):
715
692
                raise errors.InvalidRevisionSpec(self.user_spec,
716
693
                                                 branch, 'invalid date')
911
888
            location_type = 'parent branch'
912
889
        if submit_location is None:
913
890
            raise errors.NoSubmitBranch(branch)
914
 
        trace.note(gettext('Using {0} {1}').format(location_type,
915
 
                                                        submit_location))
 
891
        trace.note('Using %s %s', location_type, submit_location)
916
892
        return submit_location
917
893
 
918
894
    def _match_on(self, branch, revs):
995
971
# The order in which we want to DWIM a revision spec without any prefix.
996
972
# revno is always tried first and isn't listed here, this is used by
997
973
# RevisionSpec_dwim._match_on
998
 
dwim_revspecs = symbol_versioning.deprecated_list(
999
 
    symbol_versioning.deprecated_in((2, 4, 0)), "dwim_revspecs", [])
 
974
dwim_revspecs = [
 
975
    RevisionSpec_tag, # Let's try for a tag
 
976
    RevisionSpec_revid, # Maybe it's a revid?
 
977
    RevisionSpec_date, # Perhaps a date?
 
978
    RevisionSpec_branch, # OK, last try, maybe it's a branch
 
979
    ]
1000
980
 
1001
 
RevisionSpec_dwim.append_possible_revspec(RevisionSpec_tag)
1002
 
RevisionSpec_dwim.append_possible_revspec(RevisionSpec_revid)
1003
 
RevisionSpec_dwim.append_possible_revspec(RevisionSpec_date)
1004
 
RevisionSpec_dwim.append_possible_revspec(RevisionSpec_branch)
1005
981
 
1006
982
revspec_registry = registry.Registry()
1007
983
def _register_revspec(revspec):
1018
994
_register_revspec(RevisionSpec_submit)
1019
995
_register_revspec(RevisionSpec_annotate)
1020
996
_register_revspec(RevisionSpec_mainline)
 
997
 
 
998
# classes in this list should have a "prefix" attribute, against which
 
999
# string specs are matched
 
1000
SPEC_TYPES = symbol_versioning.deprecated_list(
 
1001
    symbol_versioning.deprecated_in((1, 12, 0)), "SPEC_TYPES", [])