/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 breezy/option.py

  • Committer: Gustav Hartvigsson
  • Date: 2021-01-09 21:36:27 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20210109213627-h1xwcutzy9m7a99b
Added 'Case Preserving Working Tree Use Cases' from Canonical Wiki

* Addod a page from the Canonical Bazaar wiki
  with information on the scmeatics of case
  perserving filesystems an a case insensitive
  filesystem works.
  
  * Needs re-work, but this will do as it is the
    same inforamoton as what was on the linked
    page in the currint documentation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005-2010 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
# TODO: For things like --diff-prefix, we want a way to customize the display
 
18
# of the option argument.
 
19
 
 
20
import optparse
 
21
import re
 
22
 
 
23
from . import (
 
24
    errors,
 
25
    registry as _mod_registry,
 
26
    revisionspec,
 
27
    )
 
28
 
 
29
 
 
30
class BadOptionValue(errors.BzrError):
 
31
 
 
32
    _fmt = """Bad value "%(value)s" for option "%(name)s"."""
 
33
 
 
34
    def __init__(self, name, value):
 
35
        errors.BzrError.__init__(self, name=name, value=value)
 
36
 
 
37
 
 
38
def _parse_revision_str(revstr):
 
39
    """This handles a revision string -> revno.
 
40
 
 
41
    This always returns a list.  The list will have one element for
 
42
    each revision specifier supplied.
 
43
 
 
44
    >>> _parse_revision_str('234')
 
45
    [<RevisionSpec_dwim 234>]
 
46
    >>> _parse_revision_str('234..567')
 
47
    [<RevisionSpec_dwim 234>, <RevisionSpec_dwim 567>]
 
48
    >>> _parse_revision_str('..')
 
49
    [<RevisionSpec None>, <RevisionSpec None>]
 
50
    >>> _parse_revision_str('..234')
 
51
    [<RevisionSpec None>, <RevisionSpec_dwim 234>]
 
52
    >>> _parse_revision_str('234..')
 
53
    [<RevisionSpec_dwim 234>, <RevisionSpec None>]
 
54
    >>> _parse_revision_str('234..456..789') # Maybe this should be an error
 
55
    [<RevisionSpec_dwim 234>, <RevisionSpec_dwim 456>, <RevisionSpec_dwim 789>]
 
56
    >>> _parse_revision_str('234....789') #Error ?
 
57
    [<RevisionSpec_dwim 234>, <RevisionSpec None>, <RevisionSpec_dwim 789>]
 
58
    >>> _parse_revision_str('revid:test@other.com-234234')
 
59
    [<RevisionSpec_revid revid:test@other.com-234234>]
 
60
    >>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
 
61
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revid revid:test@other.com-234235>]
 
62
    >>> _parse_revision_str('revid:test@other.com-234234..23')
 
63
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_dwim 23>]
 
64
    >>> _parse_revision_str('date:2005-04-12')
 
65
    [<RevisionSpec_date date:2005-04-12>]
 
66
    >>> _parse_revision_str('date:2005-04-12 12:24:33')
 
67
    [<RevisionSpec_date date:2005-04-12 12:24:33>]
 
68
    >>> _parse_revision_str('date:2005-04-12T12:24:33')
 
69
    [<RevisionSpec_date date:2005-04-12T12:24:33>]
 
70
    >>> _parse_revision_str('date:2005-04-12,12:24:33')
 
71
    [<RevisionSpec_date date:2005-04-12,12:24:33>]
 
72
    >>> _parse_revision_str('-5..23')
 
73
    [<RevisionSpec_dwim -5>, <RevisionSpec_dwim 23>]
 
74
    >>> _parse_revision_str('-5')
 
75
    [<RevisionSpec_dwim -5>]
 
76
    >>> _parse_revision_str('123a')
 
77
    [<RevisionSpec_dwim 123a>]
 
78
    >>> _parse_revision_str('abc')
 
79
    [<RevisionSpec_dwim abc>]
 
80
    >>> _parse_revision_str('branch:../branch2')
 
81
    [<RevisionSpec_branch branch:../branch2>]
 
82
    >>> _parse_revision_str('branch:../../branch2')
 
83
    [<RevisionSpec_branch branch:../../branch2>]
 
84
    >>> _parse_revision_str('branch:../../branch2..23')
 
85
    [<RevisionSpec_branch branch:../../branch2>, <RevisionSpec_dwim 23>]
 
86
    >>> _parse_revision_str('branch:..\\\\branch2')
 
87
    [<RevisionSpec_branch branch:..\\branch2>]
 
88
    >>> _parse_revision_str('branch:..\\\\..\\\\branch2..23')
 
89
    [<RevisionSpec_branch branch:..\\..\\branch2>, <RevisionSpec_dwim 23>]
 
90
    """
 
91
    # TODO: Maybe move this into revisionspec.py
 
92
    revs = []
 
93
    # split on .. that is not followed by a / or \
 
94
    sep = re.compile(r'\.\.(?![\\/])')
 
95
    for x in sep.split(revstr):
 
96
        revs.append(revisionspec.RevisionSpec.from_string(x or None))
 
97
    return revs
 
98
 
 
99
 
 
100
def _parse_change_str(revstr):
 
101
    """Parse the revision string and return a tuple with left-most
 
102
    parent of the revision.
 
103
 
 
104
    >>> _parse_change_str('123')
 
105
    (<RevisionSpec_before before:123>, <RevisionSpec_dwim 123>)
 
106
    >>> _parse_change_str('123..124')
 
107
    Traceback (most recent call last):
 
108
      ...
 
109
    breezy.errors.RangeInChangeOption: Option --change does not accept revision ranges
 
110
    """
 
111
    revs = _parse_revision_str(revstr)
 
112
    if len(revs) > 1:
 
113
        raise errors.RangeInChangeOption()
 
114
    return (revisionspec.RevisionSpec.from_string('before:' + revstr),
 
115
            revs[0])
 
116
 
 
117
 
 
118
def _parse_merge_type(typestring):
 
119
    return get_merge_type(typestring)
 
120
 
 
121
 
 
122
def get_merge_type(typestring):
 
123
    """Attempt to find the merge class/factory associated with a string."""
 
124
    from merge import merge_types
 
125
    try:
 
126
        return merge_types[typestring][0]
 
127
    except KeyError:
 
128
        templ = '%s%%7s: %%s' % (' ' * 12)
 
129
        lines = [templ % (f[0], f[1][1]) for f in merge_types.items()]
 
130
        type_list = '\n'.join(lines)
 
131
        msg = "No known merge type %s. Supported types are:\n%s" %\
 
132
            (typestring, type_list)
 
133
        raise errors.CommandError(msg)
 
134
 
 
135
 
 
136
class Option(object):
 
137
    """Description of a command line option
 
138
 
 
139
    :ivar _short_name: If this option has a single-letter name, this is it.
 
140
    Otherwise None.
 
141
    """
 
142
 
 
143
    # The dictionary of standard options. These are always legal.
 
144
    STD_OPTIONS = {}
 
145
 
 
146
    # The dictionary of commonly used options. these are only legal
 
147
    # if a command explicitly references them by name in the list
 
148
    # of supported options.
 
149
    OPTIONS = {}
 
150
 
 
151
    def __init__(self, name, help='', type=None, argname=None,
 
152
                 short_name=None, param_name=None, custom_callback=None,
 
153
                 hidden=False):
 
154
        """Make a new command option.
 
155
 
 
156
        :param name: regular name of the command, used in the double-dash
 
157
            form and also as the parameter to the command's run()
 
158
            method (unless param_name is specified).
 
159
 
 
160
        :param help: help message displayed in command help
 
161
 
 
162
        :param type: function called to parse the option argument, or
 
163
            None (default) if this option doesn't take an argument.
 
164
 
 
165
        :param argname: name of option argument, if any
 
166
 
 
167
        :param short_name: short option code for use with a single -, e.g.
 
168
            short_name="v" to enable parsing of -v.
 
169
 
 
170
        :param param_name: name of the parameter which will be passed to
 
171
            the command's run() method.
 
172
 
 
173
        :param custom_callback: a callback routine to be called after normal
 
174
            processing. The signature of the callback routine is
 
175
            (option, name, new_value, parser).
 
176
        :param hidden: If True, the option should be hidden in help and
 
177
            documentation.
 
178
        """
 
179
        self.name = name
 
180
        self.help = help
 
181
        self.type = type
 
182
        self._short_name = short_name
 
183
        if type is None:
 
184
            if argname:
 
185
                raise ValueError('argname not valid for booleans')
 
186
        elif argname is None:
 
187
            argname = 'ARG'
 
188
        self.argname = argname
 
189
        if param_name is None:
 
190
            self._param_name = self.name.replace('-', '_')
 
191
        else:
 
192
            self._param_name = param_name
 
193
        self.custom_callback = custom_callback
 
194
        self.hidden = hidden
 
195
 
 
196
    def short_name(self):
 
197
        if self._short_name:
 
198
            return self._short_name
 
199
 
 
200
    def set_short_name(self, short_name):
 
201
        self._short_name = short_name
 
202
 
 
203
    def get_negation_name(self):
 
204
        if self.name.startswith('no-'):
 
205
            return self.name[3:]
 
206
        else:
 
207
            return 'no-' + self.name
 
208
 
 
209
    def add_option(self, parser, short_name):
 
210
        """Add this option to an Optparse parser"""
 
211
        option_strings = ['--%s' % self.name]
 
212
        if short_name is not None:
 
213
            option_strings.append('-%s' % short_name)
 
214
        if self.hidden:
 
215
            help = optparse.SUPPRESS_HELP
 
216
        else:
 
217
            help = self.help
 
218
        optargfn = self.type
 
219
        if optargfn is None:
 
220
            parser.add_option(action='callback',
 
221
                              callback=self._optparse_bool_callback,
 
222
                              callback_args=(True,),
 
223
                              help=help,
 
224
                              *option_strings)
 
225
            negation_strings = ['--%s' % self.get_negation_name()]
 
226
            parser.add_option(action='callback',
 
227
                              callback=self._optparse_bool_callback,
 
228
                              callback_args=(False,),
 
229
                              help=optparse.SUPPRESS_HELP, *negation_strings)
 
230
        else:
 
231
            parser.add_option(action='callback',
 
232
                              callback=self._optparse_callback,
 
233
                              type='string', metavar=self.argname.upper(),
 
234
                              help=help,
 
235
                              default=OptionParser.DEFAULT_VALUE,
 
236
                              *option_strings)
 
237
 
 
238
    def _optparse_bool_callback(self, option, opt_str, value, parser, bool_v):
 
239
        setattr(parser.values, self._param_name, bool_v)
 
240
        if self.custom_callback is not None:
 
241
            self.custom_callback(option, self._param_name, bool_v, parser)
 
242
 
 
243
    def _optparse_callback(self, option, opt, value, parser):
 
244
        try:
 
245
            v = self.type(value)
 
246
        except ValueError as e:
 
247
            raise optparse.OptionValueError(
 
248
                'invalid value for option %s: %s' % (option, value))
 
249
        setattr(parser.values, self._param_name, v)
 
250
        if self.custom_callback is not None:
 
251
            self.custom_callback(option, self.name, v, parser)
 
252
 
 
253
    def iter_switches(self):
 
254
        """Iterate through the list of switches provided by the option
 
255
 
 
256
        :return: an iterator of (name, short_name, argname, help)
 
257
        """
 
258
        argname = self.argname
 
259
        if argname is not None:
 
260
            argname = argname.upper()
 
261
        yield self.name, self.short_name(), argname, self.help
 
262
 
 
263
    def is_hidden(self, name):
 
264
        return self.hidden
 
265
 
 
266
 
 
267
class ListOption(Option):
 
268
    """Option used to provide a list of values.
 
269
 
 
270
    On the command line, arguments are specified by a repeated use of the
 
271
    option. '-' is a special argument that resets the list. For example,
 
272
      --foo=a --foo=b
 
273
    sets the value of the 'foo' option to ['a', 'b'], and
 
274
      --foo=a --foo=b --foo=- --foo=c
 
275
    sets the value of the 'foo' option to ['c'].
 
276
    """
 
277
 
 
278
    def add_option(self, parser, short_name):
 
279
        """Add this option to an Optparse parser."""
 
280
        option_strings = ['--%s' % self.name]
 
281
        if short_name is not None:
 
282
            option_strings.append('-%s' % short_name)
 
283
        parser.add_option(action='callback',
 
284
                          callback=self._optparse_callback,
 
285
                          type='string', metavar=self.argname.upper(),
 
286
                          help=self.help, dest=self._param_name, default=[],
 
287
                          *option_strings)
 
288
 
 
289
    def _optparse_callback(self, option, opt, value, parser):
 
290
        values = getattr(parser.values, self._param_name)
 
291
        if value == '-':
 
292
            del values[:]
 
293
        else:
 
294
            values.append(self.type(value))
 
295
        if self.custom_callback is not None:
 
296
            self.custom_callback(option, self._param_name, values, parser)
 
297
 
 
298
 
 
299
class RegistryOption(Option):
 
300
    """Option based on a registry
 
301
 
 
302
    The values for the options correspond to entries in the registry.  Input
 
303
    must be a registry key.  After validation, it is converted into an object
 
304
    using Registry.get or a caller-provided converter.
 
305
    """
 
306
 
 
307
    def validate_value(self, value):
 
308
        """Validate a value name"""
 
309
        if value not in self.registry:
 
310
            raise BadOptionValue(self.name, value)
 
311
 
 
312
    def convert(self, value):
 
313
        """Convert a value name into an output type"""
 
314
        self.validate_value(value)
 
315
        if self.converter is None:
 
316
            return self.registry.get(value)
 
317
        else:
 
318
            return self.converter(value)
 
319
 
 
320
    def __init__(self, name, help, registry=None, converter=None,
 
321
                 value_switches=False, title=None, enum_switch=True,
 
322
                 lazy_registry=None, short_name=None, short_value_switches=None):
 
323
        """
 
324
        Constructor.
 
325
 
 
326
        :param name: The option name.
 
327
        :param help: Help for the option.
 
328
        :param registry: A Registry containing the values
 
329
        :param converter: Callable to invoke with the value name to produce
 
330
            the value.  If not supplied, self.registry.get is used.
 
331
        :param value_switches: If true, each possible value is assigned its
 
332
            own switch.  For example, instead of '--format knit',
 
333
            '--knit' can be used interchangeably.
 
334
        :param enum_switch: If true, a switch is provided with the option name,
 
335
            which takes a value.
 
336
        :param lazy_registry: A tuple of (module name, attribute name) for a
 
337
            registry to be lazily loaded.
 
338
        :param short_name: The short name for the enum switch, if any
 
339
        :param short_value_switches: A dict mapping values to short names
 
340
        """
 
341
        Option.__init__(self, name, help, type=self.convert,
 
342
                        short_name=short_name)
 
343
        self._registry = registry
 
344
        if registry is None:
 
345
            if lazy_registry is None:
 
346
                raise AssertionError(
 
347
                    'One of registry or lazy_registry must be given.')
 
348
            self._lazy_registry = _mod_registry._LazyObjectGetter(
 
349
                *lazy_registry)
 
350
        if registry is not None and lazy_registry is not None:
 
351
            raise AssertionError(
 
352
                'registry and lazy_registry are mutually exclusive')
 
353
        self.name = name
 
354
        self.converter = converter
 
355
        self.value_switches = value_switches
 
356
        self.enum_switch = enum_switch
 
357
        self.short_value_switches = short_value_switches
 
358
        self.title = title
 
359
        if self.title is None:
 
360
            self.title = name
 
361
 
 
362
    @property
 
363
    def registry(self):
 
364
        if self._registry is None:
 
365
            self._registry = self._lazy_registry.get_obj()
 
366
        return self._registry
 
367
 
 
368
    @staticmethod
 
369
    def from_kwargs(name_, help=None, title=None, value_switches=False,
 
370
                    enum_switch=True, **kwargs):
 
371
        """Convenience method to generate string-map registry options
 
372
 
 
373
        name, help, value_switches and enum_switch are passed to the
 
374
        RegistryOption constructor.  Any other keyword arguments are treated
 
375
        as values for the option, and their value is treated as the help.
 
376
        """
 
377
        reg = _mod_registry.Registry()
 
378
        for name, switch_help in sorted(kwargs.items()):
 
379
            name = name.replace('_', '-')
 
380
            reg.register(name, name, help=switch_help)
 
381
            if not value_switches:
 
382
                help = help + '  "' + name + '": ' + switch_help
 
383
                if not help.endswith("."):
 
384
                    help = help + "."
 
385
        return RegistryOption(name_, help, reg, title=title,
 
386
                              value_switches=value_switches, enum_switch=enum_switch)
 
387
 
 
388
    def add_option(self, parser, short_name):
 
389
        """Add this option to an Optparse parser"""
 
390
        if self.value_switches:
 
391
            parser = parser.add_option_group(self.title)
 
392
        if self.enum_switch:
 
393
            Option.add_option(self, parser, short_name)
 
394
        if self.value_switches:
 
395
            alias_map = self.registry.alias_map()
 
396
            for key in self.registry.keys():
 
397
                if key in self.registry.aliases():
 
398
                    continue
 
399
                option_strings = [
 
400
                    ('--%s' % name)
 
401
                    for name in [key] +
 
402
                    [alias for alias in alias_map.get(key, [])
 
403
                        if not self.is_hidden(alias)]]
 
404
                if self.is_hidden(key):
 
405
                    help = optparse.SUPPRESS_HELP
 
406
                else:
 
407
                    help = self.registry.get_help(key)
 
408
                if (self.short_value_switches and
 
409
                        key in self.short_value_switches):
 
410
                    option_strings.append('-%s' %
 
411
                                          self.short_value_switches[key])
 
412
                parser.add_option(action='callback',
 
413
                                  callback=self._optparse_value_callback(key),
 
414
                                  help=help,
 
415
                                  *option_strings)
 
416
 
 
417
    def _optparse_value_callback(self, cb_value):
 
418
        def cb(option, opt, value, parser):
 
419
            v = self.type(cb_value)
 
420
            setattr(parser.values, self._param_name, v)
 
421
            if self.custom_callback is not None:
 
422
                self.custom_callback(option, self._param_name, v, parser)
 
423
        return cb
 
424
 
 
425
    def iter_switches(self):
 
426
        """Iterate through the list of switches provided by the option
 
427
 
 
428
        :return: an iterator of (name, short_name, argname, help)
 
429
        """
 
430
        for value in Option.iter_switches(self):
 
431
            yield value
 
432
        if self.value_switches:
 
433
            for key in sorted(self.registry.keys()):
 
434
                yield key, None, None, self.registry.get_help(key)
 
435
 
 
436
    def is_alias(self, name):
 
437
        """Check whether a particular format is an alias."""
 
438
        if name == self.name:
 
439
            return False
 
440
        return name in self.registry.aliases()
 
441
 
 
442
    def is_hidden(self, name):
 
443
        if name == self.name:
 
444
            return Option.is_hidden(self, name)
 
445
        return getattr(self.registry.get_info(name), 'hidden', False)
 
446
 
 
447
 
 
448
class OptionParser(optparse.OptionParser):
 
449
    """OptionParser that raises exceptions instead of exiting"""
 
450
 
 
451
    DEFAULT_VALUE = object()
 
452
 
 
453
    def __init__(self):
 
454
        optparse.OptionParser.__init__(self)
 
455
        self.formatter = GettextIndentedHelpFormatter()
 
456
 
 
457
    def error(self, message):
 
458
        raise errors.CommandError(message)
 
459
 
 
460
 
 
461
class GettextIndentedHelpFormatter(optparse.IndentedHelpFormatter):
 
462
    """Adds gettext() call to format_option()"""
 
463
 
 
464
    def __init__(self):
 
465
        optparse.IndentedHelpFormatter.__init__(self)
 
466
 
 
467
    def format_option(self, option):
 
468
        """code taken from Python's optparse.py"""
 
469
        if option.help:
 
470
            from .i18n import gettext
 
471
            option.help = gettext(option.help)
 
472
        return optparse.IndentedHelpFormatter.format_option(self, option)
 
473
 
 
474
 
 
475
def get_optparser(options):
 
476
    """Generate an optparse parser for breezy-style options"""
 
477
 
 
478
    parser = OptionParser()
 
479
    parser.remove_option('--help')
 
480
    for option in options:
 
481
        option.add_option(parser, option.short_name())
 
482
    return parser
 
483
 
 
484
 
 
485
def custom_help(name, help):
 
486
    """Clone a common option overriding the help."""
 
487
    import copy
 
488
    o = copy.copy(Option.OPTIONS[name])
 
489
    o.help = help
 
490
    return o
 
491
 
 
492
 
 
493
def _standard_option(name, **kwargs):
 
494
    """Register a standard option."""
 
495
    # All standard options are implicitly 'global' ones
 
496
    Option.STD_OPTIONS[name] = Option(name, **kwargs)
 
497
    Option.OPTIONS[name] = Option.STD_OPTIONS[name]
 
498
 
 
499
 
 
500
def _standard_list_option(name, **kwargs):
 
501
    """Register a standard option."""
 
502
    # All standard options are implicitly 'global' ones
 
503
    Option.STD_OPTIONS[name] = ListOption(name, **kwargs)
 
504
    Option.OPTIONS[name] = Option.STD_OPTIONS[name]
 
505
 
 
506
 
 
507
def _global_option(name, **kwargs):
 
508
    """Register a global option."""
 
509
    Option.OPTIONS[name] = Option(name, **kwargs)
 
510
 
 
511
 
 
512
def _global_registry_option(name, help, registry=None, **kwargs):
 
513
    Option.OPTIONS[name] = RegistryOption(name, help, registry, **kwargs)
 
514
 
 
515
 
 
516
# This is the verbosity level detected during command line parsing.
 
517
# Note that the final value is dependent on the order in which the
 
518
# various flags (verbose, quiet, no-verbose, no-quiet) are given.
 
519
# The final value will be one of the following:
 
520
#
 
521
# * -ve for quiet
 
522
# * 0 for normal
 
523
# * +ve for verbose
 
524
_verbosity_level = 0
 
525
 
 
526
 
 
527
def _verbosity_level_callback(option, opt_str, value, parser):
 
528
    global _verbosity_level
 
529
    if not value:
 
530
        # Either --no-verbose or --no-quiet was specified
 
531
        _verbosity_level = 0
 
532
    elif opt_str == "verbose":
 
533
        if _verbosity_level > 0:
 
534
            _verbosity_level += 1
 
535
        else:
 
536
            _verbosity_level = 1
 
537
    else:
 
538
        if _verbosity_level < 0:
 
539
            _verbosity_level -= 1
 
540
        else:
 
541
            _verbosity_level = -1
 
542
 
 
543
 
 
544
# Declare the standard options
 
545
_standard_option('help', short_name='h',
 
546
                 help='Show help message.')
 
547
_standard_option('quiet', short_name='q',
 
548
                 help="Only display errors and warnings.",
 
549
                 custom_callback=_verbosity_level_callback)
 
550
_standard_option('usage',
 
551
                 help='Show usage message and options.')
 
552
_standard_option('verbose', short_name='v',
 
553
                 help='Display more information.',
 
554
                 custom_callback=_verbosity_level_callback)
 
555
 
 
556
# Declare commonly used options
 
557
_global_option('change',
 
558
               type=_parse_change_str,
 
559
               short_name='c',
 
560
               param_name='revision',
 
561
               help='Select changes introduced by the specified revision. See also "help revisionspec".')
 
562
_global_option('directory', short_name='d', type=str,
 
563
               help='Branch to operate on, instead of working directory.')
 
564
_global_option('file', type=str, short_name='F')
 
565
_global_registry_option('log-format', "Use specified log format.",
 
566
                        lazy_registry=('breezy.log', 'log_formatter_registry'),
 
567
                        value_switches=True, title='Log format',
 
568
                        short_value_switches={'short': 'S'})
 
569
_global_registry_option('merge-type', 'Select a particular merge algorithm.',
 
570
                        lazy_registry=('breezy.merge', 'merge_type_registry'),
 
571
                        value_switches=True, title='Merge algorithm')
 
572
_global_option('message', type=str,
 
573
               short_name='m',
 
574
               help='Message string.')
 
575
_global_option('null', short_name='0',
 
576
               help='Use an ASCII NUL (\\0) separator rather than '
 
577
               'a newline.')
 
578
_global_option('overwrite', help='Ignore differences between branches and '
 
579
               'overwrite unconditionally.')
 
580
_global_option('remember', help='Remember the specified location as a'
 
581
               ' default.')
 
582
_global_option('reprocess', help='Reprocess to reduce spurious conflicts.')
 
583
_global_option('revision',
 
584
               type=_parse_revision_str,
 
585
               short_name='r',
 
586
               help='See "help revisionspec" for details.')
 
587
_global_option('show-ids',
 
588
               help='Show internal object ids.')
 
589
_global_option('timezone',
 
590
               type=str,
 
591
               help='Display timezone as local, original, or utc.')
 
592
 
 
593
diff_writer_registry = _mod_registry.Registry()
 
594
diff_writer_registry.register('plain', lambda x: x, 'Plaintext diff output.')
 
595
diff_writer_registry.default_key = 'plain'