~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Martin Packman
  • Date: 2012-01-05 10:37:58 UTC
  • mto: This revision was merged to the branch mainline in revision 6427.
  • Revision ID: martin.packman@canonical.com-20120105103758-wzftnmsip5iv9n2g
Revert addition of get_message_encoding function

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
import os
20
20
 
 
21
import bzrlib.bzrdir
 
22
 
21
23
from bzrlib.lazy_import import lazy_import
22
24
lazy_import(globals(), """
23
25
import cStringIO
 
26
import errno
24
27
import sys
25
28
import time
26
29
 
29
32
    bugtracker,
30
33
    bundle,
31
34
    btree_index,
32
 
    bzrdir,
 
35
    controldir,
33
36
    directory_service,
34
37
    delta,
35
38
    config as _mod_config,
57
60
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
58
61
from bzrlib.smtp_connection import SMTPConnection
59
62
from bzrlib.workingtree import WorkingTree
 
63
from bzrlib.i18n import gettext, ngettext
60
64
""")
61
65
 
62
66
from bzrlib.commands import (
112
116
            if view_files:
113
117
                file_list = view_files
114
118
                view_str = views.view_display_str(view_files)
115
 
                note("Ignoring files outside view. View is %s" % view_str)
 
119
                note(gettext("Ignoring files outside view. View is %s") % view_str)
116
120
    return tree, file_list
117
121
 
118
122
 
120
124
    if revisions is None:
121
125
        return None
122
126
    if len(revisions) != 1:
123
 
        raise errors.BzrCommandError(
124
 
            'bzr %s --revision takes exactly one revision identifier' % (
 
127
        raise errors.BzrCommandError(gettext(
 
128
            'bzr %s --revision takes exactly one revision identifier') % (
125
129
                command_name,))
126
130
    return revisions[0]
127
131
 
196
200
    the --directory option is used to specify a different branch."""
197
201
    if directory is not None:
198
202
        return (None, Branch.open(directory), filename)
199
 
    return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
 
203
    return controldir.ControlDir.open_containing_tree_or_branch(filename)
200
204
 
201
205
 
202
206
# TODO: Make sure no commands unconditionally use the working directory as a
232
236
    unknown
233
237
        Not versioned and not matching an ignore pattern.
234
238
 
235
 
    Additionally for directories, symlinks and files with an executable
236
 
    bit, Bazaar indicates their type using a trailing character: '/', '@'
237
 
    or '*' respectively.
 
239
    Additionally for directories, symlinks and files with a changed
 
240
    executable bit, Bazaar indicates their type using a trailing
 
241
    character: '/', '@' or '*' respectively. These decorations can be
 
242
    disabled using the '--no-classify' option.
238
243
 
239
244
    To see ignored files use 'bzr ignored'.  For details on the
240
245
    changes to file texts, use 'bzr diff'.
271
276
                            short_name='V'),
272
277
                     Option('no-pending', help='Don\'t show pending merges.',
273
278
                           ),
 
279
                     Option('no-classify',
 
280
                            help='Do not mark object type using indicator.',
 
281
                           ),
274
282
                     ]
275
283
    aliases = ['st', 'stat']
276
284
 
279
287
 
280
288
    @display_command
281
289
    def run(self, show_ids=False, file_list=None, revision=None, short=False,
282
 
            versioned=False, no_pending=False, verbose=False):
 
290
            versioned=False, no_pending=False, verbose=False,
 
291
            no_classify=False):
283
292
        from bzrlib.status import show_tree_status
284
293
 
285
294
        if revision and len(revision) > 2:
286
 
            raise errors.BzrCommandError('bzr status --revision takes exactly'
287
 
                                         ' one or two revision specifiers')
 
295
            raise errors.BzrCommandError(gettext('bzr status --revision takes exactly'
 
296
                                         ' one or two revision specifiers'))
288
297
 
289
298
        tree, relfile_list = WorkingTree.open_containing_paths(file_list)
290
299
        # Avoid asking for specific files when that is not needed.
299
308
        show_tree_status(tree, show_ids=show_ids,
300
309
                         specific_files=relfile_list, revision=revision,
301
310
                         to_file=self.outf, short=short, versioned=versioned,
302
 
                         show_pending=(not no_pending), verbose=verbose)
 
311
                         show_pending=(not no_pending), verbose=verbose,
 
312
                         classify=not no_classify)
303
313
 
304
314
 
305
315
class cmd_cat_revision(Command):
326
336
    @display_command
327
337
    def run(self, revision_id=None, revision=None, directory=u'.'):
328
338
        if revision_id is not None and revision is not None:
329
 
            raise errors.BzrCommandError('You can only supply one of'
330
 
                                         ' revision_id or --revision')
 
339
            raise errors.BzrCommandError(gettext('You can only supply one of'
 
340
                                         ' revision_id or --revision'))
331
341
        if revision_id is None and revision is None:
332
 
            raise errors.BzrCommandError('You must supply either'
333
 
                                         ' --revision or a revision_id')
 
342
            raise errors.BzrCommandError(gettext('You must supply either'
 
343
                                         ' --revision or a revision_id'))
334
344
 
335
 
        b = bzrdir.BzrDir.open_containing_tree_or_branch(directory)[1]
 
345
        b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
336
346
 
337
347
        revisions = b.repository.revisions
338
348
        if revisions is None:
339
 
            raise errors.BzrCommandError('Repository %r does not support '
340
 
                'access to raw revision texts')
 
349
            raise errors.BzrCommandError(gettext('Repository %r does not support '
 
350
                'access to raw revision texts'))
341
351
 
342
352
        b.repository.lock_read()
343
353
        try:
347
357
                try:
348
358
                    self.print_revision(revisions, revision_id)
349
359
                except errors.NoSuchRevision:
350
 
                    msg = "The repository %s contains no revision %s." % (
 
360
                    msg = gettext("The repository {0} contains no revision {1}.").format(
351
361
                        b.repository.base, revision_id)
352
362
                    raise errors.BzrCommandError(msg)
353
363
            elif revision is not None:
354
364
                for rev in revision:
355
365
                    if rev is None:
356
366
                        raise errors.BzrCommandError(
357
 
                            'You cannot specify a NULL revision.')
 
367
                            gettext('You cannot specify a NULL revision.'))
358
368
                    rev_id = rev.as_revision_id(b)
359
369
                    self.print_revision(revisions, rev_id)
360
370
        finally:
466
476
            location_list=['.']
467
477
 
468
478
        for location in location_list:
469
 
            d = bzrdir.BzrDir.open(location)
470
 
            
 
479
            d = controldir.ControlDir.open(location)
 
480
 
471
481
            try:
472
482
                working = d.open_workingtree()
473
483
            except errors.NoWorkingTree:
474
 
                raise errors.BzrCommandError("No working tree to remove")
 
484
                raise errors.BzrCommandError(gettext("No working tree to remove"))
475
485
            except errors.NotLocalUrl:
476
 
                raise errors.BzrCommandError("You cannot remove the working tree"
477
 
                                             " of a remote path")
 
486
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
487
                                             " of a remote path"))
478
488
            if not force:
479
489
                if (working.has_changes()):
480
490
                    raise errors.UncommittedChanges(working)
482
492
                    raise errors.ShelvedChanges(working)
483
493
 
484
494
            if working.user_url != working.branch.user_url:
485
 
                raise errors.BzrCommandError("You cannot remove the working tree"
486
 
                                             " from a lightweight checkout")
 
495
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
496
                                             " from a lightweight checkout"))
487
497
 
488
498
            d.destroy_workingtree()
489
499
 
521
531
                pass # There seems to be a real error here, so we'll reset
522
532
            else:
523
533
                # Refuse
524
 
                raise errors.BzrCommandError(
 
534
                raise errors.BzrCommandError(gettext(
525
535
                    'The tree does not appear to be corrupt. You probably'
526
536
                    ' want "bzr revert" instead. Use "--force" if you are'
527
 
                    ' sure you want to reset the working tree.')
 
537
                    ' sure you want to reset the working tree.'))
528
538
        if revision is None:
529
539
            revision_ids = None
530
540
        else:
533
543
            tree.reset_state(revision_ids)
534
544
        except errors.BzrError, e:
535
545
            if revision_ids is None:
536
 
                extra = (', the header appears corrupt, try passing -r -1'
537
 
                         ' to set the state to the last commit')
 
546
                extra = (gettext(', the header appears corrupt, try passing -r -1'
 
547
                         ' to set the state to the last commit'))
538
548
            else:
539
549
                extra = ''
540
 
            raise errors.BzrCommandError('failed to reset the tree state'
541
 
                                         + extra)
 
550
            raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
542
551
 
543
552
 
544
553
class cmd_revno(Command):
550
559
    _see_also = ['info']
551
560
    takes_args = ['location?']
552
561
    takes_options = [
553
 
        Option('tree', help='Show revno of working tree'),
 
562
        Option('tree', help='Show revno of working tree.'),
 
563
        'revision',
554
564
        ]
555
565
 
556
566
    @display_command
557
 
    def run(self, tree=False, location=u'.'):
 
567
    def run(self, tree=False, location=u'.', revision=None):
 
568
        if revision is not None and tree:
 
569
            raise errors.BzrCommandError(gettext("--tree and --revision can "
 
570
                "not be used together"))
 
571
 
558
572
        if tree:
559
573
            try:
560
574
                wt = WorkingTree.open_containing(location)[0]
561
575
                self.add_cleanup(wt.lock_read().unlock)
562
576
            except (errors.NoWorkingTree, errors.NotLocalUrl):
563
577
                raise errors.NoWorkingTree(location)
 
578
            b = wt.branch
564
579
            revid = wt.last_revision()
565
 
            try:
566
 
                revno_t = wt.branch.revision_id_to_dotted_revno(revid)
567
 
            except errors.NoSuchRevision:
568
 
                revno_t = ('???',)
569
 
            revno = ".".join(str(n) for n in revno_t)
570
580
        else:
571
581
            b = Branch.open_containing(location)[0]
572
582
            self.add_cleanup(b.lock_read().unlock)
573
 
            revno = b.revno()
 
583
            if revision:
 
584
                if len(revision) != 1:
 
585
                    raise errors.BzrCommandError(gettext(
 
586
                        "Tags can only be placed on a single revision, "
 
587
                        "not on a range"))
 
588
                revid = revision[0].as_revision_id(b)
 
589
            else:
 
590
                revid = b.last_revision()
 
591
        try:
 
592
            revno_t = b.revision_id_to_dotted_revno(revid)
 
593
        except errors.NoSuchRevision:
 
594
            revno_t = ('???',)
 
595
        revno = ".".join(str(n) for n in revno_t)
574
596
        self.cleanup_now()
575
 
        self.outf.write(str(revno) + '\n')
 
597
        self.outf.write(revno + '\n')
576
598
 
577
599
 
578
600
class cmd_revision_info(Command):
585
607
        custom_help('directory',
586
608
            help='Branch to examine, '
587
609
                 'rather than the one containing the working directory.'),
588
 
        Option('tree', help='Show revno of working tree'),
 
610
        Option('tree', help='Show revno of working tree.'),
589
611
        ]
590
612
 
591
613
    @display_command
647
669
    are added.  This search proceeds recursively into versioned
648
670
    directories.  If no names are given '.' is assumed.
649
671
 
 
672
    A warning will be printed when nested trees are encountered,
 
673
    unless they are explicitly ignored.
 
674
 
650
675
    Therefore simply saying 'bzr add' will version all files that
651
676
    are currently unknown.
652
677
 
668
693
    
669
694
    Any files matching patterns in the ignore list will not be added
670
695
    unless they are explicitly mentioned.
 
696
    
 
697
    In recursive mode, files larger than the configuration option 
 
698
    add.maximum_file_size will be skipped. Named items are never skipped due
 
699
    to file size.
671
700
    """
672
701
    takes_args = ['file*']
673
702
    takes_options = [
700
729
            action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
701
730
                          to_file=self.outf, should_print=(not is_quiet()))
702
731
        else:
703
 
            action = bzrlib.add.AddAction(to_file=self.outf,
 
732
            action = bzrlib.add.AddWithSkipLargeAction(to_file=self.outf,
704
733
                should_print=(not is_quiet()))
705
734
 
706
735
        if base_tree:
713
742
            if verbose:
714
743
                for glob in sorted(ignored.keys()):
715
744
                    for path in ignored[glob]:
716
 
                        self.outf.write("ignored %s matching \"%s\"\n"
717
 
                                        % (path, glob))
 
745
                        self.outf.write(
 
746
                         gettext("ignored {0} matching \"{1}\"\n").format(
 
747
                         path, glob))
718
748
 
719
749
 
720
750
class cmd_mkdir(Command):
724
754
    """
725
755
 
726
756
    takes_args = ['dir+']
 
757
    takes_options = [
 
758
        Option(
 
759
            'parents',
 
760
            help='No error if existing, make parent directories as needed.',
 
761
            short_name='p'
 
762
            )
 
763
        ]
727
764
    encoding_type = 'replace'
728
765
 
729
 
    def run(self, dir_list):
730
 
        for d in dir_list:
731
 
            wt, dd = WorkingTree.open_containing(d)
732
 
            base = os.path.dirname(dd)
733
 
            id = wt.path2id(base)
734
 
            if id != None:
735
 
                os.mkdir(d)
736
 
                wt.add([dd])
737
 
                self.outf.write('added %s\n' % d)
 
766
    @classmethod
 
767
    def add_file_with_parents(cls, wt, relpath):
 
768
        if wt.path2id(relpath) is not None:
 
769
            return
 
770
        cls.add_file_with_parents(wt, osutils.dirname(relpath))
 
771
        wt.add([relpath])
 
772
 
 
773
    @classmethod
 
774
    def add_file_single(cls, wt, relpath):
 
775
        wt.add([relpath])
 
776
 
 
777
    def run(self, dir_list, parents=False):
 
778
        if parents:
 
779
            add_file = self.add_file_with_parents
 
780
        else:
 
781
            add_file = self.add_file_single
 
782
        for dir in dir_list:
 
783
            wt, relpath = WorkingTree.open_containing(dir)
 
784
            if parents:
 
785
                try:
 
786
                    os.makedirs(dir)
 
787
                except OSError, e:
 
788
                    if e.errno != errno.EEXIST:
 
789
                        raise
738
790
            else:
739
 
                raise errors.NotVersionedError(path=base)
 
791
                os.mkdir(dir)
 
792
            add_file(wt, relpath)
 
793
            if not is_quiet():
 
794
                self.outf.write(gettext('added %s\n') % dir)
740
795
 
741
796
 
742
797
class cmd_relpath(Command):
778
833
    @display_command
779
834
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
780
835
        if kind and kind not in ['file', 'directory', 'symlink']:
781
 
            raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
 
836
            raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
782
837
 
783
838
        revision = _get_one_revision('inventory', revision)
784
839
        work_tree, file_list = WorkingTree.open_containing_paths(file_list)
848
903
        if auto:
849
904
            return self.run_auto(names_list, after, dry_run)
850
905
        elif dry_run:
851
 
            raise errors.BzrCommandError('--dry-run requires --auto.')
 
906
            raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
852
907
        if names_list is None:
853
908
            names_list = []
854
909
        if len(names_list) < 2:
855
 
            raise errors.BzrCommandError("missing file argument")
 
910
            raise errors.BzrCommandError(gettext("missing file argument"))
856
911
        tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
 
912
        for file_name in rel_names[0:-1]:
 
913
            if file_name == '':
 
914
                raise errors.BzrCommandError(gettext("can not move root of branch"))
857
915
        self.add_cleanup(tree.lock_tree_write().unlock)
858
916
        self._run(tree, names_list, rel_names, after)
859
917
 
860
918
    def run_auto(self, names_list, after, dry_run):
861
919
        if names_list is not None and len(names_list) > 1:
862
 
            raise errors.BzrCommandError('Only one path may be specified to'
863
 
                                         ' --auto.')
 
920
            raise errors.BzrCommandError(gettext('Only one path may be specified to'
 
921
                                         ' --auto.'))
864
922
        if after:
865
 
            raise errors.BzrCommandError('--after cannot be specified with'
866
 
                                         ' --auto.')
 
923
            raise errors.BzrCommandError(gettext('--after cannot be specified with'
 
924
                                         ' --auto.'))
867
925
        work_tree, file_list = WorkingTree.open_containing_paths(
868
926
            names_list, default_directory='.')
869
927
        self.add_cleanup(work_tree.lock_tree_write().unlock)
899
957
                    self.outf.write("%s => %s\n" % (src, dest))
900
958
        else:
901
959
            if len(names_list) != 2:
902
 
                raise errors.BzrCommandError('to mv multiple files the'
 
960
                raise errors.BzrCommandError(gettext('to mv multiple files the'
903
961
                                             ' destination must be a versioned'
904
 
                                             ' directory')
 
962
                                             ' directory'))
905
963
 
906
964
            # for cicp file-systems: the src references an existing inventory
907
965
            # item:
967
1025
    branches have diverged.
968
1026
 
969
1027
    If there is no default location set, the first pull will set it (use
970
 
    --no-remember to avoid settting it). After that, you can omit the
 
1028
    --no-remember to avoid setting it). After that, you can omit the
971
1029
    location to use the default.  To change the default, use --remember. The
972
1030
    value will only be saved if the remote location can be accessed.
973
1031
 
 
1032
    The --verbose option will display the revisions pulled using the log_format
 
1033
    configuration option. You can use a different format by overriding it with
 
1034
    -Olog_format=<other_format>.
 
1035
 
974
1036
    Note: The location can be specified either in the form of a branch,
975
1037
    or in the form of a path to a file containing a merge directive generated
976
1038
    with bzr send.
1013
1075
            self.add_cleanup(branch_to.lock_write().unlock)
1014
1076
 
1015
1077
        if tree_to is None and show_base:
1016
 
            raise errors.BzrCommandError("Need working tree for --show-base.")
 
1078
            raise errors.BzrCommandError(gettext("Need working tree for --show-base."))
1017
1079
 
1018
1080
        if local and not branch_to.get_bound_location():
1019
1081
            raise errors.LocalRequiresBoundBranch()
1029
1091
        stored_loc = branch_to.get_parent()
1030
1092
        if location is None:
1031
1093
            if stored_loc is None:
1032
 
                raise errors.BzrCommandError("No pull location known or"
1033
 
                                             " specified.")
 
1094
                raise errors.BzrCommandError(gettext("No pull location known or"
 
1095
                                             " specified."))
1034
1096
            else:
1035
1097
                display_url = urlutils.unescape_for_display(stored_loc,
1036
1098
                        self.outf.encoding)
1037
1099
                if not is_quiet():
1038
 
                    self.outf.write("Using saved parent location: %s\n" % display_url)
 
1100
                    self.outf.write(gettext("Using saved parent location: %s\n") % display_url)
1039
1101
                location = stored_loc
1040
1102
 
1041
1103
        revision = _get_one_revision('pull', revision)
1042
1104
        if mergeable is not None:
1043
1105
            if revision is not None:
1044
 
                raise errors.BzrCommandError(
1045
 
                    'Cannot use -r with merge directives or bundles')
 
1106
                raise errors.BzrCommandError(gettext(
 
1107
                    'Cannot use -r with merge directives or bundles'))
1046
1108
            mergeable.install_revisions(branch_to.repository)
1047
1109
            base_revision_id, revision_id, verified = \
1048
1110
                mergeable.get_merge_request(branch_to.repository)
1066
1128
                view_info=view_info)
1067
1129
            result = tree_to.pull(
1068
1130
                branch_from, overwrite, revision_id, change_reporter,
1069
 
                possible_transports=possible_transports, local=local,
1070
 
                show_base=show_base)
 
1131
                local=local, show_base=show_base)
1071
1132
        else:
1072
1133
            result = branch_to.pull(
1073
1134
                branch_from, overwrite, revision_id, local=local)
1104
1165
    After that you will be able to do a push without '--overwrite'.
1105
1166
 
1106
1167
    If there is no default push location set, the first push will set it (use
1107
 
    --no-remember to avoid settting it).  After that, you can omit the
 
1168
    --no-remember to avoid setting it).  After that, you can omit the
1108
1169
    location to use the default.  To change the default, use --remember. The
1109
1170
    value will only be saved if the remote location can be accessed.
 
1171
 
 
1172
    The --verbose option will display the revisions pushed using the log_format
 
1173
    configuration option. You can use a different format by overriding it with
 
1174
    -Olog_format=<other_format>.
1110
1175
    """
1111
1176
 
1112
1177
    _see_also = ['pull', 'update', 'working-trees']
1150
1215
            directory = '.'
1151
1216
        # Get the source branch
1152
1217
        (tree, br_from,
1153
 
         _unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
 
1218
         _unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
1154
1219
        # Get the tip's revision_id
1155
1220
        revision = _get_one_revision('push', revision)
1156
1221
        if revision is not None:
1177
1242
                    # error by the feedback given to them. RBC 20080227.
1178
1243
                    stacked_on = parent_url
1179
1244
            if not stacked_on:
1180
 
                raise errors.BzrCommandError(
1181
 
                    "Could not determine branch to refer to.")
 
1245
                raise errors.BzrCommandError(gettext(
 
1246
                    "Could not determine branch to refer to."))
1182
1247
 
1183
1248
        # Get the destination location
1184
1249
        if location is None:
1185
1250
            stored_loc = br_from.get_push_location()
1186
1251
            if stored_loc is None:
1187
 
                raise errors.BzrCommandError(
1188
 
                    "No push location known or specified.")
 
1252
                raise errors.BzrCommandError(gettext(
 
1253
                    "No push location known or specified."))
1189
1254
            else:
1190
1255
                display_url = urlutils.unescape_for_display(stored_loc,
1191
1256
                        self.outf.encoding)
1192
 
                self.outf.write("Using saved push location: %s\n" % display_url)
 
1257
                note(gettext("Using saved push location: %s") % display_url)
1193
1258
                location = stored_loc
1194
1259
 
1195
1260
        _show_push_branch(br_from, revision_id, location, self.outf,
1253
1318
                deprecated_name=self.invoked_as,
1254
1319
                recommended_name='branch',
1255
1320
                deprecated_in_version='2.4')
1256
 
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
 
1321
        accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1257
1322
            from_location)
1258
1323
        if not (hardlink or files_from):
1259
1324
            # accelerator_tree is usually slower because you have to read N
1272
1337
            # RBC 20060209
1273
1338
            revision_id = br_from.last_revision()
1274
1339
        if to_location is None:
1275
 
            to_location = urlutils.derive_to_location(from_location)
 
1340
            to_location = getattr(br_from, "name", None)
 
1341
            if to_location is None:
 
1342
                to_location = urlutils.derive_to_location(from_location)
1276
1343
        to_transport = transport.get_transport(to_location)
1277
1344
        try:
1278
1345
            to_transport.mkdir('.')
1279
1346
        except errors.FileExists:
1280
 
            if not use_existing_dir:
1281
 
                raise errors.BzrCommandError('Target directory "%s" '
1282
 
                    'already exists.' % to_location)
 
1347
            try:
 
1348
                to_dir = controldir.ControlDir.open_from_transport(
 
1349
                    to_transport)
 
1350
            except errors.NotBranchError:
 
1351
                if not use_existing_dir:
 
1352
                    raise errors.BzrCommandError(gettext('Target directory "%s" '
 
1353
                        'already exists.') % to_location)
 
1354
                else:
 
1355
                    to_dir = None
1283
1356
            else:
1284
1357
                try:
1285
 
                    bzrdir.BzrDir.open_from_transport(to_transport)
 
1358
                    to_dir.open_branch()
1286
1359
                except errors.NotBranchError:
1287
1360
                    pass
1288
1361
                else:
1289
1362
                    raise errors.AlreadyBranchError(to_location)
1290
1363
        except errors.NoSuchFile:
1291
 
            raise errors.BzrCommandError('Parent of "%s" does not exist.'
 
1364
            raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1292
1365
                                         % to_location)
1293
 
        try:
1294
 
            # preserve whatever source format we have.
1295
 
            dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1296
 
                                        possible_transports=[to_transport],
1297
 
                                        accelerator_tree=accelerator_tree,
1298
 
                                        hardlink=hardlink, stacked=stacked,
1299
 
                                        force_new_repo=standalone,
1300
 
                                        create_tree_if_local=not no_tree,
1301
 
                                        source_branch=br_from)
1302
 
            branch = dir.open_branch()
1303
 
        except errors.NoSuchRevision:
1304
 
            to_transport.delete_tree('.')
1305
 
            msg = "The branch %s has no revision %s." % (from_location,
1306
 
                revision)
1307
 
            raise errors.BzrCommandError(msg)
 
1366
        else:
 
1367
            to_dir = None
 
1368
        if to_dir is None:
 
1369
            try:
 
1370
                # preserve whatever source format we have.
 
1371
                to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
 
1372
                                            possible_transports=[to_transport],
 
1373
                                            accelerator_tree=accelerator_tree,
 
1374
                                            hardlink=hardlink, stacked=stacked,
 
1375
                                            force_new_repo=standalone,
 
1376
                                            create_tree_if_local=not no_tree,
 
1377
                                            source_branch=br_from)
 
1378
                branch = to_dir.open_branch(
 
1379
                    possible_transports=[
 
1380
                        br_from.bzrdir.root_transport, to_transport])
 
1381
            except errors.NoSuchRevision:
 
1382
                to_transport.delete_tree('.')
 
1383
                msg = gettext("The branch {0} has no revision {1}.").format(
 
1384
                    from_location, revision)
 
1385
                raise errors.BzrCommandError(msg)
 
1386
        else:
 
1387
            branch = br_from.sprout(to_dir, revision_id=revision_id)
1308
1388
        _merge_tags_if_possible(br_from, branch)
1309
1389
        # If the source branch is stacked, the new branch may
1310
1390
        # be stacked whether we asked for that explicitly or not.
1311
1391
        # We therefore need a try/except here and not just 'if stacked:'
1312
1392
        try:
1313
 
            note('Created new stacked branch referring to %s.' %
 
1393
            note(gettext('Created new stacked branch referring to %s.') %
1314
1394
                branch.get_stacked_on_url())
1315
1395
        except (errors.NotStacked, errors.UnstackableBranchFormat,
1316
1396
            errors.UnstackableRepositoryFormat), e:
1317
 
            note('Branched %d revision(s).' % branch.revno())
 
1397
            note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1318
1398
        if bind:
1319
1399
            # Bind to the parent
1320
1400
            parent_branch = Branch.open(from_location)
1321
1401
            branch.bind(parent_branch)
1322
 
            note('New branch bound to %s' % from_location)
 
1402
            note(gettext('New branch bound to %s') % from_location)
1323
1403
        if switch:
1324
1404
            # Switch to the new branch
1325
1405
            wt, _ = WorkingTree.open_containing('.')
1326
1406
            _mod_switch.switch(wt.bzrdir, branch)
1327
 
            note('Switched to branch: %s',
 
1407
            note(gettext('Switched to branch: %s'),
1328
1408
                urlutils.unescape_for_display(branch.base, 'utf-8'))
1329
1409
 
1330
1410
 
 
1411
class cmd_branches(Command):
 
1412
    __doc__ = """List the branches available at the current location.
 
1413
 
 
1414
    This command will print the names of all the branches at the current
 
1415
    location.
 
1416
    """
 
1417
 
 
1418
    takes_args = ['location?']
 
1419
    takes_options = [
 
1420
                  Option('recursive', short_name='R',
 
1421
                         help='Recursively scan for branches rather than '
 
1422
                              'just looking in the specified location.')]
 
1423
 
 
1424
    def run(self, location=".", recursive=False):
 
1425
        if recursive:
 
1426
            t = transport.get_transport(location)
 
1427
            if not t.listable():
 
1428
                raise errors.BzrCommandError(
 
1429
                    "Can't scan this type of location.")
 
1430
            for b in controldir.ControlDir.find_branches(t):
 
1431
                self.outf.write("%s\n" % urlutils.unescape_for_display(
 
1432
                    urlutils.relative_url(t.base, b.base),
 
1433
                    self.outf.encoding).rstrip("/"))
 
1434
        else:
 
1435
            dir = controldir.ControlDir.open_containing(location)[0]
 
1436
            for branch in dir.list_branches():
 
1437
                if branch.name is None:
 
1438
                    self.outf.write(gettext(" (default)\n"))
 
1439
                else:
 
1440
                    self.outf.write(" %s\n" % branch.name.encode(
 
1441
                        self.outf.encoding))
 
1442
 
 
1443
 
1331
1444
class cmd_checkout(Command):
1332
1445
    __doc__ = """Create a new checkout of an existing branch.
1333
1446
 
1372
1485
        if branch_location is None:
1373
1486
            branch_location = osutils.getcwd()
1374
1487
            to_location = branch_location
1375
 
        accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
 
1488
        accelerator_tree, source = controldir.ControlDir.open_tree_or_branch(
1376
1489
            branch_location)
1377
1490
        if not (hardlink or files_from):
1378
1491
            # accelerator_tree is usually slower because you have to read N
1433
1546
 
1434
1547
 
1435
1548
class cmd_update(Command):
1436
 
    __doc__ = """Update a tree to have the latest code committed to its branch.
1437
 
 
1438
 
    This will perform a merge into the working tree, and may generate
1439
 
    conflicts. If you have any local changes, you will still
1440
 
    need to commit them after the update for the update to be complete.
1441
 
 
1442
 
    If you want to discard your local changes, you can just do a
1443
 
    'bzr revert' instead of 'bzr commit' after the update.
1444
 
 
1445
 
    If you want to restore a file that has been removed locally, use
1446
 
    'bzr revert' instead of 'bzr update'.
1447
 
 
1448
 
    If the tree's branch is bound to a master branch, it will also update
 
1549
    __doc__ = """Update a working tree to a new revision.
 
1550
 
 
1551
    This will perform a merge of the destination revision (the tip of the
 
1552
    branch, or the specified revision) into the working tree, and then make
 
1553
    that revision the basis revision for the working tree.  
 
1554
 
 
1555
    You can use this to visit an older revision, or to update a working tree
 
1556
    that is out of date from its branch.
 
1557
    
 
1558
    If there are any uncommitted changes in the tree, they will be carried
 
1559
    across and remain as uncommitted changes after the update.  To discard
 
1560
    these changes, use 'bzr revert'.  The uncommitted changes may conflict
 
1561
    with the changes brought in by the change in basis revision.
 
1562
 
 
1563
    If the tree's branch is bound to a master branch, bzr will also update
1449
1564
    the branch from the master.
 
1565
 
 
1566
    You cannot update just a single file or directory, because each Bazaar
 
1567
    working tree has just a single basis revision.  If you want to restore a
 
1568
    file that has been removed locally, use 'bzr revert' instead of 'bzr
 
1569
    update'.  If you want to restore a file to its state in a previous
 
1570
    revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
 
1571
    out the old content of that file to a new location.
 
1572
 
 
1573
    The 'dir' argument, if given, must be the location of the root of a
 
1574
    working tree to update.  By default, the working tree that contains the 
 
1575
    current working directory is used.
1450
1576
    """
1451
1577
 
1452
1578
    _see_also = ['pull', 'working-trees', 'status-flags']
1457
1583
                     ]
1458
1584
    aliases = ['up']
1459
1585
 
1460
 
    def run(self, dir='.', revision=None, show_base=None):
 
1586
    def run(self, dir=None, revision=None, show_base=None):
1461
1587
        if revision is not None and len(revision) != 1:
1462
 
            raise errors.BzrCommandError(
1463
 
                        "bzr update --revision takes exactly one revision")
1464
 
        tree = WorkingTree.open_containing(dir)[0]
 
1588
            raise errors.BzrCommandError(gettext(
 
1589
                "bzr update --revision takes exactly one revision"))
 
1590
        if dir is None:
 
1591
            tree = WorkingTree.open_containing('.')[0]
 
1592
        else:
 
1593
            tree, relpath = WorkingTree.open_containing(dir)
 
1594
            if relpath:
 
1595
                # See bug 557886.
 
1596
                raise errors.BzrCommandError(gettext(
 
1597
                    "bzr update can only update a whole tree, "
 
1598
                    "not a file or subdirectory"))
1465
1599
        branch = tree.branch
1466
1600
        possible_transports = []
1467
1601
        master = branch.get_master_branch(
1491
1625
            revision_id = branch.last_revision()
1492
1626
        if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1493
1627
            revno = branch.revision_id_to_dotted_revno(revision_id)
1494
 
            note("Tree is up to date at revision %s of branch %s" %
1495
 
                ('.'.join(map(str, revno)), branch_location))
 
1628
            note(gettext("Tree is up to date at revision {0} of branch {1}"
 
1629
                        ).format('.'.join(map(str, revno)), branch_location))
1496
1630
            return 0
1497
1631
        view_info = _get_view_info_for_change_reporter(tree)
1498
1632
        change_reporter = delta._ChangeReporter(
1506
1640
                old_tip=old_tip,
1507
1641
                show_base=show_base)
1508
1642
        except errors.NoSuchRevision, e:
1509
 
            raise errors.BzrCommandError(
 
1643
            raise errors.BzrCommandError(gettext(
1510
1644
                                  "branch has no revision %s\n"
1511
1645
                                  "bzr update --revision only works"
1512
 
                                  " for a revision in the branch history"
 
1646
                                  " for a revision in the branch history")
1513
1647
                                  % (e.revision))
1514
1648
        revno = tree.branch.revision_id_to_dotted_revno(
1515
1649
            _mod_revision.ensure_null(tree.last_revision()))
1516
 
        note('Updated to revision %s of branch %s' %
1517
 
             ('.'.join(map(str, revno)), branch_location))
 
1650
        note(gettext('Updated to revision {0} of branch {1}').format(
 
1651
             '.'.join(map(str, revno)), branch_location))
1518
1652
        parent_ids = tree.get_parent_ids()
1519
1653
        if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1520
 
            note('Your local commits will now show as pending merges with '
1521
 
                 "'bzr status', and can be committed with 'bzr commit'.")
 
1654
            note(gettext('Your local commits will now show as pending merges with '
 
1655
                 "'bzr status', and can be committed with 'bzr commit'."))
1522
1656
        if conflicts != 0:
1523
1657
            return 1
1524
1658
        else:
1565
1699
        else:
1566
1700
            noise_level = 0
1567
1701
        from bzrlib.info import show_bzrdir_info
1568
 
        show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
 
1702
        show_bzrdir_info(controldir.ControlDir.open_containing(location)[0],
1569
1703
                         verbose=noise_level, outfile=self.outf)
1570
1704
 
1571
1705
 
1596
1730
    def run(self, file_list, verbose=False, new=False,
1597
1731
        file_deletion_strategy='safe'):
1598
1732
        if file_deletion_strategy == 'force':
1599
 
            note("(The --force option is deprecated, rather use --no-backup "
1600
 
                "in future.)")
 
1733
            note(gettext("(The --force option is deprecated, rather use --no-backup "
 
1734
                "in future.)"))
1601
1735
            file_deletion_strategy = 'no-backup'
1602
1736
 
1603
1737
        tree, file_list = WorkingTree.open_containing_paths(file_list)
1613
1747
                specific_files=file_list).added
1614
1748
            file_list = sorted([f[0] for f in added], reverse=True)
1615
1749
            if len(file_list) == 0:
1616
 
                raise errors.BzrCommandError('No matching files.')
 
1750
                raise errors.BzrCommandError(gettext('No matching files.'))
1617
1751
        elif file_list is None:
1618
1752
            # missing files show up in iter_changes(basis) as
1619
1753
            # versioned-with-no-kind.
1703
1837
 
1704
1838
    def run(self, branch=".", canonicalize_chks=False):
1705
1839
        from bzrlib.reconcile import reconcile
1706
 
        dir = bzrdir.BzrDir.open(branch)
 
1840
        dir = controldir.ControlDir.open(branch)
1707
1841
        reconcile(dir, canonicalize_chks=canonicalize_chks)
1708
1842
 
1709
1843
 
1718
1852
    @display_command
1719
1853
    def run(self, location="."):
1720
1854
        branch = Branch.open_containing(location)[0]
1721
 
        for revid in branch.revision_history():
 
1855
        self.add_cleanup(branch.lock_read().unlock)
 
1856
        graph = branch.repository.get_graph()
 
1857
        history = list(graph.iter_lefthand_ancestry(branch.last_revision(),
 
1858
            [_mod_revision.NULL_REVISION]))
 
1859
        for revid in reversed(history):
1722
1860
            self.outf.write(revid)
1723
1861
            self.outf.write('\n')
1724
1862
 
1785
1923
                help='Specify a format for this branch. '
1786
1924
                'See "help formats".',
1787
1925
                lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1788
 
                converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
1926
                converter=lambda name: controldir.format_registry.make_bzrdir(name),
1789
1927
                value_switches=True,
1790
1928
                title="Branch format",
1791
1929
                ),
1798
1936
    def run(self, location=None, format=None, append_revisions_only=False,
1799
1937
            create_prefix=False, no_tree=False):
1800
1938
        if format is None:
1801
 
            format = bzrdir.format_registry.make_bzrdir('default')
 
1939
            format = controldir.format_registry.make_bzrdir('default')
1802
1940
        if location is None:
1803
1941
            location = u'.'
1804
1942
 
1813
1951
            to_transport.ensure_base()
1814
1952
        except errors.NoSuchFile:
1815
1953
            if not create_prefix:
1816
 
                raise errors.BzrCommandError("Parent directory of %s"
 
1954
                raise errors.BzrCommandError(gettext("Parent directory of %s"
1817
1955
                    " does not exist."
1818
1956
                    "\nYou may supply --create-prefix to create all"
1819
 
                    " leading parent directories."
 
1957
                    " leading parent directories.")
1820
1958
                    % location)
1821
1959
            to_transport.create_prefix()
1822
1960
 
1823
1961
        try:
1824
 
            a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
 
1962
            a_bzrdir = controldir.ControlDir.open_from_transport(to_transport)
1825
1963
        except errors.NotBranchError:
1826
1964
            # really a NotBzrDir error...
1827
 
            create_branch = bzrdir.BzrDir.create_branch_convenience
 
1965
            create_branch = controldir.ControlDir.create_branch_convenience
1828
1966
            if no_tree:
1829
1967
                force_new_tree = False
1830
1968
            else:
1841
1979
                        raise errors.BranchExistsWithoutWorkingTree(location)
1842
1980
                raise errors.AlreadyBranchError(location)
1843
1981
            branch = a_bzrdir.create_branch()
1844
 
            if not no_tree:
 
1982
            if not no_tree and not a_bzrdir.has_workingtree():
1845
1983
                a_bzrdir.create_workingtree()
1846
1984
        if append_revisions_only:
1847
1985
            try:
1848
1986
                branch.set_append_revisions_only(True)
1849
1987
            except errors.UpgradeRequired:
1850
 
                raise errors.BzrCommandError('This branch format cannot be set'
1851
 
                    ' to append-revisions-only.  Try --default.')
 
1988
                raise errors.BzrCommandError(gettext('This branch format cannot be set'
 
1989
                    ' to append-revisions-only.  Try --default.'))
1852
1990
        if not is_quiet():
1853
1991
            from bzrlib.info import describe_layout, describe_format
1854
1992
            try:
1858
1996
            repository = branch.repository
1859
1997
            layout = describe_layout(repository, branch, tree).lower()
1860
1998
            format = describe_format(a_bzrdir, repository, branch, tree)
1861
 
            self.outf.write("Created a %s (format: %s)\n" % (layout, format))
 
1999
            self.outf.write(gettext("Created a {0} (format: {1})\n").format(
 
2000
                  layout, format))
1862
2001
            if repository.is_shared():
1863
2002
                #XXX: maybe this can be refactored into transport.path_or_url()
1864
2003
                url = repository.bzrdir.root_transport.external_url()
1866
2005
                    url = urlutils.local_path_from_url(url)
1867
2006
                except errors.InvalidURL:
1868
2007
                    pass
1869
 
                self.outf.write("Using shared repository: %s\n" % url)
 
2008
                self.outf.write(gettext("Using shared repository: %s\n") % url)
1870
2009
 
1871
2010
 
1872
2011
class cmd_init_repository(Command):
1902
2041
    takes_options = [RegistryOption('format',
1903
2042
                            help='Specify a format for this repository. See'
1904
2043
                                 ' "bzr help formats" for details.',
1905
 
                            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1906
 
                            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
2044
                            lazy_registry=('bzrlib.controldir', 'format_registry'),
 
2045
                            converter=lambda name: controldir.format_registry.make_bzrdir(name),
1907
2046
                            value_switches=True, title='Repository format'),
1908
2047
                     Option('no-trees',
1909
2048
                             help='Branches in the repository will default to'
1913
2052
 
1914
2053
    def run(self, location, format=None, no_trees=False):
1915
2054
        if format is None:
1916
 
            format = bzrdir.format_registry.make_bzrdir('default')
 
2055
            format = controldir.format_registry.make_bzrdir('default')
1917
2056
 
1918
2057
        if location is None:
1919
2058
            location = '.'
2063
2202
        elif ':' in prefix:
2064
2203
            old_label, new_label = prefix.split(":")
2065
2204
        else:
2066
 
            raise errors.BzrCommandError(
 
2205
            raise errors.BzrCommandError(gettext(
2067
2206
                '--prefix expects two values separated by a colon'
2068
 
                ' (eg "old/:new/")')
 
2207
                ' (eg "old/:new/")'))
2069
2208
 
2070
2209
        if revision and len(revision) > 2:
2071
 
            raise errors.BzrCommandError('bzr diff --revision takes exactly'
2072
 
                                         ' one or two revision specifiers')
 
2210
            raise errors.BzrCommandError(gettext('bzr diff --revision takes exactly'
 
2211
                                         ' one or two revision specifiers'))
2073
2212
 
2074
2213
        if using is not None and format is not None:
2075
 
            raise errors.BzrCommandError('--using and --format are mutually '
2076
 
                'exclusive.')
 
2214
            raise errors.BzrCommandError(gettext(
 
2215
                '{0} and {1} are mutually exclusive').format(
 
2216
                '--using', '--format'))
2077
2217
 
2078
2218
        (old_tree, new_tree,
2079
2219
         old_branch, new_branch,
2187
2327
    try:
2188
2328
        return int(limitstring)
2189
2329
    except ValueError:
2190
 
        msg = "The limit argument must be an integer."
 
2330
        msg = gettext("The limit argument must be an integer.")
2191
2331
        raise errors.BzrCommandError(msg)
2192
2332
 
2193
2333
 
2195
2335
    try:
2196
2336
        return int(s)
2197
2337
    except ValueError:
2198
 
        msg = "The levels argument must be an integer."
 
2338
        msg = gettext("The levels argument must be an integer.")
2199
2339
        raise errors.BzrCommandError(msg)
2200
2340
 
2201
2341
 
2311
2451
 
2312
2452
    :Other filtering:
2313
2453
 
2314
 
      The --message option can be used for finding revisions that match a
2315
 
      regular expression in a commit message.
 
2454
      The --match option can be used for finding revisions that match a
 
2455
      regular expression in a commit message, committer, author or bug.
 
2456
      Specifying the option several times will match any of the supplied
 
2457
      expressions. --match-author, --match-bugs, --match-committer and
 
2458
      --match-message can be used to only match a specific field.
2316
2459
 
2317
2460
    :Tips & tricks:
2318
2461
 
2378
2521
                   argname='N',
2379
2522
                   type=_parse_levels),
2380
2523
            Option('message',
2381
 
                   short_name='m',
2382
2524
                   help='Show revisions whose message matches this '
2383
2525
                        'regular expression.',
2384
 
                   type=str),
 
2526
                   type=str,
 
2527
                   hidden=True),
2385
2528
            Option('limit',
2386
2529
                   short_name='l',
2387
2530
                   help='Limit the output to the first N revisions.',
2390
2533
            Option('show-diff',
2391
2534
                   short_name='p',
2392
2535
                   help='Show changes made in each revision as a patch.'),
2393
 
            Option('include-merges',
 
2536
            Option('include-merged',
2394
2537
                   help='Show merged revisions like --levels 0 does.'),
 
2538
            Option('include-merges', hidden=True,
 
2539
                   help='Historical alias for --include-merged.'),
 
2540
            Option('omit-merges',
 
2541
                   help='Do not report commits with more than one parent.'),
2395
2542
            Option('exclude-common-ancestry',
2396
2543
                   help='Display only the revisions that are not part'
2397
 
                   ' of both ancestries (require -rX..Y)'
 
2544
                   ' of both ancestries (require -rX..Y).'
2398
2545
                   ),
2399
2546
            Option('signatures',
2400
 
                   help='Show digital signature validity'),
 
2547
                   help='Show digital signature validity.'),
 
2548
            ListOption('match',
 
2549
                short_name='m',
 
2550
                help='Show revisions whose properties match this '
 
2551
                'expression.',
 
2552
                type=str),
 
2553
            ListOption('match-message',
 
2554
                   help='Show revisions whose message matches this '
 
2555
                   'expression.',
 
2556
                type=str),
 
2557
            ListOption('match-committer',
 
2558
                   help='Show revisions whose committer matches this '
 
2559
                   'expression.',
 
2560
                type=str),
 
2561
            ListOption('match-author',
 
2562
                   help='Show revisions whose authors match this '
 
2563
                   'expression.',
 
2564
                type=str),
 
2565
            ListOption('match-bugs',
 
2566
                   help='Show revisions whose bugs match this '
 
2567
                   'expression.',
 
2568
                type=str)
2401
2569
            ]
2402
2570
    encoding_type = 'replace'
2403
2571
 
2413
2581
            message=None,
2414
2582
            limit=None,
2415
2583
            show_diff=False,
2416
 
            include_merges=False,
 
2584
            include_merged=None,
2417
2585
            authors=None,
2418
2586
            exclude_common_ancestry=False,
2419
2587
            signatures=False,
 
2588
            match=None,
 
2589
            match_message=None,
 
2590
            match_committer=None,
 
2591
            match_author=None,
 
2592
            match_bugs=None,
 
2593
            omit_merges=False,
 
2594
            include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2420
2595
            ):
2421
2596
        from bzrlib.log import (
2422
2597
            Logger,
2424
2599
            _get_info_for_log_files,
2425
2600
            )
2426
2601
        direction = (forward and 'forward') or 'reverse'
 
2602
        if symbol_versioning.deprecated_passed(include_merges):
 
2603
            ui.ui_factory.show_user_warning(
 
2604
                'deprecated_command_option',
 
2605
                deprecated_name='--include-merges',
 
2606
                recommended_name='--include-merged',
 
2607
                deprecated_in_version='2.5',
 
2608
                command=self.invoked_as)
 
2609
            if include_merged is None:
 
2610
                include_merged = include_merges
 
2611
            else:
 
2612
                raise errors.BzrCommandError(gettext(
 
2613
                    '{0} and {1} are mutually exclusive').format(
 
2614
                    '--include-merges', '--include-merged'))
 
2615
        if include_merged is None:
 
2616
            include_merged = False
2427
2617
        if (exclude_common_ancestry
2428
2618
            and (revision is None or len(revision) != 2)):
2429
 
            raise errors.BzrCommandError(
2430
 
                '--exclude-common-ancestry requires -r with two revisions')
2431
 
        if include_merges:
 
2619
            raise errors.BzrCommandError(gettext(
 
2620
                '--exclude-common-ancestry requires -r with two revisions'))
 
2621
        if include_merged:
2432
2622
            if levels is None:
2433
2623
                levels = 0
2434
2624
            else:
2435
 
                raise errors.BzrCommandError(
2436
 
                    '--levels and --include-merges are mutually exclusive')
 
2625
                raise errors.BzrCommandError(gettext(
 
2626
                    '{0} and {1} are mutually exclusive').format(
 
2627
                    '--levels', '--include-merged'))
2437
2628
 
2438
2629
        if change is not None:
2439
2630
            if len(change) > 1:
2440
2631
                raise errors.RangeInChangeOption()
2441
2632
            if revision is not None:
2442
 
                raise errors.BzrCommandError(
2443
 
                    '--revision and --change are mutually exclusive')
 
2633
                raise errors.BzrCommandError(gettext(
 
2634
                    '{0} and {1} are mutually exclusive').format(
 
2635
                    '--revision', '--change'))
2444
2636
            else:
2445
2637
                revision = change
2446
2638
 
2452
2644
                revision, file_list, self.add_cleanup)
2453
2645
            for relpath, file_id, kind in file_info_list:
2454
2646
                if file_id is None:
2455
 
                    raise errors.BzrCommandError(
2456
 
                        "Path unknown at end or start of revision range: %s" %
 
2647
                    raise errors.BzrCommandError(gettext(
 
2648
                        "Path unknown at end or start of revision range: %s") %
2457
2649
                        relpath)
2458
2650
                # If the relpath is the top of the tree, we log everything
2459
2651
                if relpath == '':
2471
2663
                location = revision[0].get_branch()
2472
2664
            else:
2473
2665
                location = '.'
2474
 
            dir, relpath = bzrdir.BzrDir.open_containing(location)
 
2666
            dir, relpath = controldir.ControlDir.open_containing(location)
2475
2667
            b = dir.open_branch()
2476
2668
            self.add_cleanup(b.lock_read().unlock)
2477
2669
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2525
2717
        match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2526
2718
            or delta_type or partial_history)
2527
2719
 
 
2720
        match_dict = {}
 
2721
        if match:
 
2722
            match_dict[''] = match
 
2723
        if match_message:
 
2724
            match_dict['message'] = match_message
 
2725
        if match_committer:
 
2726
            match_dict['committer'] = match_committer
 
2727
        if match_author:
 
2728
            match_dict['author'] = match_author
 
2729
        if match_bugs:
 
2730
            match_dict['bugs'] = match_bugs
 
2731
 
2528
2732
        # Build the LogRequest and execute it
2529
2733
        if len(file_ids) == 0:
2530
2734
            file_ids = None
2533
2737
            start_revision=rev1, end_revision=rev2, limit=limit,
2534
2738
            message_search=message, delta_type=delta_type,
2535
2739
            diff_type=diff_type, _match_using_deltas=match_using_deltas,
2536
 
            exclude_common_ancestry=exclude_common_ancestry,
2537
 
            signature=signatures
 
2740
            exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
 
2741
            signature=signatures, omit_merges=omit_merges,
2538
2742
            )
2539
2743
        Logger(b, rqst).show(lf)
2540
2744
 
2557
2761
            # b is taken from revision[0].get_branch(), and
2558
2762
            # show_log will use its revision_history. Having
2559
2763
            # different branches will lead to weird behaviors.
2560
 
            raise errors.BzrCommandError(
 
2764
            raise errors.BzrCommandError(gettext(
2561
2765
                "bzr %s doesn't accept two revisions in different"
2562
 
                " branches." % command_name)
 
2766
                " branches.") % command_name)
2563
2767
        if start_spec.spec is None:
2564
2768
            # Avoid loading all the history.
2565
2769
            rev1 = RevisionInfo(branch, None, None)
2573
2777
        else:
2574
2778
            rev2 = end_spec.in_history(branch)
2575
2779
    else:
2576
 
        raise errors.BzrCommandError(
2577
 
            'bzr %s --revision takes one or two values.' % command_name)
 
2780
        raise errors.BzrCommandError(gettext(
 
2781
            'bzr %s --revision takes one or two values.') % command_name)
2578
2782
    return rev1, rev2
2579
2783
 
2580
2784
 
2651
2855
            null=False, kind=None, show_ids=False, path=None, directory=None):
2652
2856
 
2653
2857
        if kind and kind not in ('file', 'directory', 'symlink'):
2654
 
            raise errors.BzrCommandError('invalid kind specified')
 
2858
            raise errors.BzrCommandError(gettext('invalid kind specified'))
2655
2859
 
2656
2860
        if verbose and null:
2657
 
            raise errors.BzrCommandError('Cannot set both --verbose and --null')
 
2861
            raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
2658
2862
        all = not (unknown or versioned or ignored)
2659
2863
 
2660
2864
        selection = {'I':ignored, '?':unknown, 'V':versioned}
2663
2867
            fs_path = '.'
2664
2868
        else:
2665
2869
            if from_root:
2666
 
                raise errors.BzrCommandError('cannot specify both --from-root'
2667
 
                                             ' and PATH')
 
2870
                raise errors.BzrCommandError(gettext('cannot specify both --from-root'
 
2871
                                             ' and PATH'))
2668
2872
            fs_path = path
2669
2873
        tree, branch, relpath = \
2670
2874
            _open_directory_or_containing_tree_or_branch(fs_path, directory)
2686
2890
            if view_files:
2687
2891
                apply_view = True
2688
2892
                view_str = views.view_display_str(view_files)
2689
 
                note("Ignoring files outside view. View is %s" % view_str)
 
2893
                note(gettext("Ignoring files outside view. View is %s") % view_str)
2690
2894
 
2691
2895
        self.add_cleanup(tree.lock_read().unlock)
2692
2896
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2839
3043
                self.outf.write("%s\n" % pattern)
2840
3044
            return
2841
3045
        if not name_pattern_list:
2842
 
            raise errors.BzrCommandError("ignore requires at least one "
2843
 
                "NAME_PATTERN or --default-rules.")
 
3046
            raise errors.BzrCommandError(gettext("ignore requires at least one "
 
3047
                "NAME_PATTERN or --default-rules."))
2844
3048
        name_pattern_list = [globbing.normalize_pattern(p)
2845
3049
                             for p in name_pattern_list]
2846
3050
        bad_patterns = ''
 
3051
        bad_patterns_count = 0
2847
3052
        for p in name_pattern_list:
2848
3053
            if not globbing.Globster.is_pattern_valid(p):
 
3054
                bad_patterns_count += 1
2849
3055
                bad_patterns += ('\n  %s' % p)
2850
3056
        if bad_patterns:
2851
 
            msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
 
3057
            msg = (ngettext('Invalid ignore pattern found. %s', 
 
3058
                            'Invalid ignore patterns found. %s',
 
3059
                            bad_patterns_count) % bad_patterns)
2852
3060
            ui.ui_factory.show_error(msg)
2853
3061
            raise errors.InvalidPattern('')
2854
3062
        for name_pattern in name_pattern_list:
2855
3063
            if (name_pattern[0] == '/' or
2856
3064
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
2857
 
                raise errors.BzrCommandError(
2858
 
                    "NAME_PATTERN should not be an absolute path")
 
3065
                raise errors.BzrCommandError(gettext(
 
3066
                    "NAME_PATTERN should not be an absolute path"))
2859
3067
        tree, relpath = WorkingTree.open_containing(directory)
2860
3068
        ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2861
3069
        ignored = globbing.Globster(name_pattern_list)
2868
3076
                if ignored.match(filename):
2869
3077
                    matches.append(filename)
2870
3078
        if len(matches) > 0:
2871
 
            self.outf.write("Warning: the following files are version controlled and"
2872
 
                  " match your ignore pattern:\n%s"
 
3079
            self.outf.write(gettext("Warning: the following files are version "
 
3080
                  "controlled and match your ignore pattern:\n%s"
2873
3081
                  "\nThese files will continue to be version controlled"
2874
 
                  " unless you 'bzr remove' them.\n" % ("\n".join(matches),))
 
3082
                  " unless you 'bzr remove' them.\n") % ("\n".join(matches),))
2875
3083
 
2876
3084
 
2877
3085
class cmd_ignored(Command):
2916
3124
        try:
2917
3125
            revno = int(revno)
2918
3126
        except ValueError:
2919
 
            raise errors.BzrCommandError("not a valid revision-number: %r"
 
3127
            raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
2920
3128
                                         % revno)
2921
3129
        revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2922
3130
        self.outf.write("%s\n" % revid)
2965
3173
        Option('per-file-timestamps',
2966
3174
               help='Set modification time of files to that of the last '
2967
3175
                    'revision in which it was changed.'),
 
3176
        Option('uncommitted',
 
3177
               help='Export the working tree contents rather than that of the '
 
3178
                    'last revision.'),
2968
3179
        ]
2969
3180
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2970
 
        root=None, filters=False, per_file_timestamps=False, directory=u'.'):
 
3181
        root=None, filters=False, per_file_timestamps=False, uncommitted=False,
 
3182
        directory=u'.'):
2971
3183
        from bzrlib.export import export
2972
3184
 
2973
3185
        if branch_or_subdir is None:
2974
 
            tree = WorkingTree.open_containing(directory)[0]
2975
 
            b = tree.branch
2976
 
            subdir = None
 
3186
            branch_or_subdir = directory
 
3187
 
 
3188
        (tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
 
3189
            branch_or_subdir)
 
3190
        if tree is not None:
 
3191
            self.add_cleanup(tree.lock_read().unlock)
 
3192
 
 
3193
        if uncommitted:
 
3194
            if tree is None:
 
3195
                raise errors.BzrCommandError(
 
3196
                    gettext("--uncommitted requires a working tree"))
 
3197
            export_tree = tree
2977
3198
        else:
2978
 
            b, subdir = Branch.open_containing(branch_or_subdir)
2979
 
            tree = None
2980
 
 
2981
 
        rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
 
3199
            export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2982
3200
        try:
2983
 
            export(rev_tree, dest, format, root, subdir, filtered=filters,
 
3201
            export(export_tree, dest, format, root, subdir, filtered=filters,
2984
3202
                   per_file_timestamps=per_file_timestamps)
2985
3203
        except errors.NoSuchExportFormat, e:
2986
 
            raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
 
3204
            raise errors.BzrCommandError(
 
3205
                gettext('Unsupported export format: %s') % e.format)
2987
3206
 
2988
3207
 
2989
3208
class cmd_cat(Command):
3009
3228
    def run(self, filename, revision=None, name_from_revision=False,
3010
3229
            filters=False, directory=None):
3011
3230
        if revision is not None and len(revision) != 1:
3012
 
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
3013
 
                                         " one revision specifier")
 
3231
            raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
 
3232
                                         " one revision specifier"))
3014
3233
        tree, branch, relpath = \
3015
3234
            _open_directory_or_containing_tree_or_branch(filename, directory)
3016
3235
        self.add_cleanup(branch.lock_read().unlock)
3026
3245
 
3027
3246
        old_file_id = rev_tree.path2id(relpath)
3028
3247
 
 
3248
        # TODO: Split out this code to something that generically finds the
 
3249
        # best id for a path across one or more trees; it's like
 
3250
        # find_ids_across_trees but restricted to find just one. -- mbp
 
3251
        # 20110705.
3029
3252
        if name_from_revision:
3030
3253
            # Try in revision if requested
3031
3254
            if old_file_id is None:
3032
 
                raise errors.BzrCommandError(
3033
 
                    "%r is not present in revision %s" % (
 
3255
                raise errors.BzrCommandError(gettext(
 
3256
                    "{0!r} is not present in revision {1}").format(
3034
3257
                        filename, rev_tree.get_revision_id()))
3035
3258
            else:
3036
 
                content = rev_tree.get_file_text(old_file_id)
 
3259
                actual_file_id = old_file_id
3037
3260
        else:
3038
3261
            cur_file_id = tree.path2id(relpath)
3039
 
            found = False
3040
 
            if cur_file_id is not None:
3041
 
                # Then try with the actual file id
3042
 
                try:
3043
 
                    content = rev_tree.get_file_text(cur_file_id)
3044
 
                    found = True
3045
 
                except errors.NoSuchId:
3046
 
                    # The actual file id didn't exist at that time
3047
 
                    pass
3048
 
            if not found and old_file_id is not None:
3049
 
                # Finally try with the old file id
3050
 
                content = rev_tree.get_file_text(old_file_id)
3051
 
                found = True
3052
 
            if not found:
3053
 
                # Can't be found anywhere
3054
 
                raise errors.BzrCommandError(
3055
 
                    "%r is not present in revision %s" % (
 
3262
            if cur_file_id is not None and rev_tree.has_id(cur_file_id):
 
3263
                actual_file_id = cur_file_id
 
3264
            elif old_file_id is not None:
 
3265
                actual_file_id = old_file_id
 
3266
            else:
 
3267
                raise errors.BzrCommandError(gettext(
 
3268
                    "{0!r} is not present in revision {1}").format(
3056
3269
                        filename, rev_tree.get_revision_id()))
3057
3270
        if filtered:
3058
 
            from bzrlib.filters import (
3059
 
                ContentFilterContext,
3060
 
                filtered_output_bytes,
3061
 
                )
3062
 
            filters = rev_tree._content_filter_stack(relpath)
3063
 
            chunks = content.splitlines(True)
3064
 
            content = filtered_output_bytes(chunks, filters,
3065
 
                ContentFilterContext(relpath, rev_tree))
3066
 
            self.cleanup_now()
3067
 
            self.outf.writelines(content)
 
3271
            from bzrlib.filter_tree import ContentFilterTree
 
3272
            filter_tree = ContentFilterTree(rev_tree,
 
3273
                rev_tree._content_filter_stack)
 
3274
            content = filter_tree.get_file_text(actual_file_id)
3068
3275
        else:
3069
 
            self.cleanup_now()
3070
 
            self.outf.write(content)
 
3276
            content = rev_tree.get_file_text(actual_file_id)
 
3277
        self.cleanup_now()
 
3278
        self.outf.write(content)
3071
3279
 
3072
3280
 
3073
3281
class cmd_local_time_offset(Command):
3180
3388
    aliases = ['ci', 'checkin']
3181
3389
 
3182
3390
    def _iter_bug_fix_urls(self, fixes, branch):
 
3391
        default_bugtracker  = None
3183
3392
        # Configure the properties for bug fixing attributes.
3184
3393
        for fixed_bug in fixes:
3185
3394
            tokens = fixed_bug.split(':')
3186
 
            if len(tokens) != 2:
3187
 
                raise errors.BzrCommandError(
 
3395
            if len(tokens) == 1:
 
3396
                if default_bugtracker is None:
 
3397
                    branch_config = branch.get_config()
 
3398
                    default_bugtracker = branch_config.get_user_option(
 
3399
                        "bugtracker")
 
3400
                if default_bugtracker is None:
 
3401
                    raise errors.BzrCommandError(gettext(
 
3402
                        "No tracker specified for bug %s. Use the form "
 
3403
                        "'tracker:id' or specify a default bug tracker "
 
3404
                        "using the `bugtracker` option.\nSee "
 
3405
                        "\"bzr help bugs\" for more information on this "
 
3406
                        "feature. Commit refused.") % fixed_bug)
 
3407
                tag = default_bugtracker
 
3408
                bug_id = tokens[0]
 
3409
            elif len(tokens) != 2:
 
3410
                raise errors.BzrCommandError(gettext(
3188
3411
                    "Invalid bug %s. Must be in the form of 'tracker:id'. "
3189
3412
                    "See \"bzr help bugs\" for more information on this "
3190
 
                    "feature.\nCommit refused." % fixed_bug)
3191
 
            tag, bug_id = tokens
 
3413
                    "feature.\nCommit refused.") % fixed_bug)
 
3414
            else:
 
3415
                tag, bug_id = tokens
3192
3416
            try:
3193
3417
                yield bugtracker.get_bug_url(tag, branch, bug_id)
3194
3418
            except errors.UnknownBugTrackerAbbreviation:
3195
 
                raise errors.BzrCommandError(
3196
 
                    'Unrecognized bug %s. Commit refused.' % fixed_bug)
 
3419
                raise errors.BzrCommandError(gettext(
 
3420
                    'Unrecognized bug %s. Commit refused.') % fixed_bug)
3197
3421
            except errors.MalformedBugIdentifier, e:
3198
 
                raise errors.BzrCommandError(
3199
 
                    "%s\nCommit refused." % (str(e),))
 
3422
                raise errors.BzrCommandError(gettext(
 
3423
                    "%s\nCommit refused.") % (str(e),))
3200
3424
 
3201
3425
    def run(self, message=None, file=None, verbose=False, selected_list=None,
3202
3426
            unchanged=False, strict=False, local=False, fixes=None,
3219
3443
            try:
3220
3444
                commit_stamp, offset = timestamp.parse_patch_date(commit_time)
3221
3445
            except ValueError, e:
3222
 
                raise errors.BzrCommandError(
3223
 
                    "Could not parse --commit-time: " + str(e))
 
3446
                raise errors.BzrCommandError(gettext(
 
3447
                    "Could not parse --commit-time: " + str(e)))
3224
3448
 
3225
3449
        properties = {}
3226
3450
 
3259
3483
                message = message.replace('\r\n', '\n')
3260
3484
                message = message.replace('\r', '\n')
3261
3485
            if file:
3262
 
                raise errors.BzrCommandError(
3263
 
                    "please specify either --message or --file")
 
3486
                raise errors.BzrCommandError(gettext(
 
3487
                    "please specify either --message or --file"))
3264
3488
 
3265
3489
        def get_message(commit_obj):
3266
3490
            """Callback to get commit message"""
3289
3513
                    my_message = edit_commit_message_encoded(text,
3290
3514
                        start_message=start_message)
3291
3515
                if my_message is None:
3292
 
                    raise errors.BzrCommandError("please specify a commit"
3293
 
                        " message with either --message or --file")
3294
 
            if my_message == "":
3295
 
                raise errors.BzrCommandError("empty commit message specified")
 
3516
                    raise errors.BzrCommandError(gettext("please specify a commit"
 
3517
                        " message with either --message or --file"))
 
3518
                if my_message == "":
 
3519
                    raise errors.BzrCommandError(gettext("Empty commit message specified."
 
3520
                            " Please specify a commit message with either"
 
3521
                            " --message or --file or leave a blank message"
 
3522
                            " with --message \"\"."))
3296
3523
            return my_message
3297
3524
 
3298
3525
        # The API permits a commit with a filter of [] to mean 'select nothing'
3309
3536
                        exclude=tree.safe_relpath_files(exclude),
3310
3537
                        lossy=lossy)
3311
3538
        except PointlessCommit:
3312
 
            raise errors.BzrCommandError("No changes to commit."
 
3539
            raise errors.BzrCommandError(gettext("No changes to commit."
3313
3540
                " Please 'bzr add' the files you want to commit, or use"
3314
 
                " --unchanged to force an empty commit.")
 
3541
                " --unchanged to force an empty commit."))
3315
3542
        except ConflictsInTree:
3316
 
            raise errors.BzrCommandError('Conflicts detected in working '
 
3543
            raise errors.BzrCommandError(gettext('Conflicts detected in working '
3317
3544
                'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
3318
 
                ' resolve.')
 
3545
                ' resolve.'))
3319
3546
        except StrictCommitFailed:
3320
 
            raise errors.BzrCommandError("Commit refused because there are"
3321
 
                              " unknown files in the working tree.")
 
3547
            raise errors.BzrCommandError(gettext("Commit refused because there are"
 
3548
                              " unknown files in the working tree."))
3322
3549
        except errors.BoundBranchOutOfDate, e:
3323
 
            e.extra_help = ("\n"
 
3550
            e.extra_help = (gettext("\n"
3324
3551
                'To commit to master branch, run update and then commit.\n'
3325
3552
                'You can also pass --local to commit to continue working '
3326
 
                'disconnected.')
 
3553
                'disconnected.'))
3327
3554
            raise
3328
3555
 
3329
3556
 
3436
3663
        RegistryOption('format',
3437
3664
            help='Upgrade to a specific format.  See "bzr help'
3438
3665
                 ' formats" for details.',
3439
 
            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3440
 
            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
3666
            lazy_registry=('bzrlib.controldir', 'format_registry'),
 
3667
            converter=lambda name: controldir.format_registry.make_bzrdir(name),
3441
3668
            value_switches=True, title='Branch format'),
3442
3669
        Option('clean',
3443
3670
            help='Remove the backup.bzr directory if successful.'),
3484
3711
            if directory is None:
3485
3712
                # use branch if we're inside one; otherwise global config
3486
3713
                try:
3487
 
                    c = Branch.open_containing(u'.')[0].get_config()
 
3714
                    c = Branch.open_containing(u'.')[0].get_config_stack()
3488
3715
                except errors.NotBranchError:
3489
 
                    c = _mod_config.GlobalConfig()
 
3716
                    c = _mod_config.GlobalStack()
3490
3717
            else:
3491
 
                c = Branch.open(directory).get_config()
 
3718
                c = Branch.open(directory).get_config_stack()
 
3719
            identity = c.get('email')
3492
3720
            if email:
3493
 
                self.outf.write(c.user_email() + '\n')
 
3721
                self.outf.write(_mod_config.extract_email_address(identity)
 
3722
                                + '\n')
3494
3723
            else:
3495
 
                self.outf.write(c.username() + '\n')
 
3724
                self.outf.write(identity + '\n')
3496
3725
            return
3497
3726
 
3498
3727
        if email:
3499
 
            raise errors.BzrCommandError("--email can only be used to display existing "
3500
 
                                         "identity")
 
3728
            raise errors.BzrCommandError(gettext("--email can only be used to display existing "
 
3729
                                         "identity"))
3501
3730
 
3502
3731
        # display a warning if an email address isn't included in the given name.
3503
3732
        try:
3509
3738
        # use global config unless --branch given
3510
3739
        if branch:
3511
3740
            if directory is None:
3512
 
                c = Branch.open_containing(u'.')[0].get_config()
 
3741
                c = Branch.open_containing(u'.')[0].get_config_stack()
3513
3742
            else:
3514
 
                c = Branch.open(directory).get_config()
 
3743
                c = Branch.open(directory).get_config_stack()
3515
3744
        else:
3516
 
            c = _mod_config.GlobalConfig()
3517
 
        c.set_user_option('email', name)
 
3745
            c = _mod_config.GlobalStack()
 
3746
        c.set('email', name)
3518
3747
 
3519
3748
 
3520
3749
class cmd_nick(Command):
3582
3811
 
3583
3812
    def remove_alias(self, alias_name):
3584
3813
        if alias_name is None:
3585
 
            raise errors.BzrCommandError(
3586
 
                'bzr alias --remove expects an alias to remove.')
 
3814
            raise errors.BzrCommandError(gettext(
 
3815
                'bzr alias --remove expects an alias to remove.'))
3587
3816
        # If alias is not found, print something like:
3588
3817
        # unalias: foo: not found
3589
3818
        c = _mod_config.GlobalConfig()
3727
3956
                                param_name='starting_with', short_name='s',
3728
3957
                                help=
3729
3958
                                'Load only the tests starting with TESTID.'),
 
3959
                     Option('sync',
 
3960
                            help="By default we disable fsync and fdatasync"
 
3961
                                 " while running the test suite.")
3730
3962
                     ]
3731
3963
    encoding_type = 'replace'
3732
3964
 
3740
3972
            first=False, list_only=False,
3741
3973
            randomize=None, exclude=None, strict=False,
3742
3974
            load_list=None, debugflag=None, starting_with=None, subunit=False,
3743
 
            parallel=None, lsprof_tests=False):
 
3975
            parallel=None, lsprof_tests=False,
 
3976
            sync=False):
3744
3977
        from bzrlib import tests
3745
3978
 
3746
3979
        if testspecs_list is not None:
3751
3984
            try:
3752
3985
                from bzrlib.tests import SubUnitBzrRunner
3753
3986
            except ImportError:
3754
 
                raise errors.BzrCommandError("subunit not available. subunit "
3755
 
                    "needs to be installed to use --subunit.")
 
3987
                raise errors.BzrCommandError(gettext("subunit not available. subunit "
 
3988
                    "needs to be installed to use --subunit."))
3756
3989
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3757
3990
            # On Windows, disable automatic conversion of '\n' to '\r\n' in
3758
3991
            # stdout, which would corrupt the subunit stream. 
3767
4000
            self.additional_selftest_args.setdefault(
3768
4001
                'suite_decorators', []).append(parallel)
3769
4002
        if benchmark:
3770
 
            raise errors.BzrCommandError(
 
4003
            raise errors.BzrCommandError(gettext(
3771
4004
                "--benchmark is no longer supported from bzr 2.2; "
3772
 
                "use bzr-usertest instead")
 
4005
                "use bzr-usertest instead"))
3773
4006
        test_suite_factory = None
3774
4007
        if not exclude:
3775
4008
            exclude_pattern = None
3776
4009
        else:
3777
4010
            exclude_pattern = '(' + '|'.join(exclude) + ')'
 
4011
        if not sync:
 
4012
            self._disable_fsync()
3778
4013
        selftest_kwargs = {"verbose": verbose,
3779
4014
                          "pattern": pattern,
3780
4015
                          "stop_on_failure": one,
3802
4037
            cleanup()
3803
4038
        return int(not result)
3804
4039
 
 
4040
    def _disable_fsync(self):
 
4041
        """Change the 'os' functionality to not synchronize."""
 
4042
        self._orig_fsync = getattr(os, 'fsync', None)
 
4043
        if self._orig_fsync is not None:
 
4044
            os.fsync = lambda filedes: None
 
4045
        self._orig_fdatasync = getattr(os, 'fdatasync', None)
 
4046
        if self._orig_fdatasync is not None:
 
4047
            os.fdatasync = lambda filedes: None
 
4048
 
3805
4049
 
3806
4050
class cmd_version(Command):
3807
4051
    __doc__ = """Show version of bzr."""
3827
4071
 
3828
4072
    @display_command
3829
4073
    def run(self):
3830
 
        self.outf.write("It sure does!\n")
 
4074
        self.outf.write(gettext("It sure does!\n"))
3831
4075
 
3832
4076
 
3833
4077
class cmd_find_merge_base(Command):
3851
4095
        graph = branch1.repository.get_graph(branch2.repository)
3852
4096
        base_rev_id = graph.find_unique_lca(last1, last2)
3853
4097
 
3854
 
        self.outf.write('merge base is revision %s\n' % base_rev_id)
 
4098
        self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
3855
4099
 
3856
4100
 
3857
4101
class cmd_merge(Command):
3890
4134
    Use bzr resolve when you have fixed a problem.  See also bzr conflicts.
3891
4135
 
3892
4136
    If there is no default branch set, the first merge will set it (use
3893
 
    --no-remember to avoid settting it). After that, you can omit the branch
 
4137
    --no-remember to avoid setting it). After that, you can omit the branch
3894
4138
    to use the default.  To change the default, use --remember. The value will
3895
4139
    only be saved if the remote location can be accessed.
3896
4140
 
3982
4226
 
3983
4227
        tree = WorkingTree.open_containing(directory)[0]
3984
4228
        if tree.branch.revno() == 0:
3985
 
            raise errors.BzrCommandError('Merging into empty branches not currently supported, '
3986
 
                                         'https://bugs.launchpad.net/bzr/+bug/308562')
 
4229
            raise errors.BzrCommandError(gettext('Merging into empty branches not currently supported, '
 
4230
                                         'https://bugs.launchpad.net/bzr/+bug/308562'))
3987
4231
 
3988
4232
        try:
3989
4233
            basis_tree = tree.revision_tree(tree.last_revision())
4009
4253
                mergeable = None
4010
4254
            else:
4011
4255
                if uncommitted:
4012
 
                    raise errors.BzrCommandError('Cannot use --uncommitted'
4013
 
                        ' with bundles or merge directives.')
 
4256
                    raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
 
4257
                        ' with bundles or merge directives.'))
4014
4258
 
4015
4259
                if revision is not None:
4016
 
                    raise errors.BzrCommandError(
4017
 
                        'Cannot use -r with merge directives or bundles')
 
4260
                    raise errors.BzrCommandError(gettext(
 
4261
                        'Cannot use -r with merge directives or bundles'))
4018
4262
                merger, verified = _mod_merge.Merger.from_mergeable(tree,
4019
4263
                   mergeable, None)
4020
4264
 
4021
4265
        if merger is None and uncommitted:
4022
4266
            if revision is not None and len(revision) > 0:
4023
 
                raise errors.BzrCommandError('Cannot use --uncommitted and'
4024
 
                    ' --revision at the same time.')
 
4267
                raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
 
4268
                    ' --revision at the same time.'))
4025
4269
            merger = self.get_merger_from_uncommitted(tree, location, None)
4026
4270
            allow_pending = False
4027
4271
 
4040
4284
            if merger.interesting_files:
4041
4285
                if not merger.other_tree.has_filename(
4042
4286
                    merger.interesting_files[0]):
4043
 
                    note("merger: " + str(merger))
 
4287
                    note(gettext("merger: ") + str(merger))
4044
4288
                    raise errors.PathsDoNotExist([location])
4045
 
            note('Nothing to do.')
 
4289
            note(gettext('Nothing to do.'))
4046
4290
            return 0
4047
4291
        if pull and not preview:
4048
4292
            if merger.interesting_files is not None:
4049
 
                raise errors.BzrCommandError('Cannot pull individual files')
 
4293
                raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4050
4294
            if (merger.base_rev_id == tree.last_revision()):
4051
4295
                result = tree.pull(merger.other_branch, False,
4052
4296
                                   merger.other_rev_id)
4053
4297
                result.report(self.outf)
4054
4298
                return 0
4055
4299
        if merger.this_basis is None:
4056
 
            raise errors.BzrCommandError(
 
4300
            raise errors.BzrCommandError(gettext(
4057
4301
                "This branch has no commits."
4058
 
                " (perhaps you would prefer 'bzr pull')")
 
4302
                " (perhaps you would prefer 'bzr pull')"))
4059
4303
        if preview:
4060
4304
            return self._do_preview(merger)
4061
4305
        elif interactive:
4112
4356
    def sanity_check_merger(self, merger):
4113
4357
        if (merger.show_base and
4114
4358
            not merger.merge_type is _mod_merge.Merge3Merger):
4115
 
            raise errors.BzrCommandError("Show-base is not supported for this"
4116
 
                                         " merge type. %s" % merger.merge_type)
 
4359
            raise errors.BzrCommandError(gettext("Show-base is not supported for this"
 
4360
                                         " merge type. %s") % merger.merge_type)
4117
4361
        if merger.reprocess is None:
4118
4362
            if merger.show_base:
4119
4363
                merger.reprocess = False
4121
4365
                # Use reprocess if the merger supports it
4122
4366
                merger.reprocess = merger.merge_type.supports_reprocess
4123
4367
        if merger.reprocess and not merger.merge_type.supports_reprocess:
4124
 
            raise errors.BzrCommandError("Conflict reduction is not supported"
4125
 
                                         " for merge type %s." %
 
4368
            raise errors.BzrCommandError(gettext("Conflict reduction is not supported"
 
4369
                                         " for merge type %s.") %
4126
4370
                                         merger.merge_type)
4127
4371
        if merger.reprocess and merger.show_base:
4128
 
            raise errors.BzrCommandError("Cannot do conflict reduction and"
4129
 
                                         " show base.")
 
4372
            raise errors.BzrCommandError(gettext("Cannot do conflict reduction and"
 
4373
                                         " show base."))
4130
4374
 
4131
4375
    def _get_merger_from_branch(self, tree, location, revision, remember,
4132
4376
                                possible_transports, pb):
4236
4480
            stored_location_type = "parent"
4237
4481
        mutter("%s", stored_location)
4238
4482
        if stored_location is None:
4239
 
            raise errors.BzrCommandError("No location specified or remembered")
 
4483
            raise errors.BzrCommandError(gettext("No location specified or remembered"))
4240
4484
        display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4241
 
        note(u"%s remembered %s location %s", verb_string,
4242
 
                stored_location_type, display_url)
 
4485
        note(gettext("{0} remembered {1} location {2}").format(verb_string,
 
4486
                stored_location_type, display_url))
4243
4487
        return stored_location
4244
4488
 
4245
4489
 
4282
4526
        self.add_cleanup(tree.lock_write().unlock)
4283
4527
        parents = tree.get_parent_ids()
4284
4528
        if len(parents) != 2:
4285
 
            raise errors.BzrCommandError("Sorry, remerge only works after normal"
 
4529
            raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4286
4530
                                         " merges.  Not cherrypicking or"
4287
 
                                         " multi-merges.")
 
4531
                                         " multi-merges."))
4288
4532
        repository = tree.branch.repository
4289
4533
        interesting_ids = None
4290
4534
        new_conflicts = []
4509
4753
            type=_parse_revision_str,
4510
4754
            help='Filter on local branch revisions (inclusive). '
4511
4755
                'See "help revisionspec" for details.'),
4512
 
        Option('include-merges',
 
4756
        Option('include-merged',
4513
4757
               'Show all revisions in addition to the mainline ones.'),
 
4758
        Option('include-merges', hidden=True,
 
4759
               help='Historical alias for --include-merged.'),
4514
4760
        ]
4515
4761
    encoding_type = 'replace'
4516
4762
 
4519
4765
            theirs_only=False,
4520
4766
            log_format=None, long=False, short=False, line=False,
4521
4767
            show_ids=False, verbose=False, this=False, other=False,
4522
 
            include_merges=False, revision=None, my_revision=None,
4523
 
            directory=u'.'):
 
4768
            include_merged=None, revision=None, my_revision=None,
 
4769
            directory=u'.',
 
4770
            include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4524
4771
        from bzrlib.missing import find_unmerged, iter_log_revisions
4525
4772
        def message(s):
4526
4773
            if not is_quiet():
4527
4774
                self.outf.write(s)
4528
4775
 
 
4776
        if symbol_versioning.deprecated_passed(include_merges):
 
4777
            ui.ui_factory.show_user_warning(
 
4778
                'deprecated_command_option',
 
4779
                deprecated_name='--include-merges',
 
4780
                recommended_name='--include-merged',
 
4781
                deprecated_in_version='2.5',
 
4782
                command=self.invoked_as)
 
4783
            if include_merged is None:
 
4784
                include_merged = include_merges
 
4785
            else:
 
4786
                raise errors.BzrCommandError(gettext(
 
4787
                    '{0} and {1} are mutually exclusive').format(
 
4788
                    '--include-merges', '--include-merged'))
 
4789
        if include_merged is None:
 
4790
            include_merged = False
4529
4791
        if this:
4530
4792
            mine_only = this
4531
4793
        if other:
4546
4808
        if other_branch is None:
4547
4809
            other_branch = parent
4548
4810
            if other_branch is None:
4549
 
                raise errors.BzrCommandError("No peer location known"
4550
 
                                             " or specified.")
 
4811
                raise errors.BzrCommandError(gettext("No peer location known"
 
4812
                                             " or specified."))
4551
4813
            display_url = urlutils.unescape_for_display(parent,
4552
4814
                                                        self.outf.encoding)
4553
 
            message("Using saved parent location: "
4554
 
                    + display_url + "\n")
 
4815
            message(gettext("Using saved parent location: {0}\n").format(
 
4816
                    display_url))
4555
4817
 
4556
4818
        remote_branch = Branch.open(other_branch)
4557
4819
        if remote_branch.base == local_branch.base:
4570
4832
        local_extra, remote_extra = find_unmerged(
4571
4833
            local_branch, remote_branch, restrict,
4572
4834
            backward=not reverse,
4573
 
            include_merges=include_merges,
 
4835
            include_merged=include_merged,
4574
4836
            local_revid_range=local_revid_range,
4575
4837
            remote_revid_range=remote_revid_range)
4576
4838
 
4583
4845
 
4584
4846
        status_code = 0
4585
4847
        if local_extra and not theirs_only:
4586
 
            message("You have %d extra revision(s):\n" %
 
4848
            message(ngettext("You have %d extra revision:\n",
 
4849
                             "You have %d extra revisions:\n", 
 
4850
                             len(local_extra)) %
4587
4851
                len(local_extra))
4588
4852
            for revision in iter_log_revisions(local_extra,
4589
4853
                                local_branch.repository,
4597
4861
        if remote_extra and not mine_only:
4598
4862
            if printed_local is True:
4599
4863
                message("\n\n\n")
4600
 
            message("You are missing %d revision(s):\n" %
 
4864
            message(ngettext("You are missing %d revision:\n",
 
4865
                             "You are missing %d revisions:\n",
 
4866
                             len(remote_extra)) %
4601
4867
                len(remote_extra))
4602
4868
            for revision in iter_log_revisions(remote_extra,
4603
4869
                                remote_branch.repository,
4607
4873
 
4608
4874
        if mine_only and not local_extra:
4609
4875
            # We checked local, and found nothing extra
4610
 
            message('This branch is up to date.\n')
 
4876
            message(gettext('This branch has no new revisions.\n'))
4611
4877
        elif theirs_only and not remote_extra:
4612
4878
            # We checked remote, and found nothing extra
4613
 
            message('Other branch is up to date.\n')
 
4879
            message(gettext('Other branch has no new revisions.\n'))
4614
4880
        elif not (mine_only or theirs_only or local_extra or
4615
4881
                  remote_extra):
4616
4882
            # We checked both branches, and neither one had extra
4617
4883
            # revisions
4618
 
            message("Branches are up to date.\n")
 
4884
            message(gettext("Branches are up to date.\n"))
4619
4885
        self.cleanup_now()
4620
4886
        if not status_code and parent is None and other_branch is not None:
4621
4887
            self.add_cleanup(local_branch.lock_write().unlock)
4651
4917
        ]
4652
4918
 
4653
4919
    def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4654
 
        dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
 
4920
        dir = controldir.ControlDir.open_containing(branch_or_repo)[0]
4655
4921
        try:
4656
4922
            branch = dir.open_branch()
4657
4923
            repository = branch.repository
4782
5048
 
4783
5049
    def run(self, revision_id_list=None, revision=None, directory=u'.'):
4784
5050
        if revision_id_list is not None and revision is not None:
4785
 
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
 
5051
            raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
4786
5052
        if revision_id_list is None and revision is None:
4787
 
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
 
5053
            raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
4788
5054
        b = WorkingTree.open_containing(directory)[0].branch
4789
5055
        self.add_cleanup(b.lock_write().unlock)
4790
5056
        return self._run(b, revision_id_list, revision)
4791
5057
 
4792
5058
    def _run(self, b, revision_id_list, revision):
4793
5059
        import bzrlib.gpg as gpg
4794
 
        gpg_strategy = gpg.GPGStrategy(b.get_config())
 
5060
        gpg_strategy = gpg.GPGStrategy(b.get_config_stack())
4795
5061
        if revision_id_list is not None:
4796
5062
            b.repository.start_write_group()
4797
5063
            try:
4822
5088
                if to_revid is None:
4823
5089
                    to_revno = b.revno()
4824
5090
                if from_revno is None or to_revno is None:
4825
 
                    raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
 
5091
                    raise errors.BzrCommandError(gettext('Cannot sign a range of non-revision-history revisions'))
4826
5092
                b.repository.start_write_group()
4827
5093
                try:
4828
5094
                    for revno in range(from_revno, to_revno + 1):
4834
5100
                else:
4835
5101
                    b.repository.commit_write_group()
4836
5102
            else:
4837
 
                raise errors.BzrCommandError('Please supply either one revision, or a range.')
 
5103
                raise errors.BzrCommandError(gettext('Please supply either one revision, or a range.'))
4838
5104
 
4839
5105
 
4840
5106
class cmd_bind(Command):
4859
5125
            try:
4860
5126
                location = b.get_old_bound_location()
4861
5127
            except errors.UpgradeRequired:
4862
 
                raise errors.BzrCommandError('No location supplied.  '
4863
 
                    'This format does not remember old locations.')
 
5128
                raise errors.BzrCommandError(gettext('No location supplied.  '
 
5129
                    'This format does not remember old locations.'))
4864
5130
            else:
4865
5131
                if location is None:
4866
5132
                    if b.get_bound_location() is not None:
4867
 
                        raise errors.BzrCommandError('Branch is already bound')
 
5133
                        raise errors.BzrCommandError(gettext('Branch is already bound'))
4868
5134
                    else:
4869
 
                        raise errors.BzrCommandError('No location supplied '
4870
 
                            'and no previous location known')
 
5135
                        raise errors.BzrCommandError(gettext('No location supplied '
 
5136
                            'and no previous location known'))
4871
5137
        b_other = Branch.open(location)
4872
5138
        try:
4873
5139
            b.bind(b_other)
4874
5140
        except errors.DivergedBranches:
4875
 
            raise errors.BzrCommandError('These branches have diverged.'
4876
 
                                         ' Try merging, and then bind again.')
 
5141
            raise errors.BzrCommandError(gettext('These branches have diverged.'
 
5142
                                         ' Try merging, and then bind again.'))
4877
5143
        if b.get_config().has_explicit_nickname():
4878
5144
            b.nick = b_other.nick
4879
5145
 
4892
5158
    def run(self, directory=u'.'):
4893
5159
        b, relpath = Branch.open_containing(directory)
4894
5160
        if not b.unbind():
4895
 
            raise errors.BzrCommandError('Local branch is not bound')
 
5161
            raise errors.BzrCommandError(gettext('Local branch is not bound'))
4896
5162
 
4897
5163
 
4898
5164
class cmd_uncommit(Command):
4919
5185
    takes_options = ['verbose', 'revision',
4920
5186
                    Option('dry-run', help='Don\'t actually make changes.'),
4921
5187
                    Option('force', help='Say yes to all questions.'),
 
5188
                    Option('keep-tags',
 
5189
                           help='Keep tags that point to removed revisions.'),
4922
5190
                    Option('local',
4923
5191
                           help="Only remove the commits from the local branch"
4924
5192
                                " when in a checkout."
4928
5196
    aliases = []
4929
5197
    encoding_type = 'replace'
4930
5198
 
4931
 
    def run(self, location=None,
4932
 
            dry_run=False, verbose=False,
4933
 
            revision=None, force=False, local=False):
 
5199
    def run(self, location=None, dry_run=False, verbose=False,
 
5200
            revision=None, force=False, local=False, keep_tags=False):
4934
5201
        if location is None:
4935
5202
            location = u'.'
4936
 
        control, relpath = bzrdir.BzrDir.open_containing(location)
 
5203
        control, relpath = controldir.ControlDir.open_containing(location)
4937
5204
        try:
4938
5205
            tree = control.open_workingtree()
4939
5206
            b = tree.branch
4945
5212
            self.add_cleanup(tree.lock_write().unlock)
4946
5213
        else:
4947
5214
            self.add_cleanup(b.lock_write().unlock)
4948
 
        return self._run(b, tree, dry_run, verbose, revision, force, local=local)
 
5215
        return self._run(b, tree, dry_run, verbose, revision, force,
 
5216
                         local, keep_tags)
4949
5217
 
4950
 
    def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
 
5218
    def _run(self, b, tree, dry_run, verbose, revision, force, local,
 
5219
             keep_tags):
4951
5220
        from bzrlib.log import log_formatter, show_log
4952
5221
        from bzrlib.uncommit import uncommit
4953
5222
 
4968
5237
                rev_id = b.get_rev_id(revno)
4969
5238
 
4970
5239
        if rev_id is None or _mod_revision.is_null(rev_id):
4971
 
            self.outf.write('No revisions to uncommit.\n')
 
5240
            self.outf.write(gettext('No revisions to uncommit.\n'))
4972
5241
            return 1
4973
5242
 
4974
5243
        lf = log_formatter('short',
4983
5252
                 end_revision=last_revno)
4984
5253
 
4985
5254
        if dry_run:
4986
 
            self.outf.write('Dry-run, pretending to remove'
4987
 
                            ' the above revisions.\n')
 
5255
            self.outf.write(gettext('Dry-run, pretending to remove'
 
5256
                            ' the above revisions.\n'))
4988
5257
        else:
4989
 
            self.outf.write('The above revision(s) will be removed.\n')
 
5258
            self.outf.write(gettext('The above revision(s) will be removed.\n'))
4990
5259
 
4991
5260
        if not force:
4992
5261
            if not ui.ui_factory.confirm_action(
4993
 
                    u'Uncommit these revisions',
 
5262
                    gettext(u'Uncommit these revisions'),
4994
5263
                    'bzrlib.builtins.uncommit',
4995
5264
                    {}):
4996
 
                self.outf.write('Canceled\n')
 
5265
                self.outf.write(gettext('Canceled\n'))
4997
5266
                return 0
4998
5267
 
4999
5268
        mutter('Uncommitting from {%s} to {%s}',
5000
5269
               last_rev_id, rev_id)
5001
5270
        uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5002
 
                 revno=revno, local=local)
5003
 
        self.outf.write('You can restore the old tip by running:\n'
5004
 
             '  bzr pull . -r revid:%s\n' % last_rev_id)
 
5271
                 revno=revno, local=local, keep_tags=keep_tags)
 
5272
        self.outf.write(gettext('You can restore the old tip by running:\n'
 
5273
             '  bzr pull . -r revid:%s\n') % last_rev_id)
5005
5274
 
5006
5275
 
5007
5276
class cmd_break_lock(Command):
5041
5310
            conf = _mod_config.LockableConfig(file_name=location)
5042
5311
            conf.break_lock()
5043
5312
        else:
5044
 
            control, relpath = bzrdir.BzrDir.open_containing(location)
 
5313
            control, relpath = controldir.ControlDir.open_containing(location)
5045
5314
            try:
5046
5315
                control.break_lock()
5047
5316
            except NotImplementedError:
5091
5360
                    'option leads to global uncontrolled write access to your '
5092
5361
                    'file system.'
5093
5362
                ),
 
5363
        Option('client-timeout', type=float,
 
5364
               help='Override the default idle client timeout (5min).'),
5094
5365
        ]
5095
5366
 
5096
5367
    def get_host_and_port(self, port):
5113
5384
        return host, port
5114
5385
 
5115
5386
    def run(self, port=None, inet=False, directory=None, allow_writes=False,
5116
 
            protocol=None):
 
5387
            protocol=None, client_timeout=None):
5117
5388
        from bzrlib import transport
5118
5389
        if directory is None:
5119
5390
            directory = os.getcwd()
5120
5391
        if protocol is None:
5121
5392
            protocol = transport.transport_server_registry.get()
5122
5393
        host, port = self.get_host_and_port(port)
5123
 
        url = urlutils.local_path_to_url(directory)
 
5394
        url = transport.location_to_url(directory)
5124
5395
        if not allow_writes:
5125
5396
            url = 'readonly+' + url
5126
 
        t = transport.get_transport(url)
5127
 
        protocol(t, host, port, inet)
 
5397
        t = transport.get_transport_from_url(url)
 
5398
        try:
 
5399
            protocol(t, host, port, inet, client_timeout)
 
5400
        except TypeError, e:
 
5401
            # We use symbol_versioning.deprecated_in just so that people
 
5402
            # grepping can find it here.
 
5403
            # symbol_versioning.deprecated_in((2, 5, 0))
 
5404
            symbol_versioning.warn(
 
5405
                'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
 
5406
                'Most likely it needs to be updated to support a'
 
5407
                ' "timeout" parameter (added in bzr 2.5.0)'
 
5408
                % (e, protocol.__module__, protocol),
 
5409
                DeprecationWarning)
 
5410
            protocol(t, host, port, inet)
5128
5411
 
5129
5412
 
5130
5413
class cmd_join(Command):
5153
5436
        containing_tree = WorkingTree.open_containing(parent_dir)[0]
5154
5437
        repo = containing_tree.branch.repository
5155
5438
        if not repo.supports_rich_root():
5156
 
            raise errors.BzrCommandError(
 
5439
            raise errors.BzrCommandError(gettext(
5157
5440
                "Can't join trees because %s doesn't support rich root data.\n"
5158
 
                "You can use bzr upgrade on the repository."
 
5441
                "You can use bzr upgrade on the repository.")
5159
5442
                % (repo,))
5160
5443
        if reference:
5161
5444
            try:
5163
5446
            except errors.BadReferenceTarget, e:
5164
5447
                # XXX: Would be better to just raise a nicely printable
5165
5448
                # exception from the real origin.  Also below.  mbp 20070306
5166
 
                raise errors.BzrCommandError("Cannot join %s.  %s" %
5167
 
                                             (tree, e.reason))
 
5449
                raise errors.BzrCommandError(
 
5450
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5168
5451
        else:
5169
5452
            try:
5170
5453
                containing_tree.subsume(sub_tree)
5171
5454
            except errors.BadSubsumeSource, e:
5172
 
                raise errors.BzrCommandError("Cannot join %s.  %s" %
5173
 
                                             (tree, e.reason))
 
5455
                raise errors.BzrCommandError(
 
5456
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5174
5457
 
5175
5458
 
5176
5459
class cmd_split(Command):
5260
5543
        if submit_branch is None:
5261
5544
            submit_branch = branch.get_parent()
5262
5545
        if submit_branch is None:
5263
 
            raise errors.BzrCommandError('No submit branch specified or known')
 
5546
            raise errors.BzrCommandError(gettext('No submit branch specified or known'))
5264
5547
 
5265
5548
        stored_public_branch = branch.get_public_branch()
5266
5549
        if public_branch is None:
5268
5551
        elif stored_public_branch is None:
5269
5552
            branch.set_public_branch(public_branch)
5270
5553
        if not include_bundle and public_branch is None:
5271
 
            raise errors.BzrCommandError('No public branch specified or'
5272
 
                                         ' known')
 
5554
            raise errors.BzrCommandError(gettext('No public branch specified or'
 
5555
                                         ' known'))
5273
5556
        base_revision_id = None
5274
5557
        if revision is not None:
5275
5558
            if len(revision) > 2:
5276
 
                raise errors.BzrCommandError('bzr merge-directive takes '
5277
 
                    'at most two one revision identifiers')
 
5559
                raise errors.BzrCommandError(gettext('bzr merge-directive takes '
 
5560
                    'at most two one revision identifiers'))
5278
5561
            revision_id = revision[-1].as_revision_id(branch)
5279
5562
            if len(revision) == 2:
5280
5563
                base_revision_id = revision[0].as_revision_id(branch)
5282
5565
            revision_id = branch.last_revision()
5283
5566
        revision_id = ensure_null(revision_id)
5284
5567
        if revision_id == NULL_REVISION:
5285
 
            raise errors.BzrCommandError('No revisions to bundle.')
 
5568
            raise errors.BzrCommandError(gettext('No revisions to bundle.'))
5286
5569
        directive = merge_directive.MergeDirective2.from_objects(
5287
5570
            branch.repository, revision_id, time.time(),
5288
5571
            osutils.local_time_offset(), submit_branch,
5334
5617
 
5335
5618
    Both the submit branch and the public branch follow the usual behavior with
5336
5619
    respect to --remember: If there is no default location set, the first send
5337
 
    will set it (use --no-remember to avoid settting it). After that, you can
 
5620
    will set it (use --no-remember to avoid setting it). After that, you can
5338
5621
    omit the location to use the default.  To change the default, use
5339
5622
    --remember. The value will only be saved if the location can be accessed.
5340
5623
 
5542
5825
        self.add_cleanup(branch.lock_write().unlock)
5543
5826
        if delete:
5544
5827
            if tag_name is None:
5545
 
                raise errors.BzrCommandError("No tag specified to delete.")
 
5828
                raise errors.BzrCommandError(gettext("No tag specified to delete."))
5546
5829
            branch.tags.delete_tag(tag_name)
5547
 
            note('Deleted tag %s.' % tag_name)
 
5830
            note(gettext('Deleted tag %s.') % tag_name)
5548
5831
        else:
5549
5832
            if revision:
5550
5833
                if len(revision) != 1:
5551
 
                    raise errors.BzrCommandError(
 
5834
                    raise errors.BzrCommandError(gettext(
5552
5835
                        "Tags can only be placed on a single revision, "
5553
 
                        "not on a range")
 
5836
                        "not on a range"))
5554
5837
                revision_id = revision[0].as_revision_id(branch)
5555
5838
            else:
5556
5839
                revision_id = branch.last_revision()
5557
5840
            if tag_name is None:
5558
5841
                tag_name = branch.automatic_tag_name(revision_id)
5559
5842
                if tag_name is None:
5560
 
                    raise errors.BzrCommandError(
5561
 
                        "Please specify a tag name.")
5562
 
            if (not force) and branch.tags.has_tag(tag_name):
 
5843
                    raise errors.BzrCommandError(gettext(
 
5844
                        "Please specify a tag name."))
 
5845
            try:
 
5846
                existing_target = branch.tags.lookup_tag(tag_name)
 
5847
            except errors.NoSuchTag:
 
5848
                existing_target = None
 
5849
            if not force and existing_target not in (None, revision_id):
5563
5850
                raise errors.TagAlreadyExists(tag_name)
5564
 
            branch.tags.set_tag(tag_name, revision_id)
5565
 
            note('Created tag %s.' % tag_name)
 
5851
            if existing_target == revision_id:
 
5852
                note(gettext('Tag %s already exists for that revision.') % tag_name)
 
5853
            else:
 
5854
                branch.tags.set_tag(tag_name, revision_id)
 
5855
                if existing_target is None:
 
5856
                    note(gettext('Created tag %s.') % tag_name)
 
5857
                else:
 
5858
                    note(gettext('Updated tag %s.') % tag_name)
5566
5859
 
5567
5860
 
5568
5861
class cmd_tags(Command):
5594
5887
 
5595
5888
        self.add_cleanup(branch.lock_read().unlock)
5596
5889
        if revision:
5597
 
            graph = branch.repository.get_graph()
5598
 
            rev1, rev2 = _get_revision_range(revision, branch, self.name())
5599
 
            revid1, revid2 = rev1.rev_id, rev2.rev_id
5600
 
            # only show revisions between revid1 and revid2 (inclusive)
5601
 
            tags = [(tag, revid) for tag, revid in tags if
5602
 
                graph.is_between(revid, revid1, revid2)]
 
5890
            # Restrict to the specified range
 
5891
            tags = self._tags_for_range(branch, revision)
5603
5892
        if sort is None:
5604
5893
            sort = tag_sort_methods.get()
5605
5894
        sort(branch, tags)
5610
5899
                    revno = branch.revision_id_to_dotted_revno(revid)
5611
5900
                    if isinstance(revno, tuple):
5612
5901
                        revno = '.'.join(map(str, revno))
5613
 
                except (errors.NoSuchRevision, errors.GhostRevisionsHaveNoRevno):
 
5902
                except (errors.NoSuchRevision,
 
5903
                        errors.GhostRevisionsHaveNoRevno,
 
5904
                        errors.UnsupportedOperation):
5614
5905
                    # Bad tag data/merges can lead to tagged revisions
5615
5906
                    # which are not in this branch. Fail gracefully ...
5616
5907
                    revno = '?'
5619
5910
        for tag, revspec in tags:
5620
5911
            self.outf.write('%-20s %s\n' % (tag, revspec))
5621
5912
 
 
5913
    def _tags_for_range(self, branch, revision):
 
5914
        range_valid = True
 
5915
        rev1, rev2 = _get_revision_range(revision, branch, self.name())
 
5916
        revid1, revid2 = rev1.rev_id, rev2.rev_id
 
5917
        # _get_revision_range will always set revid2 if it's not specified.
 
5918
        # If revid1 is None, it means we want to start from the branch
 
5919
        # origin which is always a valid ancestor. If revid1 == revid2, the
 
5920
        # ancestry check is useless.
 
5921
        if revid1 and revid1 != revid2:
 
5922
            # FIXME: We really want to use the same graph than
 
5923
            # branch.iter_merge_sorted_revisions below, but this is not
 
5924
            # easily available -- vila 2011-09-23
 
5925
            if branch.repository.get_graph().is_ancestor(revid2, revid1):
 
5926
                # We don't want to output anything in this case...
 
5927
                return []
 
5928
        # only show revisions between revid1 and revid2 (inclusive)
 
5929
        tagged_revids = branch.tags.get_reverse_tag_dict()
 
5930
        found = []
 
5931
        for r in branch.iter_merge_sorted_revisions(
 
5932
            start_revision_id=revid2, stop_revision_id=revid1,
 
5933
            stop_rule='include'):
 
5934
            revid_tags = tagged_revids.get(r[0], None)
 
5935
            if revid_tags:
 
5936
                found.extend([(tag, r[0]) for tag in revid_tags])
 
5937
        return found
 
5938
 
5622
5939
 
5623
5940
class cmd_reconfigure(Command):
5624
5941
    __doc__ = """Reconfigure the type of a bzr directory.
5638
5955
    takes_args = ['location?']
5639
5956
    takes_options = [
5640
5957
        RegistryOption.from_kwargs(
5641
 
            'target_type',
5642
 
            title='Target type',
5643
 
            help='The type to reconfigure the directory to.',
 
5958
            'tree_type',
 
5959
            title='Tree type',
 
5960
            help='The relation between branch and tree.',
5644
5961
            value_switches=True, enum_switch=False,
5645
5962
            branch='Reconfigure to be an unbound branch with no working tree.',
5646
5963
            tree='Reconfigure to be an unbound branch with a working tree.',
5647
5964
            checkout='Reconfigure to be a bound branch with a working tree.',
5648
5965
            lightweight_checkout='Reconfigure to be a lightweight'
5649
5966
                ' checkout (with no local history).',
 
5967
            ),
 
5968
        RegistryOption.from_kwargs(
 
5969
            'repository_type',
 
5970
            title='Repository type',
 
5971
            help='Location fo the repository.',
 
5972
            value_switches=True, enum_switch=False,
5650
5973
            standalone='Reconfigure to be a standalone branch '
5651
5974
                '(i.e. stop using shared repository).',
5652
5975
            use_shared='Reconfigure to use a shared repository.',
 
5976
            ),
 
5977
        RegistryOption.from_kwargs(
 
5978
            'repository_trees',
 
5979
            title='Trees in Repository',
 
5980
            help='Whether new branches in the repository have trees.',
 
5981
            value_switches=True, enum_switch=False,
5653
5982
            with_trees='Reconfigure repository to create '
5654
5983
                'working trees on branches by default.',
5655
5984
            with_no_trees='Reconfigure repository to not create '
5669
5998
            ),
5670
5999
        ]
5671
6000
 
5672
 
    def run(self, location=None, target_type=None, bind_to=None, force=False,
5673
 
            stacked_on=None,
5674
 
            unstacked=None):
5675
 
        directory = bzrdir.BzrDir.open(location)
 
6001
    def run(self, location=None, bind_to=None, force=False,
 
6002
            tree_type=None, repository_type=None, repository_trees=None,
 
6003
            stacked_on=None, unstacked=None):
 
6004
        directory = controldir.ControlDir.open(location)
5676
6005
        if stacked_on and unstacked:
5677
 
            raise errors.BzrCommandError("Can't use both --stacked-on and --unstacked")
 
6006
            raise errors.BzrCommandError(gettext("Can't use both --stacked-on and --unstacked"))
5678
6007
        elif stacked_on is not None:
5679
6008
            reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5680
6009
        elif unstacked:
5682
6011
        # At the moment you can use --stacked-on and a different
5683
6012
        # reconfiguration shape at the same time; there seems no good reason
5684
6013
        # to ban it.
5685
 
        if target_type is None:
 
6014
        if (tree_type is None and
 
6015
            repository_type is None and
 
6016
            repository_trees is None):
5686
6017
            if stacked_on or unstacked:
5687
6018
                return
5688
6019
            else:
5689
 
                raise errors.BzrCommandError('No target configuration '
5690
 
                    'specified')
5691
 
        elif target_type == 'branch':
 
6020
                raise errors.BzrCommandError(gettext('No target configuration '
 
6021
                    'specified'))
 
6022
        reconfiguration = None
 
6023
        if tree_type == 'branch':
5692
6024
            reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5693
 
        elif target_type == 'tree':
 
6025
        elif tree_type == 'tree':
5694
6026
            reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5695
 
        elif target_type == 'checkout':
 
6027
        elif tree_type == 'checkout':
5696
6028
            reconfiguration = reconfigure.Reconfigure.to_checkout(
5697
6029
                directory, bind_to)
5698
 
        elif target_type == 'lightweight-checkout':
 
6030
        elif tree_type == 'lightweight-checkout':
5699
6031
            reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5700
6032
                directory, bind_to)
5701
 
        elif target_type == 'use-shared':
 
6033
        if reconfiguration:
 
6034
            reconfiguration.apply(force)
 
6035
            reconfiguration = None
 
6036
        if repository_type == 'use-shared':
5702
6037
            reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5703
 
        elif target_type == 'standalone':
 
6038
        elif repository_type == 'standalone':
5704
6039
            reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5705
 
        elif target_type == 'with-trees':
 
6040
        if reconfiguration:
 
6041
            reconfiguration.apply(force)
 
6042
            reconfiguration = None
 
6043
        if repository_trees == 'with-trees':
5706
6044
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5707
6045
                directory, True)
5708
 
        elif target_type == 'with-no-trees':
 
6046
        elif repository_trees == 'with-no-trees':
5709
6047
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5710
6048
                directory, False)
5711
 
        reconfiguration.apply(force)
 
6049
        if reconfiguration:
 
6050
            reconfiguration.apply(force)
 
6051
            reconfiguration = None
5712
6052
 
5713
6053
 
5714
6054
class cmd_switch(Command):
5749
6089
        from bzrlib import switch
5750
6090
        tree_location = directory
5751
6091
        revision = _get_one_revision('switch', revision)
5752
 
        control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
 
6092
        control_dir = controldir.ControlDir.open_containing(tree_location)[0]
5753
6093
        if to_location is None:
5754
6094
            if revision is None:
5755
 
                raise errors.BzrCommandError('You must supply either a'
5756
 
                                             ' revision or a location')
 
6095
                raise errors.BzrCommandError(gettext('You must supply either a'
 
6096
                                             ' revision or a location'))
5757
6097
            to_location = tree_location
5758
6098
        try:
5759
6099
            branch = control_dir.open_branch()
5763
6103
            had_explicit_nick = False
5764
6104
        if create_branch:
5765
6105
            if branch is None:
5766
 
                raise errors.BzrCommandError('cannot create branch without'
5767
 
                                             ' source branch')
 
6106
                raise errors.BzrCommandError(gettext('cannot create branch without'
 
6107
                                             ' source branch'))
5768
6108
            to_location = directory_service.directories.dereference(
5769
6109
                              to_location)
5770
6110
            if '/' not in to_location and '\\' not in to_location:
5771
6111
                # This path is meant to be relative to the existing branch
5772
6112
                this_url = self._get_branch_location(control_dir)
5773
 
                to_location = urlutils.join(this_url, '..', to_location)
 
6113
                # Perhaps the target control dir supports colocated branches?
 
6114
                try:
 
6115
                    root = controldir.ControlDir.open(this_url,
 
6116
                        possible_transports=[control_dir.user_transport])
 
6117
                except errors.NotBranchError:
 
6118
                    colocated = False
 
6119
                else:
 
6120
                    colocated = root._format.colocated_branches
 
6121
                if colocated:
 
6122
                    to_location = urlutils.join_segment_parameters(this_url,
 
6123
                        {"branch": urlutils.escape(to_location)})
 
6124
                else:
 
6125
                    to_location = urlutils.join(
 
6126
                        this_url, '..', urlutils.escape(to_location))
5774
6127
            to_branch = branch.bzrdir.sprout(to_location,
5775
6128
                                 possible_transports=[branch.bzrdir.root_transport],
5776
6129
                                 source_branch=branch).open_branch()
5777
6130
        else:
 
6131
            # Perhaps it's a colocated branch?
5778
6132
            try:
5779
 
                to_branch = Branch.open(to_location)
5780
 
            except errors.NotBranchError:
5781
 
                this_url = self._get_branch_location(control_dir)
5782
 
                to_branch = Branch.open(
5783
 
                    urlutils.join(this_url, '..', to_location))
 
6133
                to_branch = control_dir.open_branch(to_location)
 
6134
            except (errors.NotBranchError, errors.NoColocatedBranchSupport):
 
6135
                try:
 
6136
                    to_branch = Branch.open(to_location)
 
6137
                except errors.NotBranchError:
 
6138
                    this_url = self._get_branch_location(control_dir)
 
6139
                    to_branch = Branch.open(
 
6140
                        urlutils.join(
 
6141
                            this_url, '..', urlutils.escape(to_location)))
5784
6142
        if revision is not None:
5785
6143
            revision = revision.as_revision_id(to_branch)
5786
6144
        switch.switch(control_dir, to_branch, force, revision_id=revision)
5787
6145
        if had_explicit_nick:
5788
6146
            branch = control_dir.open_branch() #get the new branch!
5789
6147
            branch.nick = to_branch.nick
5790
 
        note('Switched to branch: %s',
 
6148
        note(gettext('Switched to branch: %s'),
5791
6149
            urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5792
6150
 
5793
6151
    def _get_branch_location(self, control_dir):
5902
6260
            name = current_view
5903
6261
        if delete:
5904
6262
            if file_list:
5905
 
                raise errors.BzrCommandError(
5906
 
                    "Both --delete and a file list specified")
 
6263
                raise errors.BzrCommandError(gettext(
 
6264
                    "Both --delete and a file list specified"))
5907
6265
            elif switch:
5908
 
                raise errors.BzrCommandError(
5909
 
                    "Both --delete and --switch specified")
 
6266
                raise errors.BzrCommandError(gettext(
 
6267
                    "Both --delete and --switch specified"))
5910
6268
            elif all:
5911
6269
                tree.views.set_view_info(None, {})
5912
 
                self.outf.write("Deleted all views.\n")
 
6270
                self.outf.write(gettext("Deleted all views.\n"))
5913
6271
            elif name is None:
5914
 
                raise errors.BzrCommandError("No current view to delete")
 
6272
                raise errors.BzrCommandError(gettext("No current view to delete"))
5915
6273
            else:
5916
6274
                tree.views.delete_view(name)
5917
 
                self.outf.write("Deleted '%s' view.\n" % name)
 
6275
                self.outf.write(gettext("Deleted '%s' view.\n") % name)
5918
6276
        elif switch:
5919
6277
            if file_list:
5920
 
                raise errors.BzrCommandError(
5921
 
                    "Both --switch and a file list specified")
 
6278
                raise errors.BzrCommandError(gettext(
 
6279
                    "Both --switch and a file list specified"))
5922
6280
            elif all:
5923
 
                raise errors.BzrCommandError(
5924
 
                    "Both --switch and --all specified")
 
6281
                raise errors.BzrCommandError(gettext(
 
6282
                    "Both --switch and --all specified"))
5925
6283
            elif switch == 'off':
5926
6284
                if current_view is None:
5927
 
                    raise errors.BzrCommandError("No current view to disable")
 
6285
                    raise errors.BzrCommandError(gettext("No current view to disable"))
5928
6286
                tree.views.set_view_info(None, view_dict)
5929
 
                self.outf.write("Disabled '%s' view.\n" % (current_view))
 
6287
                self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
5930
6288
            else:
5931
6289
                tree.views.set_view_info(switch, view_dict)
5932
6290
                view_str = views.view_display_str(tree.views.lookup_view())
5933
 
                self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
 
6291
                self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
5934
6292
        elif all:
5935
6293
            if view_dict:
5936
 
                self.outf.write('Views defined:\n')
 
6294
                self.outf.write(gettext('Views defined:\n'))
5937
6295
                for view in sorted(view_dict):
5938
6296
                    if view == current_view:
5939
6297
                        active = "=>"
5942
6300
                    view_str = views.view_display_str(view_dict[view])
5943
6301
                    self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5944
6302
            else:
5945
 
                self.outf.write('No views defined.\n')
 
6303
                self.outf.write(gettext('No views defined.\n'))
5946
6304
        elif file_list:
5947
6305
            if name is None:
5948
6306
                # No name given and no current view set
5949
6307
                name = 'my'
5950
6308
            elif name == 'off':
5951
 
                raise errors.BzrCommandError(
5952
 
                    "Cannot change the 'off' pseudo view")
 
6309
                raise errors.BzrCommandError(gettext(
 
6310
                    "Cannot change the 'off' pseudo view"))
5953
6311
            tree.views.set_view(name, sorted(file_list))
5954
6312
            view_str = views.view_display_str(tree.views.lookup_view())
5955
 
            self.outf.write("Using '%s' view: %s\n" % (name, view_str))
 
6313
            self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
5956
6314
        else:
5957
6315
            # list the files
5958
6316
            if name is None:
5959
6317
                # No name given and no current view set
5960
 
                self.outf.write('No current view.\n')
 
6318
                self.outf.write(gettext('No current view.\n'))
5961
6319
            else:
5962
6320
                view_str = views.view_display_str(tree.views.lookup_view(name))
5963
 
                self.outf.write("'%s' view is: %s\n" % (name, view_str))
 
6321
                self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
5964
6322
 
5965
6323
 
5966
6324
class cmd_hooks(Command):
5980
6338
                        self.outf.write("    %s\n" %
5981
6339
                                        (some_hooks.get_hook_name(hook),))
5982
6340
                else:
5983
 
                    self.outf.write("    <no hooks installed>\n")
 
6341
                    self.outf.write(gettext("    <no hooks installed>\n"))
5984
6342
 
5985
6343
 
5986
6344
class cmd_remove_branch(Command):
6087
6445
        manager = tree.get_shelf_manager()
6088
6446
        shelves = manager.active_shelves()
6089
6447
        if len(shelves) == 0:
6090
 
            note('No shelved changes.')
 
6448
            note(gettext('No shelved changes.'))
6091
6449
            return 0
6092
6450
        for shelf_id in reversed(shelves):
6093
6451
            message = manager.get_metadata(shelf_id).get('message')
6182
6540
        if path is not None:
6183
6541
            branchdir = path
6184
6542
        tree, branch, relpath =(
6185
 
            bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
 
6543
            controldir.ControlDir.open_containing_tree_or_branch(branchdir))
6186
6544
        if path is not None:
6187
6545
            path = relpath
6188
6546
        if tree is None:
6216
6574
    __doc__ = """Export command helps and error messages in po format."""
6217
6575
 
6218
6576
    hidden = True
 
6577
    takes_options = [Option('plugin', 
 
6578
                            help='Export help text from named command '\
 
6579
                                 '(defaults to all built in commands).',
 
6580
                            type=str),
 
6581
                     Option('include-duplicates',
 
6582
                            help='Output multiple copies of the same msgid '
 
6583
                                 'string if it appears more than once.'),
 
6584
                            ]
6219
6585
 
6220
 
    def run(self):
 
6586
    def run(self, plugin=None, include_duplicates=False):
6221
6587
        from bzrlib.export_pot import export_pot
6222
 
        export_pot(self.outf)
 
6588
        export_pot(self.outf, plugin, include_duplicates)
6223
6589
 
6224
6590
 
6225
6591
def _register_lazy_builtins():