~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 09:50:04 UTC
  • mfrom: (6424 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6426.
  • Revision ID: martin.packman@canonical.com-20120105095004-mia9xb7y0efmto0v
Merge bzr.dev to resolve conflicts in bzrlib.builtins

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""builtin bzr commands"""
18
18
 
 
19
from __future__ import absolute_import
 
20
 
19
21
import os
20
22
 
 
23
import bzrlib.bzrdir
 
24
 
21
25
from bzrlib import lazy_import
22
26
lazy_import.lazy_import(globals(), """
23
27
import cStringIO
 
28
import errno
24
29
import sys
25
30
import time
26
31
 
29
34
    bugtracker,
30
35
    bundle,
31
36
    btree_index,
32
 
    bzrdir,
 
37
    controldir,
33
38
    directory_service,
34
39
    delta,
35
40
    config as _mod_config,
57
62
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
58
63
from bzrlib.smtp_connection import SMTPConnection
59
64
from bzrlib.workingtree import WorkingTree
 
65
from bzrlib.i18n import gettext, ngettext
60
66
""")
61
67
 
62
68
from bzrlib.commands import (
112
118
            if view_files:
113
119
                file_list = view_files
114
120
                view_str = views.view_display_str(view_files)
115
 
                note("Ignoring files outside view. View is %s" % view_str)
 
121
                note(gettext("Ignoring files outside view. View is %s") % view_str)
116
122
    return tree, file_list
117
123
 
118
124
 
120
126
    if revisions is None:
121
127
        return None
122
128
    if len(revisions) != 1:
123
 
        raise errors.BzrCommandError(
124
 
            'bzr %s --revision takes exactly one revision identifier' % (
 
129
        raise errors.BzrCommandError(gettext(
 
130
            'bzr %s --revision takes exactly one revision identifier') % (
125
131
                command_name,))
126
132
    return revisions[0]
127
133
 
196
202
    the --directory option is used to specify a different branch."""
197
203
    if directory is not None:
198
204
        return (None, Branch.open(directory), filename)
199
 
    return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
 
205
    return controldir.ControlDir.open_containing_tree_or_branch(filename)
200
206
 
201
207
 
202
208
# TODO: Make sure no commands unconditionally use the working directory as a
288
294
        from bzrlib.status import show_tree_status
289
295
 
290
296
        if revision and len(revision) > 2:
291
 
            raise errors.BzrCommandError('bzr status --revision takes exactly'
292
 
                                         ' one or two revision specifiers')
 
297
            raise errors.BzrCommandError(gettext('bzr status --revision takes exactly'
 
298
                                         ' one or two revision specifiers'))
293
299
 
294
300
        tree, relfile_list = WorkingTree.open_containing_paths(file_list)
295
301
        # Avoid asking for specific files when that is not needed.
332
338
    @display_command
333
339
    def run(self, revision_id=None, revision=None, directory=u'.'):
334
340
        if revision_id is not None and revision is not None:
335
 
            raise errors.BzrCommandError('You can only supply one of'
336
 
                                         ' revision_id or --revision')
 
341
            raise errors.BzrCommandError(gettext('You can only supply one of'
 
342
                                         ' revision_id or --revision'))
337
343
        if revision_id is None and revision is None:
338
 
            raise errors.BzrCommandError('You must supply either'
339
 
                                         ' --revision or a revision_id')
 
344
            raise errors.BzrCommandError(gettext('You must supply either'
 
345
                                         ' --revision or a revision_id'))
340
346
 
341
 
        b = bzrdir.BzrDir.open_containing_tree_or_branch(directory)[1]
 
347
        b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
342
348
 
343
349
        revisions = b.repository.revisions
344
350
        if revisions is None:
345
 
            raise errors.BzrCommandError('Repository %r does not support '
346
 
                'access to raw revision texts')
 
351
            raise errors.BzrCommandError(gettext('Repository %r does not support '
 
352
                'access to raw revision texts'))
347
353
 
348
354
        b.repository.lock_read()
349
355
        try:
353
359
                try:
354
360
                    self.print_revision(revisions, revision_id)
355
361
                except errors.NoSuchRevision:
356
 
                    msg = "The repository %s contains no revision %s." % (
 
362
                    msg = gettext("The repository {0} contains no revision {1}.").format(
357
363
                        b.repository.base, revision_id)
358
364
                    raise errors.BzrCommandError(msg)
359
365
            elif revision is not None:
360
366
                for rev in revision:
361
367
                    if rev is None:
362
368
                        raise errors.BzrCommandError(
363
 
                            'You cannot specify a NULL revision.')
 
369
                            gettext('You cannot specify a NULL revision.'))
364
370
                    rev_id = rev.as_revision_id(b)
365
371
                    self.print_revision(revisions, rev_id)
366
372
        finally:
472
478
            location_list=['.']
473
479
 
474
480
        for location in location_list:
475
 
            d = bzrdir.BzrDir.open(location)
476
 
            
 
481
            d = controldir.ControlDir.open(location)
 
482
 
477
483
            try:
478
484
                working = d.open_workingtree()
479
485
            except errors.NoWorkingTree:
480
 
                raise errors.BzrCommandError("No working tree to remove")
 
486
                raise errors.BzrCommandError(gettext("No working tree to remove"))
481
487
            except errors.NotLocalUrl:
482
 
                raise errors.BzrCommandError("You cannot remove the working tree"
483
 
                                             " of a remote path")
 
488
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
489
                                             " of a remote path"))
484
490
            if not force:
485
491
                if (working.has_changes()):
486
492
                    raise errors.UncommittedChanges(working)
488
494
                    raise errors.ShelvedChanges(working)
489
495
 
490
496
            if working.user_url != working.branch.user_url:
491
 
                raise errors.BzrCommandError("You cannot remove the working tree"
492
 
                                             " from a lightweight checkout")
 
497
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
498
                                             " from a lightweight checkout"))
493
499
 
494
500
            d.destroy_workingtree()
495
501
 
527
533
                pass # There seems to be a real error here, so we'll reset
528
534
            else:
529
535
                # Refuse
530
 
                raise errors.BzrCommandError(
 
536
                raise errors.BzrCommandError(gettext(
531
537
                    'The tree does not appear to be corrupt. You probably'
532
538
                    ' want "bzr revert" instead. Use "--force" if you are'
533
 
                    ' sure you want to reset the working tree.')
 
539
                    ' sure you want to reset the working tree.'))
534
540
        if revision is None:
535
541
            revision_ids = None
536
542
        else:
539
545
            tree.reset_state(revision_ids)
540
546
        except errors.BzrError, e:
541
547
            if revision_ids is None:
542
 
                extra = (', the header appears corrupt, try passing -r -1'
543
 
                         ' to set the state to the last commit')
 
548
                extra = (gettext(', the header appears corrupt, try passing -r -1'
 
549
                         ' to set the state to the last commit'))
544
550
            else:
545
551
                extra = ''
546
 
            raise errors.BzrCommandError('failed to reset the tree state'
547
 
                                         + extra)
 
552
            raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
548
553
 
549
554
 
550
555
class cmd_revno(Command):
556
561
    _see_also = ['info']
557
562
    takes_args = ['location?']
558
563
    takes_options = [
559
 
        Option('tree', help='Show revno of working tree'),
 
564
        Option('tree', help='Show revno of working tree.'),
 
565
        'revision',
560
566
        ]
561
567
 
562
568
    @display_command
563
 
    def run(self, tree=False, location=u'.'):
 
569
    def run(self, tree=False, location=u'.', revision=None):
 
570
        if revision is not None and tree:
 
571
            raise errors.BzrCommandError(gettext("--tree and --revision can "
 
572
                "not be used together"))
 
573
 
564
574
        if tree:
565
575
            try:
566
576
                wt = WorkingTree.open_containing(location)[0]
567
577
                self.add_cleanup(wt.lock_read().unlock)
568
578
            except (errors.NoWorkingTree, errors.NotLocalUrl):
569
579
                raise errors.NoWorkingTree(location)
 
580
            b = wt.branch
570
581
            revid = wt.last_revision()
571
 
            try:
572
 
                revno_t = wt.branch.revision_id_to_dotted_revno(revid)
573
 
            except errors.NoSuchRevision:
574
 
                revno_t = ('???',)
575
 
            revno = ".".join(str(n) for n in revno_t)
576
582
        else:
577
583
            b = Branch.open_containing(location)[0]
578
584
            self.add_cleanup(b.lock_read().unlock)
579
 
            revno = b.revno()
 
585
            if revision:
 
586
                if len(revision) != 1:
 
587
                    raise errors.BzrCommandError(gettext(
 
588
                        "Tags can only be placed on a single revision, "
 
589
                        "not on a range"))
 
590
                revid = revision[0].as_revision_id(b)
 
591
            else:
 
592
                revid = b.last_revision()
 
593
        try:
 
594
            revno_t = b.revision_id_to_dotted_revno(revid)
 
595
        except errors.NoSuchRevision:
 
596
            revno_t = ('???',)
 
597
        revno = ".".join(str(n) for n in revno_t)
580
598
        self.cleanup_now()
581
 
        self.outf.write(str(revno) + '\n')
 
599
        self.outf.write(revno + '\n')
582
600
 
583
601
 
584
602
class cmd_revision_info(Command):
591
609
        custom_help('directory',
592
610
            help='Branch to examine, '
593
611
                 'rather than the one containing the working directory.'),
594
 
        Option('tree', help='Show revno of working tree'),
 
612
        Option('tree', help='Show revno of working tree.'),
595
613
        ]
596
614
 
597
615
    @display_command
653
671
    are added.  This search proceeds recursively into versioned
654
672
    directories.  If no names are given '.' is assumed.
655
673
 
 
674
    A warning will be printed when nested trees are encountered,
 
675
    unless they are explicitly ignored.
 
676
 
656
677
    Therefore simply saying 'bzr add' will version all files that
657
678
    are currently unknown.
658
679
 
723
744
            if verbose:
724
745
                for glob in sorted(ignored.keys()):
725
746
                    for path in ignored[glob]:
726
 
                        self.outf.write("ignored %s matching \"%s\"\n"
727
 
                                        % (path, glob))
 
747
                        self.outf.write(
 
748
                         gettext("ignored {0} matching \"{1}\"\n").format(
 
749
                         path, glob))
728
750
 
729
751
 
730
752
class cmd_mkdir(Command):
734
756
    """
735
757
 
736
758
    takes_args = ['dir+']
 
759
    takes_options = [
 
760
        Option(
 
761
            'parents',
 
762
            help='No error if existing, make parent directories as needed.',
 
763
            short_name='p'
 
764
            )
 
765
        ]
737
766
    encoding_type = 'replace'
738
767
 
739
 
    def run(self, dir_list):
740
 
        for d in dir_list:
741
 
            wt, dd = WorkingTree.open_containing(d)
742
 
            base = os.path.dirname(dd)
743
 
            id = wt.path2id(base)
744
 
            if id != None:
745
 
                os.mkdir(d)
746
 
                wt.add([dd])
747
 
                self.outf.write('added %s\n' % d)
 
768
    @classmethod
 
769
    def add_file_with_parents(cls, wt, relpath):
 
770
        if wt.path2id(relpath) is not None:
 
771
            return
 
772
        cls.add_file_with_parents(wt, osutils.dirname(relpath))
 
773
        wt.add([relpath])
 
774
 
 
775
    @classmethod
 
776
    def add_file_single(cls, wt, relpath):
 
777
        wt.add([relpath])
 
778
 
 
779
    def run(self, dir_list, parents=False):
 
780
        if parents:
 
781
            add_file = self.add_file_with_parents
 
782
        else:
 
783
            add_file = self.add_file_single
 
784
        for dir in dir_list:
 
785
            wt, relpath = WorkingTree.open_containing(dir)
 
786
            if parents:
 
787
                try:
 
788
                    os.makedirs(dir)
 
789
                except OSError, e:
 
790
                    if e.errno != errno.EEXIST:
 
791
                        raise
748
792
            else:
749
 
                raise errors.NotVersionedError(path=base)
 
793
                os.mkdir(dir)
 
794
            add_file(wt, relpath)
 
795
            if not is_quiet():
 
796
                self.outf.write(gettext('added %s\n') % dir)
750
797
 
751
798
 
752
799
class cmd_relpath(Command):
788
835
    @display_command
789
836
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
790
837
        if kind and kind not in ['file', 'directory', 'symlink']:
791
 
            raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
 
838
            raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
792
839
 
793
840
        revision = _get_one_revision('inventory', revision)
794
841
        work_tree, file_list = WorkingTree.open_containing_paths(file_list)
858
905
        if auto:
859
906
            return self.run_auto(names_list, after, dry_run)
860
907
        elif dry_run:
861
 
            raise errors.BzrCommandError('--dry-run requires --auto.')
 
908
            raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
862
909
        if names_list is None:
863
910
            names_list = []
864
911
        if len(names_list) < 2:
865
 
            raise errors.BzrCommandError("missing file argument")
 
912
            raise errors.BzrCommandError(gettext("missing file argument"))
866
913
        tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
 
914
        for file_name in rel_names[0:-1]:
 
915
            if file_name == '':
 
916
                raise errors.BzrCommandError(gettext("can not move root of branch"))
867
917
        self.add_cleanup(tree.lock_tree_write().unlock)
868
918
        self._run(tree, names_list, rel_names, after)
869
919
 
870
920
    def run_auto(self, names_list, after, dry_run):
871
921
        if names_list is not None and len(names_list) > 1:
872
 
            raise errors.BzrCommandError('Only one path may be specified to'
873
 
                                         ' --auto.')
 
922
            raise errors.BzrCommandError(gettext('Only one path may be specified to'
 
923
                                         ' --auto.'))
874
924
        if after:
875
 
            raise errors.BzrCommandError('--after cannot be specified with'
876
 
                                         ' --auto.')
 
925
            raise errors.BzrCommandError(gettext('--after cannot be specified with'
 
926
                                         ' --auto.'))
877
927
        work_tree, file_list = WorkingTree.open_containing_paths(
878
928
            names_list, default_directory='.')
879
929
        self.add_cleanup(work_tree.lock_tree_write().unlock)
909
959
                    self.outf.write("%s => %s\n" % (src, dest))
910
960
        else:
911
961
            if len(names_list) != 2:
912
 
                raise errors.BzrCommandError('to mv multiple files the'
 
962
                raise errors.BzrCommandError(gettext('to mv multiple files the'
913
963
                                             ' destination must be a versioned'
914
 
                                             ' directory')
 
964
                                             ' directory'))
915
965
 
916
966
            # for cicp file-systems: the src references an existing inventory
917
967
            # item:
981
1031
    location to use the default.  To change the default, use --remember. The
982
1032
    value will only be saved if the remote location can be accessed.
983
1033
 
 
1034
    The --verbose option will display the revisions pulled using the log_format
 
1035
    configuration option. You can use a different format by overriding it with
 
1036
    -Olog_format=<other_format>.
 
1037
 
984
1038
    Note: The location can be specified either in the form of a branch,
985
1039
    or in the form of a path to a file containing a merge directive generated
986
1040
    with bzr send.
1023
1077
            self.add_cleanup(branch_to.lock_write().unlock)
1024
1078
 
1025
1079
        if tree_to is None and show_base:
1026
 
            raise errors.BzrCommandError("Need working tree for --show-base.")
 
1080
            raise errors.BzrCommandError(gettext("Need working tree for --show-base."))
1027
1081
 
1028
1082
        if local and not branch_to.get_bound_location():
1029
1083
            raise errors.LocalRequiresBoundBranch()
1039
1093
        stored_loc = branch_to.get_parent()
1040
1094
        if location is None:
1041
1095
            if stored_loc is None:
1042
 
                raise errors.BzrCommandError("No pull location known or"
1043
 
                                             " specified.")
 
1096
                raise errors.BzrCommandError(gettext("No pull location known or"
 
1097
                                             " specified."))
1044
1098
            else:
1045
1099
                display_url = urlutils.unescape_for_display(stored_loc,
1046
1100
                        self.outf.encoding)
1047
1101
                if not is_quiet():
1048
 
                    self.outf.write("Using saved parent location: %s\n" % display_url)
 
1102
                    self.outf.write(gettext("Using saved parent location: %s\n") % display_url)
1049
1103
                location = stored_loc
1050
1104
 
1051
1105
        revision = _get_one_revision('pull', revision)
1052
1106
        if mergeable is not None:
1053
1107
            if revision is not None:
1054
 
                raise errors.BzrCommandError(
1055
 
                    'Cannot use -r with merge directives or bundles')
 
1108
                raise errors.BzrCommandError(gettext(
 
1109
                    'Cannot use -r with merge directives or bundles'))
1056
1110
            mergeable.install_revisions(branch_to.repository)
1057
1111
            base_revision_id, revision_id, verified = \
1058
1112
                mergeable.get_merge_request(branch_to.repository)
1116
1170
    --no-remember to avoid setting it).  After that, you can omit the
1117
1171
    location to use the default.  To change the default, use --remember. The
1118
1172
    value will only be saved if the remote location can be accessed.
 
1173
 
 
1174
    The --verbose option will display the revisions pushed using the log_format
 
1175
    configuration option. You can use a different format by overriding it with
 
1176
    -Olog_format=<other_format>.
1119
1177
    """
1120
1178
 
1121
1179
    _see_also = ['pull', 'update', 'working-trees']
1159
1217
            directory = '.'
1160
1218
        # Get the source branch
1161
1219
        (tree, br_from,
1162
 
         _unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
 
1220
         _unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
1163
1221
        # Get the tip's revision_id
1164
1222
        revision = _get_one_revision('push', revision)
1165
1223
        if revision is not None:
1186
1244
                    # error by the feedback given to them. RBC 20080227.
1187
1245
                    stacked_on = parent_url
1188
1246
            if not stacked_on:
1189
 
                raise errors.BzrCommandError(
1190
 
                    "Could not determine branch to refer to.")
 
1247
                raise errors.BzrCommandError(gettext(
 
1248
                    "Could not determine branch to refer to."))
1191
1249
 
1192
1250
        # Get the destination location
1193
1251
        if location is None:
1194
1252
            stored_loc = br_from.get_push_location()
1195
1253
            if stored_loc is None:
1196
 
                raise errors.BzrCommandError(
1197
 
                    "No push location known or specified.")
 
1254
                parent_loc = br_from.get_parent()
 
1255
                if parent_loc:
 
1256
                    raise errors.BzrCommandError(gettext(
 
1257
                        "No push location known or specified. To push to the "
 
1258
                        "parent branch (at %s), use 'bzr push :parent'." %
 
1259
                        urlutils.unescape_for_display(parent_loc,
 
1260
                            self.outf.encoding)))
 
1261
                else:
 
1262
                    raise errors.BzrCommandError(gettext(
 
1263
                        "No push location known or specified."))
1198
1264
            else:
1199
1265
                display_url = urlutils.unescape_for_display(stored_loc,
1200
1266
                        self.outf.encoding)
1201
 
                note("Using saved push location: %s" % display_url)
 
1267
                note(gettext("Using saved push location: %s") % display_url)
1202
1268
                location = stored_loc
1203
1269
 
1204
1270
        _show_push_branch(br_from, revision_id, location, self.outf,
1262
1328
                deprecated_name=self.invoked_as,
1263
1329
                recommended_name='branch',
1264
1330
                deprecated_in_version='2.4')
1265
 
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
 
1331
        accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1266
1332
            from_location)
1267
1333
        if not (hardlink or files_from):
1268
1334
            # accelerator_tree is usually slower because you have to read N
1281
1347
            # RBC 20060209
1282
1348
            revision_id = br_from.last_revision()
1283
1349
        if to_location is None:
1284
 
            to_location = urlutils.derive_to_location(from_location)
 
1350
            to_location = getattr(br_from, "name", None)
 
1351
            if to_location is None:
 
1352
                to_location = urlutils.derive_to_location(from_location)
1285
1353
        to_transport = transport.get_transport(to_location)
1286
1354
        try:
1287
1355
            to_transport.mkdir('.')
1288
1356
        except errors.FileExists:
1289
 
            if not use_existing_dir:
1290
 
                raise errors.BzrCommandError('Target directory "%s" '
1291
 
                    'already exists.' % to_location)
 
1357
            try:
 
1358
                to_dir = controldir.ControlDir.open_from_transport(
 
1359
                    to_transport)
 
1360
            except errors.NotBranchError:
 
1361
                if not use_existing_dir:
 
1362
                    raise errors.BzrCommandError(gettext('Target directory "%s" '
 
1363
                        'already exists.') % to_location)
 
1364
                else:
 
1365
                    to_dir = None
1292
1366
            else:
1293
1367
                try:
1294
 
                    bzrdir.BzrDir.open_from_transport(to_transport)
 
1368
                    to_dir.open_branch()
1295
1369
                except errors.NotBranchError:
1296
1370
                    pass
1297
1371
                else:
1298
1372
                    raise errors.AlreadyBranchError(to_location)
1299
1373
        except errors.NoSuchFile:
1300
 
            raise errors.BzrCommandError('Parent of "%s" does not exist.'
 
1374
            raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1301
1375
                                         % to_location)
1302
 
        try:
1303
 
            # preserve whatever source format we have.
1304
 
            dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1305
 
                                        possible_transports=[to_transport],
1306
 
                                        accelerator_tree=accelerator_tree,
1307
 
                                        hardlink=hardlink, stacked=stacked,
1308
 
                                        force_new_repo=standalone,
1309
 
                                        create_tree_if_local=not no_tree,
1310
 
                                        source_branch=br_from)
1311
 
            branch = dir.open_branch()
1312
 
        except errors.NoSuchRevision:
1313
 
            to_transport.delete_tree('.')
1314
 
            msg = "The branch %s has no revision %s." % (from_location,
1315
 
                revision)
1316
 
            raise errors.BzrCommandError(msg)
 
1376
        else:
 
1377
            to_dir = None
 
1378
        if to_dir is None:
 
1379
            try:
 
1380
                # preserve whatever source format we have.
 
1381
                to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
 
1382
                                            possible_transports=[to_transport],
 
1383
                                            accelerator_tree=accelerator_tree,
 
1384
                                            hardlink=hardlink, stacked=stacked,
 
1385
                                            force_new_repo=standalone,
 
1386
                                            create_tree_if_local=not no_tree,
 
1387
                                            source_branch=br_from)
 
1388
                branch = to_dir.open_branch(
 
1389
                    possible_transports=[
 
1390
                        br_from.bzrdir.root_transport, to_transport])
 
1391
            except errors.NoSuchRevision:
 
1392
                to_transport.delete_tree('.')
 
1393
                msg = gettext("The branch {0} has no revision {1}.").format(
 
1394
                    from_location, revision)
 
1395
                raise errors.BzrCommandError(msg)
 
1396
        else:
 
1397
            branch = br_from.sprout(to_dir, revision_id=revision_id)
1317
1398
        _merge_tags_if_possible(br_from, branch)
1318
1399
        # If the source branch is stacked, the new branch may
1319
1400
        # be stacked whether we asked for that explicitly or not.
1320
1401
        # We therefore need a try/except here and not just 'if stacked:'
1321
1402
        try:
1322
 
            note('Created new stacked branch referring to %s.' %
 
1403
            note(gettext('Created new stacked branch referring to %s.') %
1323
1404
                branch.get_stacked_on_url())
1324
1405
        except (errors.NotStacked, errors.UnstackableBranchFormat,
1325
1406
            errors.UnstackableRepositoryFormat), e:
1326
 
            note('Branched %d revision(s).' % branch.revno())
 
1407
            note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1327
1408
        if bind:
1328
1409
            # Bind to the parent
1329
1410
            parent_branch = Branch.open(from_location)
1330
1411
            branch.bind(parent_branch)
1331
 
            note('New branch bound to %s' % from_location)
 
1412
            note(gettext('New branch bound to %s') % from_location)
1332
1413
        if switch:
1333
1414
            # Switch to the new branch
1334
1415
            wt, _ = WorkingTree.open_containing('.')
1335
1416
            _mod_switch.switch(wt.bzrdir, branch)
1336
 
            note('Switched to branch: %s',
 
1417
            note(gettext('Switched to branch: %s'),
1337
1418
                urlutils.unescape_for_display(branch.base, 'utf-8'))
1338
1419
 
1339
1420
 
1340
1421
class cmd_branches(Command):
1341
1422
    __doc__ = """List the branches available at the current location.
1342
1423
 
1343
 
    This command will print the names of all the branches at the current location.
 
1424
    This command will print the names of all the branches at the current
 
1425
    location.
1344
1426
    """
1345
1427
 
1346
1428
    takes_args = ['location?']
 
1429
    takes_options = [
 
1430
                  Option('recursive', short_name='R',
 
1431
                         help='Recursively scan for branches rather than '
 
1432
                              'just looking in the specified location.')]
1347
1433
 
1348
 
    def run(self, location="."):
1349
 
        dir = bzrdir.BzrDir.open_containing(location)[0]
1350
 
        for branch in dir.list_branches():
1351
 
            if branch.name is None:
1352
 
                self.outf.write(" (default)\n")
1353
 
            else:
1354
 
                self.outf.write(" %s\n" % branch.name.encode(self.outf.encoding))
 
1434
    def run(self, location=".", recursive=False):
 
1435
        if recursive:
 
1436
            t = transport.get_transport(location)
 
1437
            if not t.listable():
 
1438
                raise errors.BzrCommandError(
 
1439
                    "Can't scan this type of location.")
 
1440
            for b in controldir.ControlDir.find_branches(t):
 
1441
                self.outf.write("%s\n" % urlutils.unescape_for_display(
 
1442
                    urlutils.relative_url(t.base, b.base),
 
1443
                    self.outf.encoding).rstrip("/"))
 
1444
        else:
 
1445
            dir = controldir.ControlDir.open_containing(location)[0]
 
1446
            try:
 
1447
                active_branch = dir.open_branch(name=None)
 
1448
            except errors.NotBranchError:
 
1449
                active_branch = None
 
1450
            branches = dir.get_branches()
 
1451
            names = {}
 
1452
            for name, branch in branches.iteritems():
 
1453
                if name is None:
 
1454
                    continue
 
1455
                active = (active_branch is not None and
 
1456
                          active_branch.base == branch.base)
 
1457
                names[name] = active
 
1458
            # Only mention the current branch explicitly if it's not
 
1459
            # one of the colocated branches
 
1460
            if not any(names.values()) and active_branch is not None:
 
1461
                self.outf.write("* %s\n" % gettext("(default)"))
 
1462
            for name in sorted(names.keys()):
 
1463
                active = names[name]
 
1464
                if active:
 
1465
                    prefix = "*"
 
1466
                else:
 
1467
                    prefix = " "
 
1468
                self.outf.write("%s %s\n" % (
 
1469
                    prefix, name.encode(self.outf.encoding)))
1355
1470
 
1356
1471
 
1357
1472
class cmd_checkout(Command):
1398
1513
        if branch_location is None:
1399
1514
            branch_location = osutils.getcwd()
1400
1515
            to_location = branch_location
1401
 
        accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
 
1516
        accelerator_tree, source = controldir.ControlDir.open_tree_or_branch(
1402
1517
            branch_location)
1403
1518
        if not (hardlink or files_from):
1404
1519
            # accelerator_tree is usually slower because you have to read N
1459
1574
 
1460
1575
 
1461
1576
class cmd_update(Command):
1462
 
    __doc__ = """Update a tree to have the latest code committed to its branch.
1463
 
 
1464
 
    This will perform a merge into the working tree, and may generate
1465
 
    conflicts. If you have any local changes, you will still
1466
 
    need to commit them after the update for the update to be complete.
1467
 
 
1468
 
    If you want to discard your local changes, you can just do a
1469
 
    'bzr revert' instead of 'bzr commit' after the update.
1470
 
 
1471
 
    If you want to restore a file that has been removed locally, use
1472
 
    'bzr revert' instead of 'bzr update'.
1473
 
 
1474
 
    If the tree's branch is bound to a master branch, it will also update
 
1577
    __doc__ = """Update a working tree to a new revision.
 
1578
 
 
1579
    This will perform a merge of the destination revision (the tip of the
 
1580
    branch, or the specified revision) into the working tree, and then make
 
1581
    that revision the basis revision for the working tree.  
 
1582
 
 
1583
    You can use this to visit an older revision, or to update a working tree
 
1584
    that is out of date from its branch.
 
1585
    
 
1586
    If there are any uncommitted changes in the tree, they will be carried
 
1587
    across and remain as uncommitted changes after the update.  To discard
 
1588
    these changes, use 'bzr revert'.  The uncommitted changes may conflict
 
1589
    with the changes brought in by the change in basis revision.
 
1590
 
 
1591
    If the tree's branch is bound to a master branch, bzr will also update
1475
1592
    the branch from the master.
 
1593
 
 
1594
    You cannot update just a single file or directory, because each Bazaar
 
1595
    working tree has just a single basis revision.  If you want to restore a
 
1596
    file that has been removed locally, use 'bzr revert' instead of 'bzr
 
1597
    update'.  If you want to restore a file to its state in a previous
 
1598
    revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
 
1599
    out the old content of that file to a new location.
 
1600
 
 
1601
    The 'dir' argument, if given, must be the location of the root of a
 
1602
    working tree to update.  By default, the working tree that contains the 
 
1603
    current working directory is used.
1476
1604
    """
1477
1605
 
1478
1606
    _see_also = ['pull', 'working-trees', 'status-flags']
1483
1611
                     ]
1484
1612
    aliases = ['up']
1485
1613
 
1486
 
    def run(self, dir='.', revision=None, show_base=None):
 
1614
    def run(self, dir=None, revision=None, show_base=None):
1487
1615
        if revision is not None and len(revision) != 1:
1488
 
            raise errors.BzrCommandError(
1489
 
                        "bzr update --revision takes exactly one revision")
1490
 
        tree = WorkingTree.open_containing(dir)[0]
 
1616
            raise errors.BzrCommandError(gettext(
 
1617
                "bzr update --revision takes exactly one revision"))
 
1618
        if dir is None:
 
1619
            tree = WorkingTree.open_containing('.')[0]
 
1620
        else:
 
1621
            tree, relpath = WorkingTree.open_containing(dir)
 
1622
            if relpath:
 
1623
                # See bug 557886.
 
1624
                raise errors.BzrCommandError(gettext(
 
1625
                    "bzr update can only update a whole tree, "
 
1626
                    "not a file or subdirectory"))
1491
1627
        branch = tree.branch
1492
1628
        possible_transports = []
1493
1629
        master = branch.get_master_branch(
1517
1653
            revision_id = branch.last_revision()
1518
1654
        if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1519
1655
            revno = branch.revision_id_to_dotted_revno(revision_id)
1520
 
            note("Tree is up to date at revision %s of branch %s" %
1521
 
                ('.'.join(map(str, revno)), branch_location))
 
1656
            note(gettext("Tree is up to date at revision {0} of branch {1}"
 
1657
                        ).format('.'.join(map(str, revno)), branch_location))
1522
1658
            return 0
1523
1659
        view_info = _get_view_info_for_change_reporter(tree)
1524
1660
        change_reporter = delta._ChangeReporter(
1532
1668
                old_tip=old_tip,
1533
1669
                show_base=show_base)
1534
1670
        except errors.NoSuchRevision, e:
1535
 
            raise errors.BzrCommandError(
 
1671
            raise errors.BzrCommandError(gettext(
1536
1672
                                  "branch has no revision %s\n"
1537
1673
                                  "bzr update --revision only works"
1538
 
                                  " for a revision in the branch history"
 
1674
                                  " for a revision in the branch history")
1539
1675
                                  % (e.revision))
1540
1676
        revno = tree.branch.revision_id_to_dotted_revno(
1541
1677
            _mod_revision.ensure_null(tree.last_revision()))
1542
 
        note('Updated to revision %s of branch %s' %
1543
 
             ('.'.join(map(str, revno)), branch_location))
 
1678
        note(gettext('Updated to revision {0} of branch {1}').format(
 
1679
             '.'.join(map(str, revno)), branch_location))
1544
1680
        parent_ids = tree.get_parent_ids()
1545
1681
        if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1546
 
            note('Your local commits will now show as pending merges with '
1547
 
                 "'bzr status', and can be committed with 'bzr commit'.")
 
1682
            note(gettext('Your local commits will now show as pending merges with '
 
1683
                 "'bzr status', and can be committed with 'bzr commit'."))
1548
1684
        if conflicts != 0:
1549
1685
            return 1
1550
1686
        else:
1591
1727
        else:
1592
1728
            noise_level = 0
1593
1729
        from bzrlib.info import show_bzrdir_info
1594
 
        show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
 
1730
        show_bzrdir_info(controldir.ControlDir.open_containing(location)[0],
1595
1731
                         verbose=noise_level, outfile=self.outf)
1596
1732
 
1597
1733
 
1622
1758
    def run(self, file_list, verbose=False, new=False,
1623
1759
        file_deletion_strategy='safe'):
1624
1760
        if file_deletion_strategy == 'force':
1625
 
            note("(The --force option is deprecated, rather use --no-backup "
1626
 
                "in future.)")
 
1761
            note(gettext("(The --force option is deprecated, rather use --no-backup "
 
1762
                "in future.)"))
1627
1763
            file_deletion_strategy = 'no-backup'
1628
1764
 
1629
1765
        tree, file_list = WorkingTree.open_containing_paths(file_list)
1639
1775
                specific_files=file_list).added
1640
1776
            file_list = sorted([f[0] for f in added], reverse=True)
1641
1777
            if len(file_list) == 0:
1642
 
                raise errors.BzrCommandError('No matching files.')
 
1778
                raise errors.BzrCommandError(gettext('No matching files.'))
1643
1779
        elif file_list is None:
1644
1780
            # missing files show up in iter_changes(basis) as
1645
1781
            # versioned-with-no-kind.
1729
1865
 
1730
1866
    def run(self, branch=".", canonicalize_chks=False):
1731
1867
        from bzrlib.reconcile import reconcile
1732
 
        dir = bzrdir.BzrDir.open(branch)
 
1868
        dir = controldir.ControlDir.open(branch)
1733
1869
        reconcile(dir, canonicalize_chks=canonicalize_chks)
1734
1870
 
1735
1871
 
1744
1880
    @display_command
1745
1881
    def run(self, location="."):
1746
1882
        branch = Branch.open_containing(location)[0]
1747
 
        for revid in branch.revision_history():
 
1883
        self.add_cleanup(branch.lock_read().unlock)
 
1884
        graph = branch.repository.get_graph()
 
1885
        history = list(graph.iter_lefthand_ancestry(branch.last_revision(),
 
1886
            [_mod_revision.NULL_REVISION]))
 
1887
        for revid in reversed(history):
1748
1888
            self.outf.write(revid)
1749
1889
            self.outf.write('\n')
1750
1890
 
1811
1951
                help='Specify a format for this branch. '
1812
1952
                'See "help formats".',
1813
1953
                lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1814
 
                converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
1954
                converter=lambda name: controldir.format_registry.make_bzrdir(name),
1815
1955
                value_switches=True,
1816
1956
                title="Branch format",
1817
1957
                ),
1824
1964
    def run(self, location=None, format=None, append_revisions_only=False,
1825
1965
            create_prefix=False, no_tree=False):
1826
1966
        if format is None:
1827
 
            format = bzrdir.format_registry.make_bzrdir('default')
 
1967
            format = controldir.format_registry.make_bzrdir('default')
1828
1968
        if location is None:
1829
1969
            location = u'.'
1830
1970
 
1839
1979
            to_transport.ensure_base()
1840
1980
        except errors.NoSuchFile:
1841
1981
            if not create_prefix:
1842
 
                raise errors.BzrCommandError("Parent directory of %s"
 
1982
                raise errors.BzrCommandError(gettext("Parent directory of %s"
1843
1983
                    " does not exist."
1844
1984
                    "\nYou may supply --create-prefix to create all"
1845
 
                    " leading parent directories."
 
1985
                    " leading parent directories.")
1846
1986
                    % location)
1847
1987
            to_transport.create_prefix()
1848
1988
 
1849
1989
        try:
1850
 
            a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
 
1990
            a_bzrdir = controldir.ControlDir.open_from_transport(to_transport)
1851
1991
        except errors.NotBranchError:
1852
1992
            # really a NotBzrDir error...
1853
 
            create_branch = bzrdir.BzrDir.create_branch_convenience
 
1993
            create_branch = controldir.ControlDir.create_branch_convenience
1854
1994
            if no_tree:
1855
1995
                force_new_tree = False
1856
1996
            else:
1867
2007
                        raise errors.BranchExistsWithoutWorkingTree(location)
1868
2008
                raise errors.AlreadyBranchError(location)
1869
2009
            branch = a_bzrdir.create_branch()
1870
 
            if not no_tree:
 
2010
            if not no_tree and not a_bzrdir.has_workingtree():
1871
2011
                a_bzrdir.create_workingtree()
1872
2012
        if append_revisions_only:
1873
2013
            try:
1874
2014
                branch.set_append_revisions_only(True)
1875
2015
            except errors.UpgradeRequired:
1876
 
                raise errors.BzrCommandError('This branch format cannot be set'
1877
 
                    ' to append-revisions-only.  Try --default.')
 
2016
                raise errors.BzrCommandError(gettext('This branch format cannot be set'
 
2017
                    ' to append-revisions-only.  Try --default.'))
1878
2018
        if not is_quiet():
1879
2019
            from bzrlib.info import describe_layout, describe_format
1880
2020
            try:
1884
2024
            repository = branch.repository
1885
2025
            layout = describe_layout(repository, branch, tree).lower()
1886
2026
            format = describe_format(a_bzrdir, repository, branch, tree)
1887
 
            self.outf.write("Created a %s (format: %s)\n" % (layout, format))
 
2027
            self.outf.write(gettext("Created a {0} (format: {1})\n").format(
 
2028
                  layout, format))
1888
2029
            if repository.is_shared():
1889
2030
                #XXX: maybe this can be refactored into transport.path_or_url()
1890
2031
                url = repository.bzrdir.root_transport.external_url()
1892
2033
                    url = urlutils.local_path_from_url(url)
1893
2034
                except errors.InvalidURL:
1894
2035
                    pass
1895
 
                self.outf.write("Using shared repository: %s\n" % url)
 
2036
                self.outf.write(gettext("Using shared repository: %s\n") % url)
1896
2037
 
1897
2038
 
1898
2039
class cmd_init_repository(Command):
1928
2069
    takes_options = [RegistryOption('format',
1929
2070
                            help='Specify a format for this repository. See'
1930
2071
                                 ' "bzr help formats" for details.',
1931
 
                            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1932
 
                            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
2072
                            lazy_registry=('bzrlib.controldir', 'format_registry'),
 
2073
                            converter=lambda name: controldir.format_registry.make_bzrdir(name),
1933
2074
                            value_switches=True, title='Repository format'),
1934
2075
                     Option('no-trees',
1935
2076
                             help='Branches in the repository will default to'
1939
2080
 
1940
2081
    def run(self, location, format=None, no_trees=False):
1941
2082
        if format is None:
1942
 
            format = bzrdir.format_registry.make_bzrdir('default')
 
2083
            format = controldir.format_registry.make_bzrdir('default')
1943
2084
 
1944
2085
        if location is None:
1945
2086
            location = '.'
1946
2087
 
1947
2088
        to_transport = transport.get_transport(location)
1948
 
        to_transport.ensure_base()
1949
2089
 
1950
 
        newdir = format.initialize_on_transport(to_transport)
1951
 
        repo = newdir.create_repository(shared=True)
1952
 
        repo.set_make_working_trees(not no_trees)
 
2090
        (repo, newdir, require_stacking, repository_policy) = (
 
2091
            format.initialize_on_transport_ex(to_transport,
 
2092
            create_prefix=True, make_working_trees=not no_trees,
 
2093
            shared_repo=True, force_new_repo=True,
 
2094
            use_existing_dir=True,
 
2095
            repo_format_name=format.repository_format.get_format_string()))
1953
2096
        if not is_quiet():
1954
2097
            from bzrlib.info import show_bzrdir_info
1955
 
            show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
 
2098
            show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
1956
2099
 
1957
2100
 
1958
2101
class cmd_diff(Command):
2089
2232
        elif ':' in prefix:
2090
2233
            old_label, new_label = prefix.split(":")
2091
2234
        else:
2092
 
            raise errors.BzrCommandError(
 
2235
            raise errors.BzrCommandError(gettext(
2093
2236
                '--prefix expects two values separated by a colon'
2094
 
                ' (eg "old/:new/")')
 
2237
                ' (eg "old/:new/")'))
2095
2238
 
2096
2239
        if revision and len(revision) > 2:
2097
 
            raise errors.BzrCommandError('bzr diff --revision takes exactly'
2098
 
                                         ' one or two revision specifiers')
 
2240
            raise errors.BzrCommandError(gettext('bzr diff --revision takes exactly'
 
2241
                                         ' one or two revision specifiers'))
2099
2242
 
2100
2243
        if using is not None and format is not None:
2101
 
            raise errors.BzrCommandError('--using and --format are mutually '
2102
 
                'exclusive.')
 
2244
            raise errors.BzrCommandError(gettext(
 
2245
                '{0} and {1} are mutually exclusive').format(
 
2246
                '--using', '--format'))
2103
2247
 
2104
2248
        (old_tree, new_tree,
2105
2249
         old_branch, new_branch,
2213
2357
    try:
2214
2358
        return int(limitstring)
2215
2359
    except ValueError:
2216
 
        msg = "The limit argument must be an integer."
 
2360
        msg = gettext("The limit argument must be an integer.")
2217
2361
        raise errors.BzrCommandError(msg)
2218
2362
 
2219
2363
 
2221
2365
    try:
2222
2366
        return int(s)
2223
2367
    except ValueError:
2224
 
        msg = "The levels argument must be an integer."
 
2368
        msg = gettext("The levels argument must be an integer.")
2225
2369
        raise errors.BzrCommandError(msg)
2226
2370
 
2227
2371
 
2419
2563
            Option('show-diff',
2420
2564
                   short_name='p',
2421
2565
                   help='Show changes made in each revision as a patch.'),
2422
 
            Option('include-merges',
 
2566
            Option('include-merged',
2423
2567
                   help='Show merged revisions like --levels 0 does.'),
 
2568
            Option('include-merges', hidden=True,
 
2569
                   help='Historical alias for --include-merged.'),
 
2570
            Option('omit-merges',
 
2571
                   help='Do not report commits with more than one parent.'),
2424
2572
            Option('exclude-common-ancestry',
2425
2573
                   help='Display only the revisions that are not part'
2426
 
                   ' of both ancestries (require -rX..Y)'
 
2574
                   ' of both ancestries (require -rX..Y).'
2427
2575
                   ),
2428
2576
            Option('signatures',
2429
 
                   help='Show digital signature validity'),
 
2577
                   help='Show digital signature validity.'),
2430
2578
            ListOption('match',
2431
2579
                short_name='m',
2432
2580
                help='Show revisions whose properties match this '
2463
2611
            message=None,
2464
2612
            limit=None,
2465
2613
            show_diff=False,
2466
 
            include_merges=False,
 
2614
            include_merged=None,
2467
2615
            authors=None,
2468
2616
            exclude_common_ancestry=False,
2469
2617
            signatures=False,
2472
2620
            match_committer=None,
2473
2621
            match_author=None,
2474
2622
            match_bugs=None,
 
2623
            omit_merges=False,
 
2624
            include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2475
2625
            ):
2476
2626
        from bzrlib.log import (
2477
2627
            Logger,
2479
2629
            _get_info_for_log_files,
2480
2630
            )
2481
2631
        direction = (forward and 'forward') or 'reverse'
 
2632
        if symbol_versioning.deprecated_passed(include_merges):
 
2633
            ui.ui_factory.show_user_warning(
 
2634
                'deprecated_command_option',
 
2635
                deprecated_name='--include-merges',
 
2636
                recommended_name='--include-merged',
 
2637
                deprecated_in_version='2.5',
 
2638
                command=self.invoked_as)
 
2639
            if include_merged is None:
 
2640
                include_merged = include_merges
 
2641
            else:
 
2642
                raise errors.BzrCommandError(gettext(
 
2643
                    '{0} and {1} are mutually exclusive').format(
 
2644
                    '--include-merges', '--include-merged'))
 
2645
        if include_merged is None:
 
2646
            include_merged = False
2482
2647
        if (exclude_common_ancestry
2483
2648
            and (revision is None or len(revision) != 2)):
2484
 
            raise errors.BzrCommandError(
2485
 
                '--exclude-common-ancestry requires -r with two revisions')
2486
 
        if include_merges:
 
2649
            raise errors.BzrCommandError(gettext(
 
2650
                '--exclude-common-ancestry requires -r with two revisions'))
 
2651
        if include_merged:
2487
2652
            if levels is None:
2488
2653
                levels = 0
2489
2654
            else:
2490
 
                raise errors.BzrCommandError(
2491
 
                    '--levels and --include-merges are mutually exclusive')
 
2655
                raise errors.BzrCommandError(gettext(
 
2656
                    '{0} and {1} are mutually exclusive').format(
 
2657
                    '--levels', '--include-merged'))
2492
2658
 
2493
2659
        if change is not None:
2494
2660
            if len(change) > 1:
2495
2661
                raise errors.RangeInChangeOption()
2496
2662
            if revision is not None:
2497
 
                raise errors.BzrCommandError(
2498
 
                    '--revision and --change are mutually exclusive')
 
2663
                raise errors.BzrCommandError(gettext(
 
2664
                    '{0} and {1} are mutually exclusive').format(
 
2665
                    '--revision', '--change'))
2499
2666
            else:
2500
2667
                revision = change
2501
2668
 
2507
2674
                revision, file_list, self.add_cleanup)
2508
2675
            for relpath, file_id, kind in file_info_list:
2509
2676
                if file_id is None:
2510
 
                    raise errors.BzrCommandError(
2511
 
                        "Path unknown at end or start of revision range: %s" %
 
2677
                    raise errors.BzrCommandError(gettext(
 
2678
                        "Path unknown at end or start of revision range: %s") %
2512
2679
                        relpath)
2513
2680
                # If the relpath is the top of the tree, we log everything
2514
2681
                if relpath == '':
2526
2693
                location = revision[0].get_branch()
2527
2694
            else:
2528
2695
                location = '.'
2529
 
            dir, relpath = bzrdir.BzrDir.open_containing(location)
 
2696
            dir, relpath = controldir.ControlDir.open_containing(location)
2530
2697
            b = dir.open_branch()
2531
2698
            self.add_cleanup(b.lock_read().unlock)
2532
2699
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2591
2758
            match_dict['author'] = match_author
2592
2759
        if match_bugs:
2593
2760
            match_dict['bugs'] = match_bugs
2594
 
            
 
2761
 
2595
2762
        # Build the LogRequest and execute it
2596
2763
        if len(file_ids) == 0:
2597
2764
            file_ids = None
2601
2768
            message_search=message, delta_type=delta_type,
2602
2769
            diff_type=diff_type, _match_using_deltas=match_using_deltas,
2603
2770
            exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
2604
 
            signature=signatures
 
2771
            signature=signatures, omit_merges=omit_merges,
2605
2772
            )
2606
2773
        Logger(b, rqst).show(lf)
2607
2774
 
2624
2791
            # b is taken from revision[0].get_branch(), and
2625
2792
            # show_log will use its revision_history. Having
2626
2793
            # different branches will lead to weird behaviors.
2627
 
            raise errors.BzrCommandError(
 
2794
            raise errors.BzrCommandError(gettext(
2628
2795
                "bzr %s doesn't accept two revisions in different"
2629
 
                " branches." % command_name)
 
2796
                " branches.") % command_name)
2630
2797
        if start_spec.spec is None:
2631
2798
            # Avoid loading all the history.
2632
2799
            rev1 = RevisionInfo(branch, None, None)
2640
2807
        else:
2641
2808
            rev2 = end_spec.in_history(branch)
2642
2809
    else:
2643
 
        raise errors.BzrCommandError(
2644
 
            'bzr %s --revision takes one or two values.' % command_name)
 
2810
        raise errors.BzrCommandError(gettext(
 
2811
            'bzr %s --revision takes one or two values.') % command_name)
2645
2812
    return rev1, rev2
2646
2813
 
2647
2814
 
2718
2885
            null=False, kind=None, show_ids=False, path=None, directory=None):
2719
2886
 
2720
2887
        if kind and kind not in ('file', 'directory', 'symlink'):
2721
 
            raise errors.BzrCommandError('invalid kind specified')
 
2888
            raise errors.BzrCommandError(gettext('invalid kind specified'))
2722
2889
 
2723
2890
        if verbose and null:
2724
 
            raise errors.BzrCommandError('Cannot set both --verbose and --null')
 
2891
            raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
2725
2892
        all = not (unknown or versioned or ignored)
2726
2893
 
2727
2894
        selection = {'I':ignored, '?':unknown, 'V':versioned}
2730
2897
            fs_path = '.'
2731
2898
        else:
2732
2899
            if from_root:
2733
 
                raise errors.BzrCommandError('cannot specify both --from-root'
2734
 
                                             ' and PATH')
 
2900
                raise errors.BzrCommandError(gettext('cannot specify both --from-root'
 
2901
                                             ' and PATH'))
2735
2902
            fs_path = path
2736
2903
        tree, branch, relpath = \
2737
2904
            _open_directory_or_containing_tree_or_branch(fs_path, directory)
2753
2920
            if view_files:
2754
2921
                apply_view = True
2755
2922
                view_str = views.view_display_str(view_files)
2756
 
                note("Ignoring files outside view. View is %s" % view_str)
 
2923
                note(gettext("Ignoring files outside view. View is %s") % view_str)
2757
2924
 
2758
2925
        self.add_cleanup(tree.lock_read().unlock)
2759
2926
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2906
3073
                self.outf.write("%s\n" % pattern)
2907
3074
            return
2908
3075
        if not name_pattern_list:
2909
 
            raise errors.BzrCommandError("ignore requires at least one "
2910
 
                "NAME_PATTERN or --default-rules.")
 
3076
            raise errors.BzrCommandError(gettext("ignore requires at least one "
 
3077
                "NAME_PATTERN or --default-rules."))
2911
3078
        name_pattern_list = [globbing.normalize_pattern(p)
2912
3079
                             for p in name_pattern_list]
2913
3080
        bad_patterns = ''
 
3081
        bad_patterns_count = 0
2914
3082
        for p in name_pattern_list:
2915
3083
            if not globbing.Globster.is_pattern_valid(p):
 
3084
                bad_patterns_count += 1
2916
3085
                bad_patterns += ('\n  %s' % p)
2917
3086
        if bad_patterns:
2918
 
            msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
 
3087
            msg = (ngettext('Invalid ignore pattern found. %s', 
 
3088
                            'Invalid ignore patterns found. %s',
 
3089
                            bad_patterns_count) % bad_patterns)
2919
3090
            ui.ui_factory.show_error(msg)
2920
3091
            raise errors.InvalidPattern('')
2921
3092
        for name_pattern in name_pattern_list:
2922
3093
            if (name_pattern[0] == '/' or
2923
3094
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
2924
 
                raise errors.BzrCommandError(
2925
 
                    "NAME_PATTERN should not be an absolute path")
 
3095
                raise errors.BzrCommandError(gettext(
 
3096
                    "NAME_PATTERN should not be an absolute path"))
2926
3097
        tree, relpath = WorkingTree.open_containing(directory)
2927
3098
        ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2928
3099
        ignored = globbing.Globster(name_pattern_list)
2935
3106
                if ignored.match(filename):
2936
3107
                    matches.append(filename)
2937
3108
        if len(matches) > 0:
2938
 
            self.outf.write("Warning: the following files are version controlled and"
2939
 
                  " match your ignore pattern:\n%s"
 
3109
            self.outf.write(gettext("Warning: the following files are version "
 
3110
                  "controlled and match your ignore pattern:\n%s"
2940
3111
                  "\nThese files will continue to be version controlled"
2941
 
                  " unless you 'bzr remove' them.\n" % ("\n".join(matches),))
 
3112
                  " unless you 'bzr remove' them.\n") % ("\n".join(matches),))
2942
3113
 
2943
3114
 
2944
3115
class cmd_ignored(Command):
2983
3154
        try:
2984
3155
            revno = int(revno)
2985
3156
        except ValueError:
2986
 
            raise errors.BzrCommandError("not a valid revision-number: %r"
 
3157
            raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
2987
3158
                                         % revno)
2988
3159
        revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2989
3160
        self.outf.write("%s\n" % revid)
3032
3203
        Option('per-file-timestamps',
3033
3204
               help='Set modification time of files to that of the last '
3034
3205
                    'revision in which it was changed.'),
 
3206
        Option('uncommitted',
 
3207
               help='Export the working tree contents rather than that of the '
 
3208
                    'last revision.'),
3035
3209
        ]
3036
3210
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3037
 
        root=None, filters=False, per_file_timestamps=False, directory=u'.'):
 
3211
        root=None, filters=False, per_file_timestamps=False, uncommitted=False,
 
3212
        directory=u'.'):
3038
3213
        from bzrlib.export import export
3039
3214
 
3040
3215
        if branch_or_subdir is None:
3041
 
            tree = WorkingTree.open_containing(directory)[0]
3042
 
            b = tree.branch
3043
 
            subdir = None
 
3216
            branch_or_subdir = directory
 
3217
 
 
3218
        (tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
 
3219
            branch_or_subdir)
 
3220
        if tree is not None:
 
3221
            self.add_cleanup(tree.lock_read().unlock)
 
3222
 
 
3223
        if uncommitted:
 
3224
            if tree is None:
 
3225
                raise errors.BzrCommandError(
 
3226
                    gettext("--uncommitted requires a working tree"))
 
3227
            export_tree = tree
3044
3228
        else:
3045
 
            b, subdir = Branch.open_containing(branch_or_subdir)
3046
 
            tree = None
3047
 
 
3048
 
        rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
 
3229
            export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3049
3230
        try:
3050
 
            export(rev_tree, dest, format, root, subdir, filtered=filters,
 
3231
            export(export_tree, dest, format, root, subdir, filtered=filters,
3051
3232
                   per_file_timestamps=per_file_timestamps)
3052
3233
        except errors.NoSuchExportFormat, e:
3053
 
            raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
 
3234
            raise errors.BzrCommandError(
 
3235
                gettext('Unsupported export format: %s') % e.format)
3054
3236
 
3055
3237
 
3056
3238
class cmd_cat(Command):
3076
3258
    def run(self, filename, revision=None, name_from_revision=False,
3077
3259
            filters=False, directory=None):
3078
3260
        if revision is not None and len(revision) != 1:
3079
 
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
3080
 
                                         " one revision specifier")
 
3261
            raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
 
3262
                                         " one revision specifier"))
3081
3263
        tree, branch, relpath = \
3082
3264
            _open_directory_or_containing_tree_or_branch(filename, directory)
3083
3265
        self.add_cleanup(branch.lock_read().unlock)
3100
3282
        if name_from_revision:
3101
3283
            # Try in revision if requested
3102
3284
            if old_file_id is None:
3103
 
                raise errors.BzrCommandError(
3104
 
                    "%r is not present in revision %s" % (
 
3285
                raise errors.BzrCommandError(gettext(
 
3286
                    "{0!r} is not present in revision {1}").format(
3105
3287
                        filename, rev_tree.get_revision_id()))
3106
3288
            else:
3107
3289
                actual_file_id = old_file_id
3112
3294
            elif old_file_id is not None:
3113
3295
                actual_file_id = old_file_id
3114
3296
            else:
3115
 
                raise errors.BzrCommandError(
3116
 
                    "%r is not present in revision %s" % (
 
3297
                raise errors.BzrCommandError(gettext(
 
3298
                    "{0!r} is not present in revision {1}").format(
3117
3299
                        filename, rev_tree.get_revision_id()))
3118
3300
        if filtered:
3119
3301
            from bzrlib.filter_tree import ContentFilterTree
3236
3418
    aliases = ['ci', 'checkin']
3237
3419
 
3238
3420
    def _iter_bug_fix_urls(self, fixes, branch):
 
3421
        default_bugtracker  = None
3239
3422
        # Configure the properties for bug fixing attributes.
3240
3423
        for fixed_bug in fixes:
3241
3424
            tokens = fixed_bug.split(':')
3242
 
            if len(tokens) != 2:
3243
 
                raise errors.BzrCommandError(
 
3425
            if len(tokens) == 1:
 
3426
                if default_bugtracker is None:
 
3427
                    branch_config = branch.get_config()
 
3428
                    default_bugtracker = branch_config.get_user_option(
 
3429
                        "bugtracker")
 
3430
                if default_bugtracker is None:
 
3431
                    raise errors.BzrCommandError(gettext(
 
3432
                        "No tracker specified for bug %s. Use the form "
 
3433
                        "'tracker:id' or specify a default bug tracker "
 
3434
                        "using the `bugtracker` option.\nSee "
 
3435
                        "\"bzr help bugs\" for more information on this "
 
3436
                        "feature. Commit refused.") % fixed_bug)
 
3437
                tag = default_bugtracker
 
3438
                bug_id = tokens[0]
 
3439
            elif len(tokens) != 2:
 
3440
                raise errors.BzrCommandError(gettext(
3244
3441
                    "Invalid bug %s. Must be in the form of 'tracker:id'. "
3245
3442
                    "See \"bzr help bugs\" for more information on this "
3246
 
                    "feature.\nCommit refused." % fixed_bug)
3247
 
            tag, bug_id = tokens
 
3443
                    "feature.\nCommit refused.") % fixed_bug)
 
3444
            else:
 
3445
                tag, bug_id = tokens
3248
3446
            try:
3249
3447
                yield bugtracker.get_bug_url(tag, branch, bug_id)
3250
3448
            except errors.UnknownBugTrackerAbbreviation:
3251
 
                raise errors.BzrCommandError(
3252
 
                    'Unrecognized bug %s. Commit refused.' % fixed_bug)
 
3449
                raise errors.BzrCommandError(gettext(
 
3450
                    'Unrecognized bug %s. Commit refused.') % fixed_bug)
3253
3451
            except errors.MalformedBugIdentifier, e:
3254
 
                raise errors.BzrCommandError(
3255
 
                    "%s\nCommit refused." % (str(e),))
 
3452
                raise errors.BzrCommandError(gettext(
 
3453
                    "%s\nCommit refused.") % (str(e),))
3256
3454
 
3257
3455
    def run(self, message=None, file=None, verbose=False, selected_list=None,
3258
3456
            unchanged=False, strict=False, local=False, fixes=None,
3275
3473
            try:
3276
3474
                commit_stamp, offset = timestamp.parse_patch_date(commit_time)
3277
3475
            except ValueError, e:
3278
 
                raise errors.BzrCommandError(
3279
 
                    "Could not parse --commit-time: " + str(e))
 
3476
                raise errors.BzrCommandError(gettext(
 
3477
                    "Could not parse --commit-time: " + str(e)))
3280
3478
 
3281
3479
        properties = {}
3282
3480
 
3315
3513
                message = message.replace('\r\n', '\n')
3316
3514
                message = message.replace('\r', '\n')
3317
3515
            if file:
3318
 
                raise errors.BzrCommandError(
3319
 
                    "please specify either --message or --file")
 
3516
                raise errors.BzrCommandError(gettext(
 
3517
                    "please specify either --message or --file"))
3320
3518
 
3321
3519
        def get_message(commit_obj):
3322
3520
            """Callback to get commit message"""
3345
3543
                    my_message = edit_commit_message_encoded(text,
3346
3544
                        start_message=start_message)
3347
3545
                if my_message is None:
3348
 
                    raise errors.BzrCommandError("please specify a commit"
3349
 
                        " message with either --message or --file")
 
3546
                    raise errors.BzrCommandError(gettext("please specify a commit"
 
3547
                        " message with either --message or --file"))
3350
3548
                if my_message == "":
3351
 
                    raise errors.BzrCommandError("Empty commit message specified."
 
3549
                    raise errors.BzrCommandError(gettext("Empty commit message specified."
3352
3550
                            " Please specify a commit message with either"
3353
3551
                            " --message or --file or leave a blank message"
3354
 
                            " with --message \"\".")
 
3552
                            " with --message \"\"."))
3355
3553
            return my_message
3356
3554
 
3357
3555
        # The API permits a commit with a filter of [] to mean 'select nothing'
3368
3566
                        exclude=tree.safe_relpath_files(exclude),
3369
3567
                        lossy=lossy)
3370
3568
        except PointlessCommit:
3371
 
            raise errors.BzrCommandError("No changes to commit."
 
3569
            raise errors.BzrCommandError(gettext("No changes to commit."
3372
3570
                " Please 'bzr add' the files you want to commit, or use"
3373
 
                " --unchanged to force an empty commit.")
 
3571
                " --unchanged to force an empty commit."))
3374
3572
        except ConflictsInTree:
3375
 
            raise errors.BzrCommandError('Conflicts detected in working '
 
3573
            raise errors.BzrCommandError(gettext('Conflicts detected in working '
3376
3574
                'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
3377
 
                ' resolve.')
 
3575
                ' resolve.'))
3378
3576
        except StrictCommitFailed:
3379
 
            raise errors.BzrCommandError("Commit refused because there are"
3380
 
                              " unknown files in the working tree.")
 
3577
            raise errors.BzrCommandError(gettext("Commit refused because there are"
 
3578
                              " unknown files in the working tree."))
3381
3579
        except errors.BoundBranchOutOfDate, e:
3382
 
            e.extra_help = ("\n"
 
3580
            e.extra_help = (gettext("\n"
3383
3581
                'To commit to master branch, run update and then commit.\n'
3384
3582
                'You can also pass --local to commit to continue working '
3385
 
                'disconnected.')
 
3583
                'disconnected.'))
3386
3584
            raise
3387
3585
 
3388
3586
 
3495
3693
        RegistryOption('format',
3496
3694
            help='Upgrade to a specific format.  See "bzr help'
3497
3695
                 ' formats" for details.',
3498
 
            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3499
 
            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
3696
            lazy_registry=('bzrlib.controldir', 'format_registry'),
 
3697
            converter=lambda name: controldir.format_registry.make_bzrdir(name),
3500
3698
            value_switches=True, title='Branch format'),
3501
3699
        Option('clean',
3502
3700
            help='Remove the backup.bzr directory if successful.'),
3543
3741
            if directory is None:
3544
3742
                # use branch if we're inside one; otherwise global config
3545
3743
                try:
3546
 
                    c = Branch.open_containing(u'.')[0].get_config()
 
3744
                    c = Branch.open_containing(u'.')[0].get_config_stack()
3547
3745
                except errors.NotBranchError:
3548
 
                    c = _mod_config.GlobalConfig()
 
3746
                    c = _mod_config.GlobalStack()
3549
3747
            else:
3550
 
                c = Branch.open(directory).get_config()
 
3748
                c = Branch.open(directory).get_config_stack()
 
3749
            identity = c.get('email')
3551
3750
            if email:
3552
 
                self.outf.write(c.user_email() + '\n')
 
3751
                self.outf.write(_mod_config.extract_email_address(identity)
 
3752
                                + '\n')
3553
3753
            else:
3554
 
                self.outf.write(c.username() + '\n')
 
3754
                self.outf.write(identity + '\n')
3555
3755
            return
3556
3756
 
3557
3757
        if email:
3558
 
            raise errors.BzrCommandError("--email can only be used to display existing "
3559
 
                                         "identity")
 
3758
            raise errors.BzrCommandError(gettext("--email can only be used to display existing "
 
3759
                                         "identity"))
3560
3760
 
3561
3761
        # display a warning if an email address isn't included in the given name.
3562
3762
        try:
3568
3768
        # use global config unless --branch given
3569
3769
        if branch:
3570
3770
            if directory is None:
3571
 
                c = Branch.open_containing(u'.')[0].get_config()
 
3771
                c = Branch.open_containing(u'.')[0].get_config_stack()
3572
3772
            else:
3573
 
                c = Branch.open(directory).get_config()
 
3773
                c = Branch.open(directory).get_config_stack()
3574
3774
        else:
3575
 
            c = _mod_config.GlobalConfig()
3576
 
        c.set_user_option('email', name)
 
3775
            c = _mod_config.GlobalStack()
 
3776
        c.set('email', name)
3577
3777
 
3578
3778
 
3579
3779
class cmd_nick(Command):
3641
3841
 
3642
3842
    def remove_alias(self, alias_name):
3643
3843
        if alias_name is None:
3644
 
            raise errors.BzrCommandError(
3645
 
                'bzr alias --remove expects an alias to remove.')
 
3844
            raise errors.BzrCommandError(gettext(
 
3845
                'bzr alias --remove expects an alias to remove.'))
3646
3846
        # If alias is not found, print something like:
3647
3847
        # unalias: foo: not found
3648
3848
        c = _mod_config.GlobalConfig()
3786
3986
                                param_name='starting_with', short_name='s',
3787
3987
                                help=
3788
3988
                                'Load only the tests starting with TESTID.'),
 
3989
                     Option('sync',
 
3990
                            help="By default we disable fsync and fdatasync"
 
3991
                                 " while running the test suite.")
3789
3992
                     ]
3790
3993
    encoding_type = 'replace'
3791
3994
 
3799
4002
            first=False, list_only=False,
3800
4003
            randomize=None, exclude=None, strict=False,
3801
4004
            load_list=None, debugflag=None, starting_with=None, subunit=False,
3802
 
            parallel=None, lsprof_tests=False):
 
4005
            parallel=None, lsprof_tests=False,
 
4006
            sync=False):
3803
4007
 
3804
4008
        # During selftest, disallow proxying, as it can cause severe
3805
4009
        # performance penalties and is only needed for thread
3819
4023
            try:
3820
4024
                from bzrlib.tests import SubUnitBzrRunner
3821
4025
            except ImportError:
3822
 
                raise errors.BzrCommandError("subunit not available. subunit "
3823
 
                    "needs to be installed to use --subunit.")
 
4026
                raise errors.BzrCommandError(gettext("subunit not available. subunit "
 
4027
                    "needs to be installed to use --subunit."))
3824
4028
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3825
4029
            # On Windows, disable automatic conversion of '\n' to '\r\n' in
3826
4030
            # stdout, which would corrupt the subunit stream. 
3835
4039
            self.additional_selftest_args.setdefault(
3836
4040
                'suite_decorators', []).append(parallel)
3837
4041
        if benchmark:
3838
 
            raise errors.BzrCommandError(
 
4042
            raise errors.BzrCommandError(gettext(
3839
4043
                "--benchmark is no longer supported from bzr 2.2; "
3840
 
                "use bzr-usertest instead")
 
4044
                "use bzr-usertest instead"))
3841
4045
        test_suite_factory = None
3842
4046
        if not exclude:
3843
4047
            exclude_pattern = None
3844
4048
        else:
3845
4049
            exclude_pattern = '(' + '|'.join(exclude) + ')'
 
4050
        if not sync:
 
4051
            self._disable_fsync()
3846
4052
        selftest_kwargs = {"verbose": verbose,
3847
4053
                          "pattern": pattern,
3848
4054
                          "stop_on_failure": one,
3870
4076
            cleanup()
3871
4077
        return int(not result)
3872
4078
 
 
4079
    def _disable_fsync(self):
 
4080
        """Change the 'os' functionality to not synchronize."""
 
4081
        self._orig_fsync = getattr(os, 'fsync', None)
 
4082
        if self._orig_fsync is not None:
 
4083
            os.fsync = lambda filedes: None
 
4084
        self._orig_fdatasync = getattr(os, 'fdatasync', None)
 
4085
        if self._orig_fdatasync is not None:
 
4086
            os.fdatasync = lambda filedes: None
 
4087
 
3873
4088
 
3874
4089
class cmd_version(Command):
3875
4090
    __doc__ = """Show version of bzr."""
3895
4110
 
3896
4111
    @display_command
3897
4112
    def run(self):
3898
 
        self.outf.write("It sure does!\n")
 
4113
        self.outf.write(gettext("It sure does!\n"))
3899
4114
 
3900
4115
 
3901
4116
class cmd_find_merge_base(Command):
3919
4134
        graph = branch1.repository.get_graph(branch2.repository)
3920
4135
        base_rev_id = graph.find_unique_lca(last1, last2)
3921
4136
 
3922
 
        self.outf.write('merge base is revision %s\n' % base_rev_id)
 
4137
        self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
3923
4138
 
3924
4139
 
3925
4140
class cmd_merge(Command):
4050
4265
 
4051
4266
        tree = WorkingTree.open_containing(directory)[0]
4052
4267
        if tree.branch.revno() == 0:
4053
 
            raise errors.BzrCommandError('Merging into empty branches not currently supported, '
4054
 
                                         'https://bugs.launchpad.net/bzr/+bug/308562')
 
4268
            raise errors.BzrCommandError(gettext('Merging into empty branches not currently supported, '
 
4269
                                         'https://bugs.launchpad.net/bzr/+bug/308562'))
4055
4270
 
4056
4271
        try:
4057
4272
            basis_tree = tree.revision_tree(tree.last_revision())
4077
4292
                mergeable = None
4078
4293
            else:
4079
4294
                if uncommitted:
4080
 
                    raise errors.BzrCommandError('Cannot use --uncommitted'
4081
 
                        ' with bundles or merge directives.')
 
4295
                    raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
 
4296
                        ' with bundles or merge directives.'))
4082
4297
 
4083
4298
                if revision is not None:
4084
 
                    raise errors.BzrCommandError(
4085
 
                        'Cannot use -r with merge directives or bundles')
 
4299
                    raise errors.BzrCommandError(gettext(
 
4300
                        'Cannot use -r with merge directives or bundles'))
4086
4301
                merger, verified = _mod_merge.Merger.from_mergeable(tree,
4087
4302
                   mergeable, None)
4088
4303
 
4089
4304
        if merger is None and uncommitted:
4090
4305
            if revision is not None and len(revision) > 0:
4091
 
                raise errors.BzrCommandError('Cannot use --uncommitted and'
4092
 
                    ' --revision at the same time.')
 
4306
                raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
 
4307
                    ' --revision at the same time.'))
4093
4308
            merger = self.get_merger_from_uncommitted(tree, location, None)
4094
4309
            allow_pending = False
4095
4310
 
4108
4323
            if merger.interesting_files:
4109
4324
                if not merger.other_tree.has_filename(
4110
4325
                    merger.interesting_files[0]):
4111
 
                    note("merger: " + str(merger))
 
4326
                    note(gettext("merger: ") + str(merger))
4112
4327
                    raise errors.PathsDoNotExist([location])
4113
 
            note('Nothing to do.')
 
4328
            note(gettext('Nothing to do.'))
4114
4329
            return 0
4115
4330
        if pull and not preview:
4116
4331
            if merger.interesting_files is not None:
4117
 
                raise errors.BzrCommandError('Cannot pull individual files')
 
4332
                raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4118
4333
            if (merger.base_rev_id == tree.last_revision()):
4119
4334
                result = tree.pull(merger.other_branch, False,
4120
4335
                                   merger.other_rev_id)
4121
4336
                result.report(self.outf)
4122
4337
                return 0
4123
4338
        if merger.this_basis is None:
4124
 
            raise errors.BzrCommandError(
 
4339
            raise errors.BzrCommandError(gettext(
4125
4340
                "This branch has no commits."
4126
 
                " (perhaps you would prefer 'bzr pull')")
 
4341
                " (perhaps you would prefer 'bzr pull')"))
4127
4342
        if preview:
4128
4343
            return self._do_preview(merger)
4129
4344
        elif interactive:
4180
4395
    def sanity_check_merger(self, merger):
4181
4396
        if (merger.show_base and
4182
4397
            not merger.merge_type is _mod_merge.Merge3Merger):
4183
 
            raise errors.BzrCommandError("Show-base is not supported for this"
4184
 
                                         " merge type. %s" % merger.merge_type)
 
4398
            raise errors.BzrCommandError(gettext("Show-base is not supported for this"
 
4399
                                         " merge type. %s") % merger.merge_type)
4185
4400
        if merger.reprocess is None:
4186
4401
            if merger.show_base:
4187
4402
                merger.reprocess = False
4189
4404
                # Use reprocess if the merger supports it
4190
4405
                merger.reprocess = merger.merge_type.supports_reprocess
4191
4406
        if merger.reprocess and not merger.merge_type.supports_reprocess:
4192
 
            raise errors.BzrCommandError("Conflict reduction is not supported"
4193
 
                                         " for merge type %s." %
 
4407
            raise errors.BzrCommandError(gettext("Conflict reduction is not supported"
 
4408
                                         " for merge type %s.") %
4194
4409
                                         merger.merge_type)
4195
4410
        if merger.reprocess and merger.show_base:
4196
 
            raise errors.BzrCommandError("Cannot do conflict reduction and"
4197
 
                                         " show base.")
 
4411
            raise errors.BzrCommandError(gettext("Cannot do conflict reduction and"
 
4412
                                         " show base."))
4198
4413
 
4199
4414
    def _get_merger_from_branch(self, tree, location, revision, remember,
4200
4415
                                possible_transports, pb):
4304
4519
            stored_location_type = "parent"
4305
4520
        mutter("%s", stored_location)
4306
4521
        if stored_location is None:
4307
 
            raise errors.BzrCommandError("No location specified or remembered")
 
4522
            raise errors.BzrCommandError(gettext("No location specified or remembered"))
4308
4523
        display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4309
 
        note(u"%s remembered %s location %s", verb_string,
4310
 
                stored_location_type, display_url)
 
4524
        note(gettext("{0} remembered {1} location {2}").format(verb_string,
 
4525
                stored_location_type, display_url))
4311
4526
        return stored_location
4312
4527
 
4313
4528
 
4350
4565
        self.add_cleanup(tree.lock_write().unlock)
4351
4566
        parents = tree.get_parent_ids()
4352
4567
        if len(parents) != 2:
4353
 
            raise errors.BzrCommandError("Sorry, remerge only works after normal"
 
4568
            raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4354
4569
                                         " merges.  Not cherrypicking or"
4355
 
                                         " multi-merges.")
 
4570
                                         " multi-merges."))
4356
4571
        repository = tree.branch.repository
4357
4572
        interesting_ids = None
4358
4573
        new_conflicts = []
4517
4732
 
4518
4733
    @display_command
4519
4734
    def run(self, context=None):
4520
 
        import shellcomplete
 
4735
        from bzrlib import shellcomplete
4521
4736
        shellcomplete.shellcomplete(context)
4522
4737
 
4523
4738
 
4577
4792
            type=_parse_revision_str,
4578
4793
            help='Filter on local branch revisions (inclusive). '
4579
4794
                'See "help revisionspec" for details.'),
4580
 
        Option('include-merges',
 
4795
        Option('include-merged',
4581
4796
               'Show all revisions in addition to the mainline ones.'),
 
4797
        Option('include-merges', hidden=True,
 
4798
               help='Historical alias for --include-merged.'),
4582
4799
        ]
4583
4800
    encoding_type = 'replace'
4584
4801
 
4587
4804
            theirs_only=False,
4588
4805
            log_format=None, long=False, short=False, line=False,
4589
4806
            show_ids=False, verbose=False, this=False, other=False,
4590
 
            include_merges=False, revision=None, my_revision=None,
4591
 
            directory=u'.'):
 
4807
            include_merged=None, revision=None, my_revision=None,
 
4808
            directory=u'.',
 
4809
            include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4592
4810
        from bzrlib.missing import find_unmerged, iter_log_revisions
4593
4811
        def message(s):
4594
4812
            if not is_quiet():
4595
4813
                self.outf.write(s)
4596
4814
 
 
4815
        if symbol_versioning.deprecated_passed(include_merges):
 
4816
            ui.ui_factory.show_user_warning(
 
4817
                'deprecated_command_option',
 
4818
                deprecated_name='--include-merges',
 
4819
                recommended_name='--include-merged',
 
4820
                deprecated_in_version='2.5',
 
4821
                command=self.invoked_as)
 
4822
            if include_merged is None:
 
4823
                include_merged = include_merges
 
4824
            else:
 
4825
                raise errors.BzrCommandError(gettext(
 
4826
                    '{0} and {1} are mutually exclusive').format(
 
4827
                    '--include-merges', '--include-merged'))
 
4828
        if include_merged is None:
 
4829
            include_merged = False
4597
4830
        if this:
4598
4831
            mine_only = this
4599
4832
        if other:
4614
4847
        if other_branch is None:
4615
4848
            other_branch = parent
4616
4849
            if other_branch is None:
4617
 
                raise errors.BzrCommandError("No peer location known"
4618
 
                                             " or specified.")
 
4850
                raise errors.BzrCommandError(gettext("No peer location known"
 
4851
                                             " or specified."))
4619
4852
            display_url = urlutils.unescape_for_display(parent,
4620
4853
                                                        self.outf.encoding)
4621
 
            message("Using saved parent location: "
4622
 
                    + display_url + "\n")
 
4854
            message(gettext("Using saved parent location: {0}\n").format(
 
4855
                    display_url))
4623
4856
 
4624
4857
        remote_branch = Branch.open(other_branch)
4625
4858
        if remote_branch.base == local_branch.base:
4638
4871
        local_extra, remote_extra = find_unmerged(
4639
4872
            local_branch, remote_branch, restrict,
4640
4873
            backward=not reverse,
4641
 
            include_merges=include_merges,
 
4874
            include_merged=include_merged,
4642
4875
            local_revid_range=local_revid_range,
4643
4876
            remote_revid_range=remote_revid_range)
4644
4877
 
4651
4884
 
4652
4885
        status_code = 0
4653
4886
        if local_extra and not theirs_only:
4654
 
            message("You have %d extra revision(s):\n" %
 
4887
            message(ngettext("You have %d extra revision:\n",
 
4888
                             "You have %d extra revisions:\n", 
 
4889
                             len(local_extra)) %
4655
4890
                len(local_extra))
4656
4891
            for revision in iter_log_revisions(local_extra,
4657
4892
                                local_branch.repository,
4665
4900
        if remote_extra and not mine_only:
4666
4901
            if printed_local is True:
4667
4902
                message("\n\n\n")
4668
 
            message("You are missing %d revision(s):\n" %
 
4903
            message(ngettext("You are missing %d revision:\n",
 
4904
                             "You are missing %d revisions:\n",
 
4905
                             len(remote_extra)) %
4669
4906
                len(remote_extra))
4670
4907
            for revision in iter_log_revisions(remote_extra,
4671
4908
                                remote_branch.repository,
4675
4912
 
4676
4913
        if mine_only and not local_extra:
4677
4914
            # We checked local, and found nothing extra
4678
 
            message('This branch has no new revisions.\n')
 
4915
            message(gettext('This branch has no new revisions.\n'))
4679
4916
        elif theirs_only and not remote_extra:
4680
4917
            # We checked remote, and found nothing extra
4681
 
            message('Other branch has no new revisions.\n')
 
4918
            message(gettext('Other branch has no new revisions.\n'))
4682
4919
        elif not (mine_only or theirs_only or local_extra or
4683
4920
                  remote_extra):
4684
4921
            # We checked both branches, and neither one had extra
4685
4922
            # revisions
4686
 
            message("Branches are up to date.\n")
 
4923
            message(gettext("Branches are up to date.\n"))
4687
4924
        self.cleanup_now()
4688
4925
        if not status_code and parent is None and other_branch is not None:
4689
4926
            self.add_cleanup(local_branch.lock_write().unlock)
4719
4956
        ]
4720
4957
 
4721
4958
    def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4722
 
        dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
 
4959
        dir = controldir.ControlDir.open_containing(branch_or_repo)[0]
4723
4960
        try:
4724
4961
            branch = dir.open_branch()
4725
4962
            repository = branch.repository
4850
5087
 
4851
5088
    def run(self, revision_id_list=None, revision=None, directory=u'.'):
4852
5089
        if revision_id_list is not None and revision is not None:
4853
 
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
 
5090
            raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
4854
5091
        if revision_id_list is None and revision is None:
4855
 
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
 
5092
            raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
4856
5093
        b = WorkingTree.open_containing(directory)[0].branch
4857
5094
        self.add_cleanup(b.lock_write().unlock)
4858
5095
        return self._run(b, revision_id_list, revision)
4859
5096
 
4860
5097
    def _run(self, b, revision_id_list, revision):
4861
5098
        import bzrlib.gpg as gpg
4862
 
        gpg_strategy = gpg.GPGStrategy(b.get_config())
 
5099
        gpg_strategy = gpg.GPGStrategy(b.get_config_stack())
4863
5100
        if revision_id_list is not None:
4864
5101
            b.repository.start_write_group()
4865
5102
            try:
4890
5127
                if to_revid is None:
4891
5128
                    to_revno = b.revno()
4892
5129
                if from_revno is None or to_revno is None:
4893
 
                    raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
 
5130
                    raise errors.BzrCommandError(gettext('Cannot sign a range of non-revision-history revisions'))
4894
5131
                b.repository.start_write_group()
4895
5132
                try:
4896
5133
                    for revno in range(from_revno, to_revno + 1):
4902
5139
                else:
4903
5140
                    b.repository.commit_write_group()
4904
5141
            else:
4905
 
                raise errors.BzrCommandError('Please supply either one revision, or a range.')
 
5142
                raise errors.BzrCommandError(gettext('Please supply either one revision, or a range.'))
4906
5143
 
4907
5144
 
4908
5145
class cmd_bind(Command):
4927
5164
            try:
4928
5165
                location = b.get_old_bound_location()
4929
5166
            except errors.UpgradeRequired:
4930
 
                raise errors.BzrCommandError('No location supplied.  '
4931
 
                    'This format does not remember old locations.')
 
5167
                raise errors.BzrCommandError(gettext('No location supplied.  '
 
5168
                    'This format does not remember old locations.'))
4932
5169
            else:
4933
5170
                if location is None:
4934
5171
                    if b.get_bound_location() is not None:
4935
 
                        raise errors.BzrCommandError('Branch is already bound')
 
5172
                        raise errors.BzrCommandError(gettext('Branch is already bound'))
4936
5173
                    else:
4937
 
                        raise errors.BzrCommandError('No location supplied '
4938
 
                            'and no previous location known')
 
5174
                        raise errors.BzrCommandError(gettext('No location supplied '
 
5175
                            'and no previous location known'))
4939
5176
        b_other = Branch.open(location)
4940
5177
        try:
4941
5178
            b.bind(b_other)
4942
5179
        except errors.DivergedBranches:
4943
 
            raise errors.BzrCommandError('These branches have diverged.'
4944
 
                                         ' Try merging, and then bind again.')
 
5180
            raise errors.BzrCommandError(gettext('These branches have diverged.'
 
5181
                                         ' Try merging, and then bind again.'))
4945
5182
        if b.get_config().has_explicit_nickname():
4946
5183
            b.nick = b_other.nick
4947
5184
 
4960
5197
    def run(self, directory=u'.'):
4961
5198
        b, relpath = Branch.open_containing(directory)
4962
5199
        if not b.unbind():
4963
 
            raise errors.BzrCommandError('Local branch is not bound')
 
5200
            raise errors.BzrCommandError(gettext('Local branch is not bound'))
4964
5201
 
4965
5202
 
4966
5203
class cmd_uncommit(Command):
5002
5239
            revision=None, force=False, local=False, keep_tags=False):
5003
5240
        if location is None:
5004
5241
            location = u'.'
5005
 
        control, relpath = bzrdir.BzrDir.open_containing(location)
 
5242
        control, relpath = controldir.ControlDir.open_containing(location)
5006
5243
        try:
5007
5244
            tree = control.open_workingtree()
5008
5245
            b = tree.branch
5039
5276
                rev_id = b.get_rev_id(revno)
5040
5277
 
5041
5278
        if rev_id is None or _mod_revision.is_null(rev_id):
5042
 
            self.outf.write('No revisions to uncommit.\n')
 
5279
            self.outf.write(gettext('No revisions to uncommit.\n'))
5043
5280
            return 1
5044
5281
 
5045
5282
        lf = log_formatter('short',
5054
5291
                 end_revision=last_revno)
5055
5292
 
5056
5293
        if dry_run:
5057
 
            self.outf.write('Dry-run, pretending to remove'
5058
 
                            ' the above revisions.\n')
 
5294
            self.outf.write(gettext('Dry-run, pretending to remove'
 
5295
                            ' the above revisions.\n'))
5059
5296
        else:
5060
 
            self.outf.write('The above revision(s) will be removed.\n')
 
5297
            self.outf.write(gettext('The above revision(s) will be removed.\n'))
5061
5298
 
5062
5299
        if not force:
5063
5300
            if not ui.ui_factory.confirm_action(
5064
 
                    u'Uncommit these revisions',
 
5301
                    gettext(u'Uncommit these revisions'),
5065
5302
                    'bzrlib.builtins.uncommit',
5066
5303
                    {}):
5067
 
                self.outf.write('Canceled\n')
 
5304
                self.outf.write(gettext('Canceled\n'))
5068
5305
                return 0
5069
5306
 
5070
5307
        mutter('Uncommitting from {%s} to {%s}',
5071
5308
               last_rev_id, rev_id)
5072
5309
        uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5073
5310
                 revno=revno, local=local, keep_tags=keep_tags)
5074
 
        self.outf.write('You can restore the old tip by running:\n'
5075
 
             '  bzr pull . -r revid:%s\n' % last_rev_id)
 
5311
        self.outf.write(gettext('You can restore the old tip by running:\n'
 
5312
             '  bzr pull . -r revid:%s\n') % last_rev_id)
5076
5313
 
5077
5314
 
5078
5315
class cmd_break_lock(Command):
5112
5349
            conf = _mod_config.LockableConfig(file_name=location)
5113
5350
            conf.break_lock()
5114
5351
        else:
5115
 
            control, relpath = bzrdir.BzrDir.open_containing(location)
 
5352
            control, relpath = controldir.ControlDir.open_containing(location)
5116
5353
            try:
5117
5354
                control.break_lock()
5118
5355
            except NotImplementedError:
5162
5399
                    'option leads to global uncontrolled write access to your '
5163
5400
                    'file system.'
5164
5401
                ),
 
5402
        Option('client-timeout', type=float,
 
5403
               help='Override the default idle client timeout (5min).'),
5165
5404
        ]
5166
5405
 
5167
5406
    def get_host_and_port(self, port):
5184
5423
        return host, port
5185
5424
 
5186
5425
    def run(self, port=None, inet=False, directory=None, allow_writes=False,
5187
 
            protocol=None):
 
5426
            protocol=None, client_timeout=None):
5188
5427
        from bzrlib import transport
5189
5428
        if directory is None:
5190
5429
            directory = os.getcwd()
5191
5430
        if protocol is None:
5192
5431
            protocol = transport.transport_server_registry.get()
5193
5432
        host, port = self.get_host_and_port(port)
5194
 
        url = urlutils.local_path_to_url(directory)
 
5433
        url = transport.location_to_url(directory)
5195
5434
        if not allow_writes:
5196
5435
            url = 'readonly+' + url
5197
 
        t = transport.get_transport(url)
5198
 
        protocol(t, host, port, inet)
 
5436
        t = transport.get_transport_from_url(url)
 
5437
        try:
 
5438
            protocol(t, host, port, inet, client_timeout)
 
5439
        except TypeError, e:
 
5440
            # We use symbol_versioning.deprecated_in just so that people
 
5441
            # grepping can find it here.
 
5442
            # symbol_versioning.deprecated_in((2, 5, 0))
 
5443
            symbol_versioning.warn(
 
5444
                'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
 
5445
                'Most likely it needs to be updated to support a'
 
5446
                ' "timeout" parameter (added in bzr 2.5.0)'
 
5447
                % (e, protocol.__module__, protocol),
 
5448
                DeprecationWarning)
 
5449
            protocol(t, host, port, inet)
5199
5450
 
5200
5451
 
5201
5452
class cmd_join(Command):
5224
5475
        containing_tree = WorkingTree.open_containing(parent_dir)[0]
5225
5476
        repo = containing_tree.branch.repository
5226
5477
        if not repo.supports_rich_root():
5227
 
            raise errors.BzrCommandError(
 
5478
            raise errors.BzrCommandError(gettext(
5228
5479
                "Can't join trees because %s doesn't support rich root data.\n"
5229
 
                "You can use bzr upgrade on the repository."
 
5480
                "You can use bzr upgrade on the repository.")
5230
5481
                % (repo,))
5231
5482
        if reference:
5232
5483
            try:
5234
5485
            except errors.BadReferenceTarget, e:
5235
5486
                # XXX: Would be better to just raise a nicely printable
5236
5487
                # exception from the real origin.  Also below.  mbp 20070306
5237
 
                raise errors.BzrCommandError("Cannot join %s.  %s" %
5238
 
                                             (tree, e.reason))
 
5488
                raise errors.BzrCommandError(
 
5489
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5239
5490
        else:
5240
5491
            try:
5241
5492
                containing_tree.subsume(sub_tree)
5242
5493
            except errors.BadSubsumeSource, e:
5243
 
                raise errors.BzrCommandError("Cannot join %s.  %s" %
5244
 
                                             (tree, e.reason))
 
5494
                raise errors.BzrCommandError(
 
5495
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5245
5496
 
5246
5497
 
5247
5498
class cmd_split(Command):
5331
5582
        if submit_branch is None:
5332
5583
            submit_branch = branch.get_parent()
5333
5584
        if submit_branch is None:
5334
 
            raise errors.BzrCommandError('No submit branch specified or known')
 
5585
            raise errors.BzrCommandError(gettext('No submit branch specified or known'))
5335
5586
 
5336
5587
        stored_public_branch = branch.get_public_branch()
5337
5588
        if public_branch is None:
5339
5590
        elif stored_public_branch is None:
5340
5591
            branch.set_public_branch(public_branch)
5341
5592
        if not include_bundle and public_branch is None:
5342
 
            raise errors.BzrCommandError('No public branch specified or'
5343
 
                                         ' known')
 
5593
            raise errors.BzrCommandError(gettext('No public branch specified or'
 
5594
                                         ' known'))
5344
5595
        base_revision_id = None
5345
5596
        if revision is not None:
5346
5597
            if len(revision) > 2:
5347
 
                raise errors.BzrCommandError('bzr merge-directive takes '
5348
 
                    'at most two one revision identifiers')
 
5598
                raise errors.BzrCommandError(gettext('bzr merge-directive takes '
 
5599
                    'at most two one revision identifiers'))
5349
5600
            revision_id = revision[-1].as_revision_id(branch)
5350
5601
            if len(revision) == 2:
5351
5602
                base_revision_id = revision[0].as_revision_id(branch)
5353
5604
            revision_id = branch.last_revision()
5354
5605
        revision_id = ensure_null(revision_id)
5355
5606
        if revision_id == NULL_REVISION:
5356
 
            raise errors.BzrCommandError('No revisions to bundle.')
 
5607
            raise errors.BzrCommandError(gettext('No revisions to bundle.'))
5357
5608
        directive = merge_directive.MergeDirective2.from_objects(
5358
5609
            branch.repository, revision_id, time.time(),
5359
5610
            osutils.local_time_offset(), submit_branch,
5367
5618
                self.outf.writelines(directive.to_lines())
5368
5619
        else:
5369
5620
            message = directive.to_email(mail_to, branch, sign)
5370
 
            s = SMTPConnection(branch.get_config())
 
5621
            s = SMTPConnection(branch.get_config_stack())
5371
5622
            s.send_email(message)
5372
5623
 
5373
5624
 
5613
5864
        self.add_cleanup(branch.lock_write().unlock)
5614
5865
        if delete:
5615
5866
            if tag_name is None:
5616
 
                raise errors.BzrCommandError("No tag specified to delete.")
 
5867
                raise errors.BzrCommandError(gettext("No tag specified to delete."))
5617
5868
            branch.tags.delete_tag(tag_name)
5618
 
            note('Deleted tag %s.' % tag_name)
 
5869
            note(gettext('Deleted tag %s.') % tag_name)
5619
5870
        else:
5620
5871
            if revision:
5621
5872
                if len(revision) != 1:
5622
 
                    raise errors.BzrCommandError(
 
5873
                    raise errors.BzrCommandError(gettext(
5623
5874
                        "Tags can only be placed on a single revision, "
5624
 
                        "not on a range")
 
5875
                        "not on a range"))
5625
5876
                revision_id = revision[0].as_revision_id(branch)
5626
5877
            else:
5627
5878
                revision_id = branch.last_revision()
5628
5879
            if tag_name is None:
5629
5880
                tag_name = branch.automatic_tag_name(revision_id)
5630
5881
                if tag_name is None:
5631
 
                    raise errors.BzrCommandError(
5632
 
                        "Please specify a tag name.")
5633
 
            if (not force) and branch.tags.has_tag(tag_name):
 
5882
                    raise errors.BzrCommandError(gettext(
 
5883
                        "Please specify a tag name."))
 
5884
            try:
 
5885
                existing_target = branch.tags.lookup_tag(tag_name)
 
5886
            except errors.NoSuchTag:
 
5887
                existing_target = None
 
5888
            if not force and existing_target not in (None, revision_id):
5634
5889
                raise errors.TagAlreadyExists(tag_name)
5635
 
            branch.tags.set_tag(tag_name, revision_id)
5636
 
            note('Created tag %s.' % tag_name)
 
5890
            if existing_target == revision_id:
 
5891
                note(gettext('Tag %s already exists for that revision.') % tag_name)
 
5892
            else:
 
5893
                branch.tags.set_tag(tag_name, revision_id)
 
5894
                if existing_target is None:
 
5895
                    note(gettext('Created tag %s.') % tag_name)
 
5896
                else:
 
5897
                    note(gettext('Updated tag %s.') % tag_name)
5637
5898
 
5638
5899
 
5639
5900
class cmd_tags(Command):
5665
5926
 
5666
5927
        self.add_cleanup(branch.lock_read().unlock)
5667
5928
        if revision:
5668
 
            graph = branch.repository.get_graph()
5669
 
            rev1, rev2 = _get_revision_range(revision, branch, self.name())
5670
 
            revid1, revid2 = rev1.rev_id, rev2.rev_id
5671
 
            # only show revisions between revid1 and revid2 (inclusive)
5672
 
            tags = [(tag, revid) for tag, revid in tags if
5673
 
                graph.is_between(revid, revid1, revid2)]
 
5929
            # Restrict to the specified range
 
5930
            tags = self._tags_for_range(branch, revision)
5674
5931
        if sort is None:
5675
5932
            sort = tag_sort_methods.get()
5676
5933
        sort(branch, tags)
5681
5938
                    revno = branch.revision_id_to_dotted_revno(revid)
5682
5939
                    if isinstance(revno, tuple):
5683
5940
                        revno = '.'.join(map(str, revno))
5684
 
                except (errors.NoSuchRevision, errors.GhostRevisionsHaveNoRevno):
 
5941
                except (errors.NoSuchRevision,
 
5942
                        errors.GhostRevisionsHaveNoRevno,
 
5943
                        errors.UnsupportedOperation):
5685
5944
                    # Bad tag data/merges can lead to tagged revisions
5686
5945
                    # which are not in this branch. Fail gracefully ...
5687
5946
                    revno = '?'
5690
5949
        for tag, revspec in tags:
5691
5950
            self.outf.write('%-20s %s\n' % (tag, revspec))
5692
5951
 
 
5952
    def _tags_for_range(self, branch, revision):
 
5953
        range_valid = True
 
5954
        rev1, rev2 = _get_revision_range(revision, branch, self.name())
 
5955
        revid1, revid2 = rev1.rev_id, rev2.rev_id
 
5956
        # _get_revision_range will always set revid2 if it's not specified.
 
5957
        # If revid1 is None, it means we want to start from the branch
 
5958
        # origin which is always a valid ancestor. If revid1 == revid2, the
 
5959
        # ancestry check is useless.
 
5960
        if revid1 and revid1 != revid2:
 
5961
            # FIXME: We really want to use the same graph than
 
5962
            # branch.iter_merge_sorted_revisions below, but this is not
 
5963
            # easily available -- vila 2011-09-23
 
5964
            if branch.repository.get_graph().is_ancestor(revid2, revid1):
 
5965
                # We don't want to output anything in this case...
 
5966
                return []
 
5967
        # only show revisions between revid1 and revid2 (inclusive)
 
5968
        tagged_revids = branch.tags.get_reverse_tag_dict()
 
5969
        found = []
 
5970
        for r in branch.iter_merge_sorted_revisions(
 
5971
            start_revision_id=revid2, stop_revision_id=revid1,
 
5972
            stop_rule='include'):
 
5973
            revid_tags = tagged_revids.get(r[0], None)
 
5974
            if revid_tags:
 
5975
                found.extend([(tag, r[0]) for tag in revid_tags])
 
5976
        return found
 
5977
 
5693
5978
 
5694
5979
class cmd_reconfigure(Command):
5695
5980
    __doc__ = """Reconfigure the type of a bzr directory.
5709
5994
    takes_args = ['location?']
5710
5995
    takes_options = [
5711
5996
        RegistryOption.from_kwargs(
5712
 
            'target_type',
5713
 
            title='Target type',
5714
 
            help='The type to reconfigure the directory to.',
 
5997
            'tree_type',
 
5998
            title='Tree type',
 
5999
            help='The relation between branch and tree.',
5715
6000
            value_switches=True, enum_switch=False,
5716
6001
            branch='Reconfigure to be an unbound branch with no working tree.',
5717
6002
            tree='Reconfigure to be an unbound branch with a working tree.',
5718
6003
            checkout='Reconfigure to be a bound branch with a working tree.',
5719
6004
            lightweight_checkout='Reconfigure to be a lightweight'
5720
6005
                ' checkout (with no local history).',
 
6006
            ),
 
6007
        RegistryOption.from_kwargs(
 
6008
            'repository_type',
 
6009
            title='Repository type',
 
6010
            help='Location fo the repository.',
 
6011
            value_switches=True, enum_switch=False,
5721
6012
            standalone='Reconfigure to be a standalone branch '
5722
6013
                '(i.e. stop using shared repository).',
5723
6014
            use_shared='Reconfigure to use a shared repository.',
 
6015
            ),
 
6016
        RegistryOption.from_kwargs(
 
6017
            'repository_trees',
 
6018
            title='Trees in Repository',
 
6019
            help='Whether new branches in the repository have trees.',
 
6020
            value_switches=True, enum_switch=False,
5724
6021
            with_trees='Reconfigure repository to create '
5725
6022
                'working trees on branches by default.',
5726
6023
            with_no_trees='Reconfigure repository to not create '
5740
6037
            ),
5741
6038
        ]
5742
6039
 
5743
 
    def run(self, location=None, target_type=None, bind_to=None, force=False,
5744
 
            stacked_on=None,
5745
 
            unstacked=None):
5746
 
        directory = bzrdir.BzrDir.open(location)
 
6040
    def run(self, location=None, bind_to=None, force=False,
 
6041
            tree_type=None, repository_type=None, repository_trees=None,
 
6042
            stacked_on=None, unstacked=None):
 
6043
        directory = controldir.ControlDir.open(location)
5747
6044
        if stacked_on and unstacked:
5748
 
            raise errors.BzrCommandError("Can't use both --stacked-on and --unstacked")
 
6045
            raise errors.BzrCommandError(gettext("Can't use both --stacked-on and --unstacked"))
5749
6046
        elif stacked_on is not None:
5750
6047
            reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5751
6048
        elif unstacked:
5753
6050
        # At the moment you can use --stacked-on and a different
5754
6051
        # reconfiguration shape at the same time; there seems no good reason
5755
6052
        # to ban it.
5756
 
        if target_type is None:
 
6053
        if (tree_type is None and
 
6054
            repository_type is None and
 
6055
            repository_trees is None):
5757
6056
            if stacked_on or unstacked:
5758
6057
                return
5759
6058
            else:
5760
 
                raise errors.BzrCommandError('No target configuration '
5761
 
                    'specified')
5762
 
        elif target_type == 'branch':
 
6059
                raise errors.BzrCommandError(gettext('No target configuration '
 
6060
                    'specified'))
 
6061
        reconfiguration = None
 
6062
        if tree_type == 'branch':
5763
6063
            reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5764
 
        elif target_type == 'tree':
 
6064
        elif tree_type == 'tree':
5765
6065
            reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5766
 
        elif target_type == 'checkout':
 
6066
        elif tree_type == 'checkout':
5767
6067
            reconfiguration = reconfigure.Reconfigure.to_checkout(
5768
6068
                directory, bind_to)
5769
 
        elif target_type == 'lightweight-checkout':
 
6069
        elif tree_type == 'lightweight-checkout':
5770
6070
            reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5771
6071
                directory, bind_to)
5772
 
        elif target_type == 'use-shared':
 
6072
        if reconfiguration:
 
6073
            reconfiguration.apply(force)
 
6074
            reconfiguration = None
 
6075
        if repository_type == 'use-shared':
5773
6076
            reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5774
 
        elif target_type == 'standalone':
 
6077
        elif repository_type == 'standalone':
5775
6078
            reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5776
 
        elif target_type == 'with-trees':
 
6079
        if reconfiguration:
 
6080
            reconfiguration.apply(force)
 
6081
            reconfiguration = None
 
6082
        if repository_trees == 'with-trees':
5777
6083
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5778
6084
                directory, True)
5779
 
        elif target_type == 'with-no-trees':
 
6085
        elif repository_trees == 'with-no-trees':
5780
6086
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5781
6087
                directory, False)
5782
 
        reconfiguration.apply(force)
 
6088
        if reconfiguration:
 
6089
            reconfiguration.apply(force)
 
6090
            reconfiguration = None
5783
6091
 
5784
6092
 
5785
6093
class cmd_switch(Command):
5820
6128
        from bzrlib import switch
5821
6129
        tree_location = directory
5822
6130
        revision = _get_one_revision('switch', revision)
5823
 
        control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
 
6131
        control_dir = controldir.ControlDir.open_containing(tree_location)[0]
5824
6132
        if to_location is None:
5825
6133
            if revision is None:
5826
 
                raise errors.BzrCommandError('You must supply either a'
5827
 
                                             ' revision or a location')
 
6134
                raise errors.BzrCommandError(gettext('You must supply either a'
 
6135
                                             ' revision or a location'))
5828
6136
            to_location = tree_location
5829
6137
        try:
5830
6138
            branch = control_dir.open_branch()
5834
6142
            had_explicit_nick = False
5835
6143
        if create_branch:
5836
6144
            if branch is None:
5837
 
                raise errors.BzrCommandError('cannot create branch without'
5838
 
                                             ' source branch')
 
6145
                raise errors.BzrCommandError(gettext('cannot create branch without'
 
6146
                                             ' source branch'))
5839
6147
            to_location = directory_service.directories.dereference(
5840
6148
                              to_location)
5841
6149
            if '/' not in to_location and '\\' not in to_location:
5842
6150
                # This path is meant to be relative to the existing branch
5843
6151
                this_url = self._get_branch_location(control_dir)
5844
 
                to_location = urlutils.join(this_url, '..', to_location)
 
6152
                # Perhaps the target control dir supports colocated branches?
 
6153
                try:
 
6154
                    root = controldir.ControlDir.open(this_url,
 
6155
                        possible_transports=[control_dir.user_transport])
 
6156
                except errors.NotBranchError:
 
6157
                    colocated = False
 
6158
                else:
 
6159
                    colocated = root._format.colocated_branches
 
6160
                if colocated:
 
6161
                    to_location = urlutils.join_segment_parameters(this_url,
 
6162
                        {"branch": urlutils.escape(to_location)})
 
6163
                else:
 
6164
                    to_location = urlutils.join(
 
6165
                        this_url, '..', urlutils.escape(to_location))
5845
6166
            to_branch = branch.bzrdir.sprout(to_location,
5846
6167
                                 possible_transports=[branch.bzrdir.root_transport],
5847
6168
                                 source_branch=branch).open_branch()
5848
6169
        else:
 
6170
            # Perhaps it's a colocated branch?
5849
6171
            try:
5850
 
                to_branch = Branch.open(to_location)
5851
 
            except errors.NotBranchError:
5852
 
                this_url = self._get_branch_location(control_dir)
5853
 
                to_branch = Branch.open(
5854
 
                    urlutils.join(this_url, '..', to_location))
 
6172
                to_branch = control_dir.open_branch(to_location)
 
6173
            except (errors.NotBranchError, errors.NoColocatedBranchSupport):
 
6174
                try:
 
6175
                    to_branch = Branch.open(to_location)
 
6176
                except errors.NotBranchError:
 
6177
                    this_url = self._get_branch_location(control_dir)
 
6178
                    to_branch = Branch.open(
 
6179
                        urlutils.join(
 
6180
                            this_url, '..', urlutils.escape(to_location)))
5855
6181
        if revision is not None:
5856
6182
            revision = revision.as_revision_id(to_branch)
5857
6183
        switch.switch(control_dir, to_branch, force, revision_id=revision)
5858
6184
        if had_explicit_nick:
5859
6185
            branch = control_dir.open_branch() #get the new branch!
5860
6186
            branch.nick = to_branch.nick
5861
 
        note('Switched to branch: %s',
 
6187
        note(gettext('Switched to branch: %s'),
5862
6188
            urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5863
6189
 
5864
6190
    def _get_branch_location(self, control_dir):
5973
6299
            name = current_view
5974
6300
        if delete:
5975
6301
            if file_list:
5976
 
                raise errors.BzrCommandError(
5977
 
                    "Both --delete and a file list specified")
 
6302
                raise errors.BzrCommandError(gettext(
 
6303
                    "Both --delete and a file list specified"))
5978
6304
            elif switch:
5979
 
                raise errors.BzrCommandError(
5980
 
                    "Both --delete and --switch specified")
 
6305
                raise errors.BzrCommandError(gettext(
 
6306
                    "Both --delete and --switch specified"))
5981
6307
            elif all:
5982
6308
                tree.views.set_view_info(None, {})
5983
 
                self.outf.write("Deleted all views.\n")
 
6309
                self.outf.write(gettext("Deleted all views.\n"))
5984
6310
            elif name is None:
5985
 
                raise errors.BzrCommandError("No current view to delete")
 
6311
                raise errors.BzrCommandError(gettext("No current view to delete"))
5986
6312
            else:
5987
6313
                tree.views.delete_view(name)
5988
 
                self.outf.write("Deleted '%s' view.\n" % name)
 
6314
                self.outf.write(gettext("Deleted '%s' view.\n") % name)
5989
6315
        elif switch:
5990
6316
            if file_list:
5991
 
                raise errors.BzrCommandError(
5992
 
                    "Both --switch and a file list specified")
 
6317
                raise errors.BzrCommandError(gettext(
 
6318
                    "Both --switch and a file list specified"))
5993
6319
            elif all:
5994
 
                raise errors.BzrCommandError(
5995
 
                    "Both --switch and --all specified")
 
6320
                raise errors.BzrCommandError(gettext(
 
6321
                    "Both --switch and --all specified"))
5996
6322
            elif switch == 'off':
5997
6323
                if current_view is None:
5998
 
                    raise errors.BzrCommandError("No current view to disable")
 
6324
                    raise errors.BzrCommandError(gettext("No current view to disable"))
5999
6325
                tree.views.set_view_info(None, view_dict)
6000
 
                self.outf.write("Disabled '%s' view.\n" % (current_view))
 
6326
                self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
6001
6327
            else:
6002
6328
                tree.views.set_view_info(switch, view_dict)
6003
6329
                view_str = views.view_display_str(tree.views.lookup_view())
6004
 
                self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
 
6330
                self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
6005
6331
        elif all:
6006
6332
            if view_dict:
6007
 
                self.outf.write('Views defined:\n')
 
6333
                self.outf.write(gettext('Views defined:\n'))
6008
6334
                for view in sorted(view_dict):
6009
6335
                    if view == current_view:
6010
6336
                        active = "=>"
6013
6339
                    view_str = views.view_display_str(view_dict[view])
6014
6340
                    self.outf.write('%s %-20s %s\n' % (active, view, view_str))
6015
6341
            else:
6016
 
                self.outf.write('No views defined.\n')
 
6342
                self.outf.write(gettext('No views defined.\n'))
6017
6343
        elif file_list:
6018
6344
            if name is None:
6019
6345
                # No name given and no current view set
6020
6346
                name = 'my'
6021
6347
            elif name == 'off':
6022
 
                raise errors.BzrCommandError(
6023
 
                    "Cannot change the 'off' pseudo view")
 
6348
                raise errors.BzrCommandError(gettext(
 
6349
                    "Cannot change the 'off' pseudo view"))
6024
6350
            tree.views.set_view(name, sorted(file_list))
6025
6351
            view_str = views.view_display_str(tree.views.lookup_view())
6026
 
            self.outf.write("Using '%s' view: %s\n" % (name, view_str))
 
6352
            self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
6027
6353
        else:
6028
6354
            # list the files
6029
6355
            if name is None:
6030
6356
                # No name given and no current view set
6031
 
                self.outf.write('No current view.\n')
 
6357
                self.outf.write(gettext('No current view.\n'))
6032
6358
            else:
6033
6359
                view_str = views.view_display_str(tree.views.lookup_view(name))
6034
 
                self.outf.write("'%s' view is: %s\n" % (name, view_str))
 
6360
                self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
6035
6361
 
6036
6362
 
6037
6363
class cmd_hooks(Command):
6051
6377
                        self.outf.write("    %s\n" %
6052
6378
                                        (some_hooks.get_hook_name(hook),))
6053
6379
                else:
6054
 
                    self.outf.write("    <no hooks installed>\n")
 
6380
                    self.outf.write(gettext("    <no hooks installed>\n"))
6055
6381
 
6056
6382
 
6057
6383
class cmd_remove_branch(Command):
6158
6484
        manager = tree.get_shelf_manager()
6159
6485
        shelves = manager.active_shelves()
6160
6486
        if len(shelves) == 0:
6161
 
            note('No shelved changes.')
 
6487
            note(gettext('No shelved changes.'))
6162
6488
            return 0
6163
6489
        for shelf_id in reversed(shelves):
6164
6490
            message = manager.get_metadata(shelf_id).get('message')
6253
6579
        if path is not None:
6254
6580
            branchdir = path
6255
6581
        tree, branch, relpath =(
6256
 
            bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
 
6582
            controldir.ControlDir.open_containing_tree_or_branch(branchdir))
6257
6583
        if path is not None:
6258
6584
            path = relpath
6259
6585
        if tree is None:
6287
6613
    __doc__ = """Export command helps and error messages in po format."""
6288
6614
 
6289
6615
    hidden = True
 
6616
    takes_options = [Option('plugin', 
 
6617
                            help='Export help text from named command '\
 
6618
                                 '(defaults to all built in commands).',
 
6619
                            type=str),
 
6620
                     Option('include-duplicates',
 
6621
                            help='Output multiple copies of the same msgid '
 
6622
                                 'string if it appears more than once.'),
 
6623
                            ]
6290
6624
 
6291
 
    def run(self):
 
6625
    def run(self, plugin=None, include_duplicates=False):
6292
6626
        from bzrlib.export_pot import export_pot
6293
 
        export_pot(self.outf)
 
6627
        export_pot(self.outf, plugin, include_duplicates)
6294
6628
 
6295
6629
 
6296
6630
def _register_lazy_builtins():