~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Martin Packman
  • Date: 2012-02-01 12:32:26 UTC
  • mto: (6437.23.4 2.5)
  • mto: This revision was merged to the branch mainline in revision 6459.
  • Revision ID: martin.packman@canonical.com-20120201123226-eudbx4v8yl0w8q93
Add some similar tests for path_from_environ as well

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
 
21
 
from bzrlib.lazy_import import lazy_import
22
 
lazy_import(globals(), """
 
23
import bzrlib.bzrdir
 
24
 
 
25
from bzrlib import lazy_import
 
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 (
77
83
    )
78
84
 
79
85
 
 
86
def _get_branch_location(control_dir, possible_transports=None):
 
87
    """Return location of branch for this control dir."""
 
88
    try:
 
89
        this_branch = control_dir.open_branch(
 
90
            possible_transports=possible_transports)
 
91
        # This may be a heavy checkout, where we want the master branch
 
92
        master_location = this_branch.get_bound_location()
 
93
        if master_location is not None:
 
94
            return master_location
 
95
        # If not, use a local sibling
 
96
        return this_branch.base
 
97
    except errors.NotBranchError:
 
98
        format = control_dir.find_branch_format()
 
99
        if getattr(format, 'get_reference', None) is not None:
 
100
            return format.get_reference(control_dir)
 
101
        else:
 
102
            return control_dir.root_transport.base
 
103
 
 
104
 
 
105
def _is_colocated(control_dir, possible_transports=None):
 
106
    """Check if the branch in control_dir is colocated.
 
107
 
 
108
    :param control_dir: Control directory
 
109
    :return: Boolean indicating whether 
 
110
    """
 
111
    # This path is meant to be relative to the existing branch
 
112
    this_url = _get_branch_location(control_dir,
 
113
        possible_transports=possible_transports)
 
114
    # Perhaps the target control dir supports colocated branches?
 
115
    try:
 
116
        root = controldir.ControlDir.open(this_url,
 
117
            possible_transports=possible_transports)
 
118
    except errors.NotBranchError:
 
119
        return (False, this_url)
 
120
    else:
 
121
        try:
 
122
            wt = control_dir.open_workingtree()
 
123
        except (errors.NoWorkingTree, errors.NotLocalUrl):
 
124
            return (False, this_url)
 
125
        else:
 
126
            return (
 
127
                root._format.colocated_branches and
 
128
                control_dir.control_url == root.control_url,
 
129
                this_url)
 
130
 
 
131
 
 
132
def lookup_new_sibling_branch(control_dir, location, possible_transports=None):
 
133
    """Lookup the location for a new sibling branch.
 
134
 
 
135
    :param control_dir: Control directory relative to which to look up
 
136
        the name.
 
137
    :param location: Name of the new branch
 
138
    :return: Full location to the new branch
 
139
    """
 
140
    location = directory_service.directories.dereference(location)
 
141
    if '/' not in location and '\\' not in location:
 
142
        (colocated, this_url) = _is_colocated(control_dir, possible_transports)
 
143
 
 
144
        if colocated:
 
145
            return urlutils.join_segment_parameters(this_url,
 
146
                {"branch": urlutils.escape(location)})
 
147
        else:
 
148
            return urlutils.join(this_url, '..', urlutils.escape(location))
 
149
    return location
 
150
 
 
151
 
 
152
def lookup_sibling_branch(control_dir, location, possible_transports=None):
 
153
    """Lookup sibling branch.
 
154
    
 
155
    :param control_dir: Control directory relative to which to lookup the
 
156
        location.
 
157
    :param location: Location to look up
 
158
    :return: branch to open
 
159
    """
 
160
    try:
 
161
        # Perhaps it's a colocated branch?
 
162
        return control_dir.open_branch(location, 
 
163
            possible_transports=possible_transports)
 
164
    except (errors.NotBranchError, errors.NoColocatedBranchSupport):
 
165
        try:
 
166
            return Branch.open(location)
 
167
        except errors.NotBranchError:
 
168
            this_url = _get_branch_location(control_dir)
 
169
            return Branch.open(
 
170
                urlutils.join(
 
171
                    this_url, '..', urlutils.escape(location)))
 
172
 
 
173
 
80
174
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
81
175
def tree_files(file_list, default_branch=u'.', canonicalize=True,
82
176
    apply_view=True):
112
206
            if view_files:
113
207
                file_list = view_files
114
208
                view_str = views.view_display_str(view_files)
115
 
                note("Ignoring files outside view. View is %s" % view_str)
 
209
                note(gettext("Ignoring files outside view. View is %s") % view_str)
116
210
    return tree, file_list
117
211
 
118
212
 
120
214
    if revisions is None:
121
215
        return None
122
216
    if len(revisions) != 1:
123
 
        raise errors.BzrCommandError(
124
 
            'bzr %s --revision takes exactly one revision identifier' % (
 
217
        raise errors.BzrCommandError(gettext(
 
218
            'bzr %s --revision takes exactly one revision identifier') % (
125
219
                command_name,))
126
220
    return revisions[0]
127
221
 
196
290
    the --directory option is used to specify a different branch."""
197
291
    if directory is not None:
198
292
        return (None, Branch.open(directory), filename)
199
 
    return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
 
293
    return controldir.ControlDir.open_containing_tree_or_branch(filename)
200
294
 
201
295
 
202
296
# TODO: Make sure no commands unconditionally use the working directory as a
288
382
        from bzrlib.status import show_tree_status
289
383
 
290
384
        if revision and len(revision) > 2:
291
 
            raise errors.BzrCommandError('bzr status --revision takes exactly'
292
 
                                         ' one or two revision specifiers')
 
385
            raise errors.BzrCommandError(gettext('bzr status --revision takes exactly'
 
386
                                         ' one or two revision specifiers'))
293
387
 
294
388
        tree, relfile_list = WorkingTree.open_containing_paths(file_list)
295
389
        # Avoid asking for specific files when that is not needed.
332
426
    @display_command
333
427
    def run(self, revision_id=None, revision=None, directory=u'.'):
334
428
        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')
 
429
            raise errors.BzrCommandError(gettext('You can only supply one of'
 
430
                                         ' revision_id or --revision'))
337
431
        if revision_id is None and revision is None:
338
 
            raise errors.BzrCommandError('You must supply either'
339
 
                                         ' --revision or a revision_id')
 
432
            raise errors.BzrCommandError(gettext('You must supply either'
 
433
                                         ' --revision or a revision_id'))
340
434
 
341
 
        b = bzrdir.BzrDir.open_containing_tree_or_branch(directory)[1]
 
435
        b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
342
436
 
343
437
        revisions = b.repository.revisions
344
438
        if revisions is None:
345
 
            raise errors.BzrCommandError('Repository %r does not support '
346
 
                'access to raw revision texts')
 
439
            raise errors.BzrCommandError(gettext('Repository %r does not support '
 
440
                'access to raw revision texts'))
347
441
 
348
442
        b.repository.lock_read()
349
443
        try:
353
447
                try:
354
448
                    self.print_revision(revisions, revision_id)
355
449
                except errors.NoSuchRevision:
356
 
                    msg = "The repository %s contains no revision %s." % (
 
450
                    msg = gettext("The repository {0} contains no revision {1}.").format(
357
451
                        b.repository.base, revision_id)
358
452
                    raise errors.BzrCommandError(msg)
359
453
            elif revision is not None:
360
454
                for rev in revision:
361
455
                    if rev is None:
362
456
                        raise errors.BzrCommandError(
363
 
                            'You cannot specify a NULL revision.')
 
457
                            gettext('You cannot specify a NULL revision.'))
364
458
                    rev_id = rev.as_revision_id(b)
365
459
                    self.print_revision(revisions, rev_id)
366
460
        finally:
472
566
            location_list=['.']
473
567
 
474
568
        for location in location_list:
475
 
            d = bzrdir.BzrDir.open(location)
476
 
            
 
569
            d = controldir.ControlDir.open(location)
 
570
 
477
571
            try:
478
572
                working = d.open_workingtree()
479
573
            except errors.NoWorkingTree:
480
 
                raise errors.BzrCommandError("No working tree to remove")
 
574
                raise errors.BzrCommandError(gettext("No working tree to remove"))
481
575
            except errors.NotLocalUrl:
482
 
                raise errors.BzrCommandError("You cannot remove the working tree"
483
 
                                             " of a remote path")
 
576
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
577
                                             " of a remote path"))
484
578
            if not force:
485
579
                if (working.has_changes()):
486
580
                    raise errors.UncommittedChanges(working)
488
582
                    raise errors.ShelvedChanges(working)
489
583
 
490
584
            if working.user_url != working.branch.user_url:
491
 
                raise errors.BzrCommandError("You cannot remove the working tree"
492
 
                                             " from a lightweight checkout")
 
585
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
586
                                             " from a lightweight checkout"))
493
587
 
494
588
            d.destroy_workingtree()
495
589
 
527
621
                pass # There seems to be a real error here, so we'll reset
528
622
            else:
529
623
                # Refuse
530
 
                raise errors.BzrCommandError(
 
624
                raise errors.BzrCommandError(gettext(
531
625
                    'The tree does not appear to be corrupt. You probably'
532
626
                    ' want "bzr revert" instead. Use "--force" if you are'
533
 
                    ' sure you want to reset the working tree.')
 
627
                    ' sure you want to reset the working tree.'))
534
628
        if revision is None:
535
629
            revision_ids = None
536
630
        else:
539
633
            tree.reset_state(revision_ids)
540
634
        except errors.BzrError, e:
541
635
            if revision_ids is None:
542
 
                extra = (', the header appears corrupt, try passing -r -1'
543
 
                         ' to set the state to the last commit')
 
636
                extra = (gettext(', the header appears corrupt, try passing -r -1'
 
637
                         ' to set the state to the last commit'))
544
638
            else:
545
639
                extra = ''
546
 
            raise errors.BzrCommandError('failed to reset the tree state'
547
 
                                         + extra)
 
640
            raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
548
641
 
549
642
 
550
643
class cmd_revno(Command):
556
649
    _see_also = ['info']
557
650
    takes_args = ['location?']
558
651
    takes_options = [
559
 
        Option('tree', help='Show revno of working tree'),
 
652
        Option('tree', help='Show revno of working tree.'),
 
653
        'revision',
560
654
        ]
561
655
 
562
656
    @display_command
563
 
    def run(self, tree=False, location=u'.'):
 
657
    def run(self, tree=False, location=u'.', revision=None):
 
658
        if revision is not None and tree:
 
659
            raise errors.BzrCommandError(gettext("--tree and --revision can "
 
660
                "not be used together"))
 
661
 
564
662
        if tree:
565
663
            try:
566
664
                wt = WorkingTree.open_containing(location)[0]
567
665
                self.add_cleanup(wt.lock_read().unlock)
568
666
            except (errors.NoWorkingTree, errors.NotLocalUrl):
569
667
                raise errors.NoWorkingTree(location)
 
668
            b = wt.branch
570
669
            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
670
        else:
577
671
            b = Branch.open_containing(location)[0]
578
672
            self.add_cleanup(b.lock_read().unlock)
579
 
            revno = b.revno()
 
673
            if revision:
 
674
                if len(revision) != 1:
 
675
                    raise errors.BzrCommandError(gettext(
 
676
                        "Tags can only be placed on a single revision, "
 
677
                        "not on a range"))
 
678
                revid = revision[0].as_revision_id(b)
 
679
            else:
 
680
                revid = b.last_revision()
 
681
        try:
 
682
            revno_t = b.revision_id_to_dotted_revno(revid)
 
683
        except errors.NoSuchRevision:
 
684
            revno_t = ('???',)
 
685
        revno = ".".join(str(n) for n in revno_t)
580
686
        self.cleanup_now()
581
 
        self.outf.write(str(revno) + '\n')
 
687
        self.outf.write(revno + '\n')
582
688
 
583
689
 
584
690
class cmd_revision_info(Command):
591
697
        custom_help('directory',
592
698
            help='Branch to examine, '
593
699
                 'rather than the one containing the working directory.'),
594
 
        Option('tree', help='Show revno of working tree'),
 
700
        Option('tree', help='Show revno of working tree.'),
595
701
        ]
596
702
 
597
703
    @display_command
653
759
    are added.  This search proceeds recursively into versioned
654
760
    directories.  If no names are given '.' is assumed.
655
761
 
 
762
    A warning will be printed when nested trees are encountered,
 
763
    unless they are explicitly ignored.
 
764
 
656
765
    Therefore simply saying 'bzr add' will version all files that
657
766
    are currently unknown.
658
767
 
674
783
    
675
784
    Any files matching patterns in the ignore list will not be added
676
785
    unless they are explicitly mentioned.
 
786
    
 
787
    In recursive mode, files larger than the configuration option 
 
788
    add.maximum_file_size will be skipped. Named items are never skipped due
 
789
    to file size.
677
790
    """
678
791
    takes_args = ['file*']
679
792
    takes_options = [
706
819
            action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
707
820
                          to_file=self.outf, should_print=(not is_quiet()))
708
821
        else:
709
 
            action = bzrlib.add.AddAction(to_file=self.outf,
 
822
            action = bzrlib.add.AddWithSkipLargeAction(to_file=self.outf,
710
823
                should_print=(not is_quiet()))
711
824
 
712
825
        if base_tree:
719
832
            if verbose:
720
833
                for glob in sorted(ignored.keys()):
721
834
                    for path in ignored[glob]:
722
 
                        self.outf.write("ignored %s matching \"%s\"\n"
723
 
                                        % (path, glob))
 
835
                        self.outf.write(
 
836
                         gettext("ignored {0} matching \"{1}\"\n").format(
 
837
                         path, glob))
724
838
 
725
839
 
726
840
class cmd_mkdir(Command):
730
844
    """
731
845
 
732
846
    takes_args = ['dir+']
 
847
    takes_options = [
 
848
        Option(
 
849
            'parents',
 
850
            help='No error if existing, make parent directories as needed.',
 
851
            short_name='p'
 
852
            )
 
853
        ]
733
854
    encoding_type = 'replace'
734
855
 
735
 
    def run(self, dir_list):
736
 
        for d in dir_list:
737
 
            wt, dd = WorkingTree.open_containing(d)
738
 
            base = os.path.dirname(dd)
739
 
            id = wt.path2id(base)
740
 
            if id != None:
741
 
                os.mkdir(d)
742
 
                wt.add([dd])
743
 
                self.outf.write('added %s\n' % d)
 
856
    @classmethod
 
857
    def add_file_with_parents(cls, wt, relpath):
 
858
        if wt.path2id(relpath) is not None:
 
859
            return
 
860
        cls.add_file_with_parents(wt, osutils.dirname(relpath))
 
861
        wt.add([relpath])
 
862
 
 
863
    @classmethod
 
864
    def add_file_single(cls, wt, relpath):
 
865
        wt.add([relpath])
 
866
 
 
867
    def run(self, dir_list, parents=False):
 
868
        if parents:
 
869
            add_file = self.add_file_with_parents
 
870
        else:
 
871
            add_file = self.add_file_single
 
872
        for dir in dir_list:
 
873
            wt, relpath = WorkingTree.open_containing(dir)
 
874
            if parents:
 
875
                try:
 
876
                    os.makedirs(dir)
 
877
                except OSError, e:
 
878
                    if e.errno != errno.EEXIST:
 
879
                        raise
744
880
            else:
745
 
                raise errors.NotVersionedError(path=base)
 
881
                os.mkdir(dir)
 
882
            add_file(wt, relpath)
 
883
            if not is_quiet():
 
884
                self.outf.write(gettext('added %s\n') % dir)
746
885
 
747
886
 
748
887
class cmd_relpath(Command):
784
923
    @display_command
785
924
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
786
925
        if kind and kind not in ['file', 'directory', 'symlink']:
787
 
            raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
 
926
            raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
788
927
 
789
928
        revision = _get_one_revision('inventory', revision)
790
929
        work_tree, file_list = WorkingTree.open_containing_paths(file_list)
854
993
        if auto:
855
994
            return self.run_auto(names_list, after, dry_run)
856
995
        elif dry_run:
857
 
            raise errors.BzrCommandError('--dry-run requires --auto.')
 
996
            raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
858
997
        if names_list is None:
859
998
            names_list = []
860
999
        if len(names_list) < 2:
861
 
            raise errors.BzrCommandError("missing file argument")
 
1000
            raise errors.BzrCommandError(gettext("missing file argument"))
862
1001
        tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
 
1002
        for file_name in rel_names[0:-1]:
 
1003
            if file_name == '':
 
1004
                raise errors.BzrCommandError(gettext("can not move root of branch"))
863
1005
        self.add_cleanup(tree.lock_tree_write().unlock)
864
1006
        self._run(tree, names_list, rel_names, after)
865
1007
 
866
1008
    def run_auto(self, names_list, after, dry_run):
867
1009
        if names_list is not None and len(names_list) > 1:
868
 
            raise errors.BzrCommandError('Only one path may be specified to'
869
 
                                         ' --auto.')
 
1010
            raise errors.BzrCommandError(gettext('Only one path may be specified to'
 
1011
                                         ' --auto.'))
870
1012
        if after:
871
 
            raise errors.BzrCommandError('--after cannot be specified with'
872
 
                                         ' --auto.')
 
1013
            raise errors.BzrCommandError(gettext('--after cannot be specified with'
 
1014
                                         ' --auto.'))
873
1015
        work_tree, file_list = WorkingTree.open_containing_paths(
874
1016
            names_list, default_directory='.')
875
1017
        self.add_cleanup(work_tree.lock_tree_write().unlock)
905
1047
                    self.outf.write("%s => %s\n" % (src, dest))
906
1048
        else:
907
1049
            if len(names_list) != 2:
908
 
                raise errors.BzrCommandError('to mv multiple files the'
 
1050
                raise errors.BzrCommandError(gettext('to mv multiple files the'
909
1051
                                             ' destination must be a versioned'
910
 
                                             ' directory')
 
1052
                                             ' directory'))
911
1053
 
912
1054
            # for cicp file-systems: the src references an existing inventory
913
1055
            # item:
973
1115
    branches have diverged.
974
1116
 
975
1117
    If there is no default location set, the first pull will set it (use
976
 
    --no-remember to avoid settting it). After that, you can omit the
 
1118
    --no-remember to avoid setting it). After that, you can omit the
977
1119
    location to use the default.  To change the default, use --remember. The
978
1120
    value will only be saved if the remote location can be accessed.
979
1121
 
 
1122
    The --verbose option will display the revisions pulled using the log_format
 
1123
    configuration option. You can use a different format by overriding it with
 
1124
    -Olog_format=<other_format>.
 
1125
 
980
1126
    Note: The location can be specified either in the form of a branch,
981
1127
    or in the form of a path to a file containing a merge directive generated
982
1128
    with bzr send.
1019
1165
            self.add_cleanup(branch_to.lock_write().unlock)
1020
1166
 
1021
1167
        if tree_to is None and show_base:
1022
 
            raise errors.BzrCommandError("Need working tree for --show-base.")
 
1168
            raise errors.BzrCommandError(gettext("Need working tree for --show-base."))
1023
1169
 
1024
1170
        if local and not branch_to.get_bound_location():
1025
1171
            raise errors.LocalRequiresBoundBranch()
1035
1181
        stored_loc = branch_to.get_parent()
1036
1182
        if location is None:
1037
1183
            if stored_loc is None:
1038
 
                raise errors.BzrCommandError("No pull location known or"
1039
 
                                             " specified.")
 
1184
                raise errors.BzrCommandError(gettext("No pull location known or"
 
1185
                                             " specified."))
1040
1186
            else:
1041
1187
                display_url = urlutils.unescape_for_display(stored_loc,
1042
1188
                        self.outf.encoding)
1043
1189
                if not is_quiet():
1044
 
                    self.outf.write("Using saved parent location: %s\n" % display_url)
 
1190
                    self.outf.write(gettext("Using saved parent location: %s\n") % display_url)
1045
1191
                location = stored_loc
1046
1192
 
1047
1193
        revision = _get_one_revision('pull', revision)
1048
1194
        if mergeable is not None:
1049
1195
            if revision is not None:
1050
 
                raise errors.BzrCommandError(
1051
 
                    'Cannot use -r with merge directives or bundles')
 
1196
                raise errors.BzrCommandError(gettext(
 
1197
                    'Cannot use -r with merge directives or bundles'))
1052
1198
            mergeable.install_revisions(branch_to.repository)
1053
1199
            base_revision_id, revision_id, verified = \
1054
1200
                mergeable.get_merge_request(branch_to.repository)
1072
1218
                view_info=view_info)
1073
1219
            result = tree_to.pull(
1074
1220
                branch_from, overwrite, revision_id, change_reporter,
1075
 
                possible_transports=possible_transports, local=local,
1076
 
                show_base=show_base)
 
1221
                local=local, show_base=show_base)
1077
1222
        else:
1078
1223
            result = branch_to.pull(
1079
1224
                branch_from, overwrite, revision_id, local=local)
1110
1255
    After that you will be able to do a push without '--overwrite'.
1111
1256
 
1112
1257
    If there is no default push location set, the first push will set it (use
1113
 
    --no-remember to avoid settting it).  After that, you can omit the
 
1258
    --no-remember to avoid setting it).  After that, you can omit the
1114
1259
    location to use the default.  To change the default, use --remember. The
1115
1260
    value will only be saved if the remote location can be accessed.
 
1261
 
 
1262
    The --verbose option will display the revisions pushed using the log_format
 
1263
    configuration option. You can use a different format by overriding it with
 
1264
    -Olog_format=<other_format>.
1116
1265
    """
1117
1266
 
1118
1267
    _see_also = ['pull', 'update', 'working-trees']
1156
1305
            directory = '.'
1157
1306
        # Get the source branch
1158
1307
        (tree, br_from,
1159
 
         _unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
 
1308
         _unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
1160
1309
        # Get the tip's revision_id
1161
1310
        revision = _get_one_revision('push', revision)
1162
1311
        if revision is not None:
1183
1332
                    # error by the feedback given to them. RBC 20080227.
1184
1333
                    stacked_on = parent_url
1185
1334
            if not stacked_on:
1186
 
                raise errors.BzrCommandError(
1187
 
                    "Could not determine branch to refer to.")
 
1335
                raise errors.BzrCommandError(gettext(
 
1336
                    "Could not determine branch to refer to."))
1188
1337
 
1189
1338
        # Get the destination location
1190
1339
        if location is None:
1191
1340
            stored_loc = br_from.get_push_location()
1192
1341
            if stored_loc is None:
1193
 
                raise errors.BzrCommandError(
1194
 
                    "No push location known or specified.")
 
1342
                parent_loc = br_from.get_parent()
 
1343
                if parent_loc:
 
1344
                    raise errors.BzrCommandError(gettext(
 
1345
                        "No push location known or specified. To push to the "
 
1346
                        "parent branch (at %s), use 'bzr push :parent'." %
 
1347
                        urlutils.unescape_for_display(parent_loc,
 
1348
                            self.outf.encoding)))
 
1349
                else:
 
1350
                    raise errors.BzrCommandError(gettext(
 
1351
                        "No push location known or specified."))
1195
1352
            else:
1196
1353
                display_url = urlutils.unescape_for_display(stored_loc,
1197
1354
                        self.outf.encoding)
1198
 
                self.outf.write("Using saved push location: %s\n" % display_url)
 
1355
                note(gettext("Using saved push location: %s") % display_url)
1199
1356
                location = stored_loc
1200
1357
 
1201
1358
        _show_push_branch(br_from, revision_id, location, self.outf,
1259
1416
                deprecated_name=self.invoked_as,
1260
1417
                recommended_name='branch',
1261
1418
                deprecated_in_version='2.4')
1262
 
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
 
1419
        accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1263
1420
            from_location)
1264
1421
        if not (hardlink or files_from):
1265
1422
            # accelerator_tree is usually slower because you have to read N
1278
1435
            # RBC 20060209
1279
1436
            revision_id = br_from.last_revision()
1280
1437
        if to_location is None:
1281
 
            to_location = urlutils.derive_to_location(from_location)
 
1438
            to_location = getattr(br_from, "name", None)
 
1439
            if not to_location:
 
1440
                to_location = urlutils.derive_to_location(from_location)
1282
1441
        to_transport = transport.get_transport(to_location)
1283
1442
        try:
1284
1443
            to_transport.mkdir('.')
1285
1444
        except errors.FileExists:
1286
 
            if not use_existing_dir:
1287
 
                raise errors.BzrCommandError('Target directory "%s" '
1288
 
                    'already exists.' % to_location)
 
1445
            try:
 
1446
                to_dir = controldir.ControlDir.open_from_transport(
 
1447
                    to_transport)
 
1448
            except errors.NotBranchError:
 
1449
                if not use_existing_dir:
 
1450
                    raise errors.BzrCommandError(gettext('Target directory "%s" '
 
1451
                        'already exists.') % to_location)
 
1452
                else:
 
1453
                    to_dir = None
1289
1454
            else:
1290
1455
                try:
1291
 
                    bzrdir.BzrDir.open_from_transport(to_transport)
 
1456
                    to_dir.open_branch()
1292
1457
                except errors.NotBranchError:
1293
1458
                    pass
1294
1459
                else:
1295
1460
                    raise errors.AlreadyBranchError(to_location)
1296
1461
        except errors.NoSuchFile:
1297
 
            raise errors.BzrCommandError('Parent of "%s" does not exist.'
 
1462
            raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1298
1463
                                         % to_location)
1299
 
        try:
1300
 
            # preserve whatever source format we have.
1301
 
            dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1302
 
                                        possible_transports=[to_transport],
1303
 
                                        accelerator_tree=accelerator_tree,
1304
 
                                        hardlink=hardlink, stacked=stacked,
1305
 
                                        force_new_repo=standalone,
1306
 
                                        create_tree_if_local=not no_tree,
1307
 
                                        source_branch=br_from)
1308
 
            branch = dir.open_branch()
1309
 
        except errors.NoSuchRevision:
1310
 
            to_transport.delete_tree('.')
1311
 
            msg = "The branch %s has no revision %s." % (from_location,
1312
 
                revision)
1313
 
            raise errors.BzrCommandError(msg)
 
1464
        else:
 
1465
            to_dir = None
 
1466
        if to_dir is None:
 
1467
            try:
 
1468
                # preserve whatever source format we have.
 
1469
                to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
 
1470
                                            possible_transports=[to_transport],
 
1471
                                            accelerator_tree=accelerator_tree,
 
1472
                                            hardlink=hardlink, stacked=stacked,
 
1473
                                            force_new_repo=standalone,
 
1474
                                            create_tree_if_local=not no_tree,
 
1475
                                            source_branch=br_from)
 
1476
                branch = to_dir.open_branch(
 
1477
                    possible_transports=[
 
1478
                        br_from.bzrdir.root_transport, to_transport])
 
1479
            except errors.NoSuchRevision:
 
1480
                to_transport.delete_tree('.')
 
1481
                msg = gettext("The branch {0} has no revision {1}.").format(
 
1482
                    from_location, revision)
 
1483
                raise errors.BzrCommandError(msg)
 
1484
        else:
 
1485
            try:
 
1486
                to_repo = to_dir.open_repository()
 
1487
            except errors.NoRepositoryPresent:
 
1488
                to_repo = to_dir.create_repository()
 
1489
            to_repo.fetch(br_from.repository, revision_id=revision_id)
 
1490
            branch = br_from.sprout(to_dir, revision_id=revision_id)
1314
1491
        _merge_tags_if_possible(br_from, branch)
1315
1492
        # If the source branch is stacked, the new branch may
1316
1493
        # be stacked whether we asked for that explicitly or not.
1317
1494
        # We therefore need a try/except here and not just 'if stacked:'
1318
1495
        try:
1319
 
            note('Created new stacked branch referring to %s.' %
 
1496
            note(gettext('Created new stacked branch referring to %s.') %
1320
1497
                branch.get_stacked_on_url())
1321
1498
        except (errors.NotStacked, errors.UnstackableBranchFormat,
1322
1499
            errors.UnstackableRepositoryFormat), e:
1323
 
            note('Branched %d revision(s).' % branch.revno())
 
1500
            note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1324
1501
        if bind:
1325
1502
            # Bind to the parent
1326
1503
            parent_branch = Branch.open(from_location)
1327
1504
            branch.bind(parent_branch)
1328
 
            note('New branch bound to %s' % from_location)
 
1505
            note(gettext('New branch bound to %s') % from_location)
1329
1506
        if switch:
1330
1507
            # Switch to the new branch
1331
1508
            wt, _ = WorkingTree.open_containing('.')
1332
1509
            _mod_switch.switch(wt.bzrdir, branch)
1333
 
            note('Switched to branch: %s',
 
1510
            note(gettext('Switched to branch: %s'),
1334
1511
                urlutils.unescape_for_display(branch.base, 'utf-8'))
1335
1512
 
1336
1513
 
 
1514
class cmd_branches(Command):
 
1515
    __doc__ = """List the branches available at the current location.
 
1516
 
 
1517
    This command will print the names of all the branches at the current
 
1518
    location.
 
1519
    """
 
1520
 
 
1521
    takes_args = ['location?']
 
1522
    takes_options = [
 
1523
                  Option('recursive', short_name='R',
 
1524
                         help='Recursively scan for branches rather than '
 
1525
                              'just looking in the specified location.')]
 
1526
 
 
1527
    def run(self, location=".", recursive=False):
 
1528
        if recursive:
 
1529
            t = transport.get_transport(location)
 
1530
            if not t.listable():
 
1531
                raise errors.BzrCommandError(
 
1532
                    "Can't scan this type of location.")
 
1533
            for b in controldir.ControlDir.find_branches(t):
 
1534
                self.outf.write("%s\n" % urlutils.unescape_for_display(
 
1535
                    urlutils.relative_url(t.base, b.base),
 
1536
                    self.outf.encoding).rstrip("/"))
 
1537
        else:
 
1538
            dir = controldir.ControlDir.open_containing(location)[0]
 
1539
            try:
 
1540
                active_branch = dir.open_branch(name="")
 
1541
            except errors.NotBranchError:
 
1542
                active_branch = None
 
1543
            branches = dir.get_branches()
 
1544
            names = {}
 
1545
            for name, branch in branches.iteritems():
 
1546
                if name == "":
 
1547
                    continue
 
1548
                active = (active_branch is not None and
 
1549
                          active_branch.base == branch.base)
 
1550
                names[name] = active
 
1551
            # Only mention the current branch explicitly if it's not
 
1552
            # one of the colocated branches
 
1553
            if not any(names.values()) and active_branch is not None:
 
1554
                self.outf.write("* %s\n" % gettext("(default)"))
 
1555
            for name in sorted(names.keys()):
 
1556
                active = names[name]
 
1557
                if active:
 
1558
                    prefix = "*"
 
1559
                else:
 
1560
                    prefix = " "
 
1561
                self.outf.write("%s %s\n" % (
 
1562
                    prefix, name.encode(self.outf.encoding)))
 
1563
 
 
1564
 
1337
1565
class cmd_checkout(Command):
1338
1566
    __doc__ = """Create a new checkout of an existing branch.
1339
1567
 
1378
1606
        if branch_location is None:
1379
1607
            branch_location = osutils.getcwd()
1380
1608
            to_location = branch_location
1381
 
        accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
 
1609
        accelerator_tree, source = controldir.ControlDir.open_tree_or_branch(
1382
1610
            branch_location)
1383
1611
        if not (hardlink or files_from):
1384
1612
            # accelerator_tree is usually slower because you have to read N
1439
1667
 
1440
1668
 
1441
1669
class cmd_update(Command):
1442
 
    __doc__ = """Update a tree to have the latest code committed to its branch.
1443
 
 
1444
 
    This will perform a merge into the working tree, and may generate
1445
 
    conflicts. If you have any local changes, you will still
1446
 
    need to commit them after the update for the update to be complete.
1447
 
 
1448
 
    If you want to discard your local changes, you can just do a
1449
 
    'bzr revert' instead of 'bzr commit' after the update.
1450
 
 
1451
 
    If you want to restore a file that has been removed locally, use
1452
 
    'bzr revert' instead of 'bzr update'.
1453
 
 
1454
 
    If the tree's branch is bound to a master branch, it will also update
 
1670
    __doc__ = """Update a working tree to a new revision.
 
1671
 
 
1672
    This will perform a merge of the destination revision (the tip of the
 
1673
    branch, or the specified revision) into the working tree, and then make
 
1674
    that revision the basis revision for the working tree.  
 
1675
 
 
1676
    You can use this to visit an older revision, or to update a working tree
 
1677
    that is out of date from its branch.
 
1678
    
 
1679
    If there are any uncommitted changes in the tree, they will be carried
 
1680
    across and remain as uncommitted changes after the update.  To discard
 
1681
    these changes, use 'bzr revert'.  The uncommitted changes may conflict
 
1682
    with the changes brought in by the change in basis revision.
 
1683
 
 
1684
    If the tree's branch is bound to a master branch, bzr will also update
1455
1685
    the branch from the master.
 
1686
 
 
1687
    You cannot update just a single file or directory, because each Bazaar
 
1688
    working tree has just a single basis revision.  If you want to restore a
 
1689
    file that has been removed locally, use 'bzr revert' instead of 'bzr
 
1690
    update'.  If you want to restore a file to its state in a previous
 
1691
    revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
 
1692
    out the old content of that file to a new location.
 
1693
 
 
1694
    The 'dir' argument, if given, must be the location of the root of a
 
1695
    working tree to update.  By default, the working tree that contains the 
 
1696
    current working directory is used.
1456
1697
    """
1457
1698
 
1458
1699
    _see_also = ['pull', 'working-trees', 'status-flags']
1463
1704
                     ]
1464
1705
    aliases = ['up']
1465
1706
 
1466
 
    def run(self, dir='.', revision=None, show_base=None):
 
1707
    def run(self, dir=None, revision=None, show_base=None):
1467
1708
        if revision is not None and len(revision) != 1:
1468
 
            raise errors.BzrCommandError(
1469
 
                        "bzr update --revision takes exactly one revision")
1470
 
        tree = WorkingTree.open_containing(dir)[0]
 
1709
            raise errors.BzrCommandError(gettext(
 
1710
                "bzr update --revision takes exactly one revision"))
 
1711
        if dir is None:
 
1712
            tree = WorkingTree.open_containing('.')[0]
 
1713
        else:
 
1714
            tree, relpath = WorkingTree.open_containing(dir)
 
1715
            if relpath:
 
1716
                # See bug 557886.
 
1717
                raise errors.BzrCommandError(gettext(
 
1718
                    "bzr update can only update a whole tree, "
 
1719
                    "not a file or subdirectory"))
1471
1720
        branch = tree.branch
1472
1721
        possible_transports = []
1473
1722
        master = branch.get_master_branch(
1497
1746
            revision_id = branch.last_revision()
1498
1747
        if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1499
1748
            revno = branch.revision_id_to_dotted_revno(revision_id)
1500
 
            note("Tree is up to date at revision %s of branch %s" %
1501
 
                ('.'.join(map(str, revno)), branch_location))
 
1749
            note(gettext("Tree is up to date at revision {0} of branch {1}"
 
1750
                        ).format('.'.join(map(str, revno)), branch_location))
1502
1751
            return 0
1503
1752
        view_info = _get_view_info_for_change_reporter(tree)
1504
1753
        change_reporter = delta._ChangeReporter(
1512
1761
                old_tip=old_tip,
1513
1762
                show_base=show_base)
1514
1763
        except errors.NoSuchRevision, e:
1515
 
            raise errors.BzrCommandError(
 
1764
            raise errors.BzrCommandError(gettext(
1516
1765
                                  "branch has no revision %s\n"
1517
1766
                                  "bzr update --revision only works"
1518
 
                                  " for a revision in the branch history"
 
1767
                                  " for a revision in the branch history")
1519
1768
                                  % (e.revision))
1520
1769
        revno = tree.branch.revision_id_to_dotted_revno(
1521
1770
            _mod_revision.ensure_null(tree.last_revision()))
1522
 
        note('Updated to revision %s of branch %s' %
1523
 
             ('.'.join(map(str, revno)), branch_location))
 
1771
        note(gettext('Updated to revision {0} of branch {1}').format(
 
1772
             '.'.join(map(str, revno)), branch_location))
1524
1773
        parent_ids = tree.get_parent_ids()
1525
1774
        if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1526
 
            note('Your local commits will now show as pending merges with '
1527
 
                 "'bzr status', and can be committed with 'bzr commit'.")
 
1775
            note(gettext('Your local commits will now show as pending merges with '
 
1776
                 "'bzr status', and can be committed with 'bzr commit'."))
1528
1777
        if conflicts != 0:
1529
1778
            return 1
1530
1779
        else:
1571
1820
        else:
1572
1821
            noise_level = 0
1573
1822
        from bzrlib.info import show_bzrdir_info
1574
 
        show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
 
1823
        show_bzrdir_info(controldir.ControlDir.open_containing(location)[0],
1575
1824
                         verbose=noise_level, outfile=self.outf)
1576
1825
 
1577
1826
 
1602
1851
    def run(self, file_list, verbose=False, new=False,
1603
1852
        file_deletion_strategy='safe'):
1604
1853
        if file_deletion_strategy == 'force':
1605
 
            note("(The --force option is deprecated, rather use --no-backup "
1606
 
                "in future.)")
 
1854
            note(gettext("(The --force option is deprecated, rather use --no-backup "
 
1855
                "in future.)"))
1607
1856
            file_deletion_strategy = 'no-backup'
1608
1857
 
1609
1858
        tree, file_list = WorkingTree.open_containing_paths(file_list)
1619
1868
                specific_files=file_list).added
1620
1869
            file_list = sorted([f[0] for f in added], reverse=True)
1621
1870
            if len(file_list) == 0:
1622
 
                raise errors.BzrCommandError('No matching files.')
 
1871
                raise errors.BzrCommandError(gettext('No matching files.'))
1623
1872
        elif file_list is None:
1624
1873
            # missing files show up in iter_changes(basis) as
1625
1874
            # versioned-with-no-kind.
1709
1958
 
1710
1959
    def run(self, branch=".", canonicalize_chks=False):
1711
1960
        from bzrlib.reconcile import reconcile
1712
 
        dir = bzrdir.BzrDir.open(branch)
 
1961
        dir = controldir.ControlDir.open(branch)
1713
1962
        reconcile(dir, canonicalize_chks=canonicalize_chks)
1714
1963
 
1715
1964
 
1724
1973
    @display_command
1725
1974
    def run(self, location="."):
1726
1975
        branch = Branch.open_containing(location)[0]
1727
 
        for revid in branch.revision_history():
 
1976
        self.add_cleanup(branch.lock_read().unlock)
 
1977
        graph = branch.repository.get_graph()
 
1978
        history = list(graph.iter_lefthand_ancestry(branch.last_revision(),
 
1979
            [_mod_revision.NULL_REVISION]))
 
1980
        for revid in reversed(history):
1728
1981
            self.outf.write(revid)
1729
1982
            self.outf.write('\n')
1730
1983
 
1791
2044
                help='Specify a format for this branch. '
1792
2045
                'See "help formats".',
1793
2046
                lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1794
 
                converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
2047
                converter=lambda name: controldir.format_registry.make_bzrdir(name),
1795
2048
                value_switches=True,
1796
2049
                title="Branch format",
1797
2050
                ),
1804
2057
    def run(self, location=None, format=None, append_revisions_only=False,
1805
2058
            create_prefix=False, no_tree=False):
1806
2059
        if format is None:
1807
 
            format = bzrdir.format_registry.make_bzrdir('default')
 
2060
            format = controldir.format_registry.make_bzrdir('default')
1808
2061
        if location is None:
1809
2062
            location = u'.'
1810
2063
 
1819
2072
            to_transport.ensure_base()
1820
2073
        except errors.NoSuchFile:
1821
2074
            if not create_prefix:
1822
 
                raise errors.BzrCommandError("Parent directory of %s"
 
2075
                raise errors.BzrCommandError(gettext("Parent directory of %s"
1823
2076
                    " does not exist."
1824
2077
                    "\nYou may supply --create-prefix to create all"
1825
 
                    " leading parent directories."
 
2078
                    " leading parent directories.")
1826
2079
                    % location)
1827
2080
            to_transport.create_prefix()
1828
2081
 
1829
2082
        try:
1830
 
            a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
 
2083
            a_bzrdir = controldir.ControlDir.open_from_transport(to_transport)
1831
2084
        except errors.NotBranchError:
1832
2085
            # really a NotBzrDir error...
1833
 
            create_branch = bzrdir.BzrDir.create_branch_convenience
 
2086
            create_branch = controldir.ControlDir.create_branch_convenience
1834
2087
            if no_tree:
1835
2088
                force_new_tree = False
1836
2089
            else:
1847
2100
                        raise errors.BranchExistsWithoutWorkingTree(location)
1848
2101
                raise errors.AlreadyBranchError(location)
1849
2102
            branch = a_bzrdir.create_branch()
1850
 
            if not no_tree:
 
2103
            if not no_tree and not a_bzrdir.has_workingtree():
1851
2104
                a_bzrdir.create_workingtree()
1852
2105
        if append_revisions_only:
1853
2106
            try:
1854
2107
                branch.set_append_revisions_only(True)
1855
2108
            except errors.UpgradeRequired:
1856
 
                raise errors.BzrCommandError('This branch format cannot be set'
1857
 
                    ' to append-revisions-only.  Try --default.')
 
2109
                raise errors.BzrCommandError(gettext('This branch format cannot be set'
 
2110
                    ' to append-revisions-only.  Try --default.'))
1858
2111
        if not is_quiet():
1859
2112
            from bzrlib.info import describe_layout, describe_format
1860
2113
            try:
1864
2117
            repository = branch.repository
1865
2118
            layout = describe_layout(repository, branch, tree).lower()
1866
2119
            format = describe_format(a_bzrdir, repository, branch, tree)
1867
 
            self.outf.write("Created a %s (format: %s)\n" % (layout, format))
 
2120
            self.outf.write(gettext("Created a {0} (format: {1})\n").format(
 
2121
                  layout, format))
1868
2122
            if repository.is_shared():
1869
2123
                #XXX: maybe this can be refactored into transport.path_or_url()
1870
2124
                url = repository.bzrdir.root_transport.external_url()
1872
2126
                    url = urlutils.local_path_from_url(url)
1873
2127
                except errors.InvalidURL:
1874
2128
                    pass
1875
 
                self.outf.write("Using shared repository: %s\n" % url)
 
2129
                self.outf.write(gettext("Using shared repository: %s\n") % url)
1876
2130
 
1877
2131
 
1878
2132
class cmd_init_repository(Command):
1908
2162
    takes_options = [RegistryOption('format',
1909
2163
                            help='Specify a format for this repository. See'
1910
2164
                                 ' "bzr help formats" for details.',
1911
 
                            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1912
 
                            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
2165
                            lazy_registry=('bzrlib.controldir', 'format_registry'),
 
2166
                            converter=lambda name: controldir.format_registry.make_bzrdir(name),
1913
2167
                            value_switches=True, title='Repository format'),
1914
2168
                     Option('no-trees',
1915
2169
                             help='Branches in the repository will default to'
1919
2173
 
1920
2174
    def run(self, location, format=None, no_trees=False):
1921
2175
        if format is None:
1922
 
            format = bzrdir.format_registry.make_bzrdir('default')
 
2176
            format = controldir.format_registry.make_bzrdir('default')
1923
2177
 
1924
2178
        if location is None:
1925
2179
            location = '.'
1926
2180
 
1927
2181
        to_transport = transport.get_transport(location)
1928
 
        to_transport.ensure_base()
1929
2182
 
1930
 
        newdir = format.initialize_on_transport(to_transport)
1931
 
        repo = newdir.create_repository(shared=True)
1932
 
        repo.set_make_working_trees(not no_trees)
 
2183
        (repo, newdir, require_stacking, repository_policy) = (
 
2184
            format.initialize_on_transport_ex(to_transport,
 
2185
            create_prefix=True, make_working_trees=not no_trees,
 
2186
            shared_repo=True, force_new_repo=True,
 
2187
            use_existing_dir=True,
 
2188
            repo_format_name=format.repository_format.get_format_string()))
1933
2189
        if not is_quiet():
1934
2190
            from bzrlib.info import show_bzrdir_info
1935
 
            show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
 
2191
            show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
1936
2192
 
1937
2193
 
1938
2194
class cmd_diff(Command):
2069
2325
        elif ':' in prefix:
2070
2326
            old_label, new_label = prefix.split(":")
2071
2327
        else:
2072
 
            raise errors.BzrCommandError(
 
2328
            raise errors.BzrCommandError(gettext(
2073
2329
                '--prefix expects two values separated by a colon'
2074
 
                ' (eg "old/:new/")')
 
2330
                ' (eg "old/:new/")'))
2075
2331
 
2076
2332
        if revision and len(revision) > 2:
2077
 
            raise errors.BzrCommandError('bzr diff --revision takes exactly'
2078
 
                                         ' one or two revision specifiers')
 
2333
            raise errors.BzrCommandError(gettext('bzr diff --revision takes exactly'
 
2334
                                         ' one or two revision specifiers'))
2079
2335
 
2080
2336
        if using is not None and format is not None:
2081
 
            raise errors.BzrCommandError('--using and --format are mutually '
2082
 
                'exclusive.')
 
2337
            raise errors.BzrCommandError(gettext(
 
2338
                '{0} and {1} are mutually exclusive').format(
 
2339
                '--using', '--format'))
2083
2340
 
2084
2341
        (old_tree, new_tree,
2085
2342
         old_branch, new_branch,
2193
2450
    try:
2194
2451
        return int(limitstring)
2195
2452
    except ValueError:
2196
 
        msg = "The limit argument must be an integer."
 
2453
        msg = gettext("The limit argument must be an integer.")
2197
2454
        raise errors.BzrCommandError(msg)
2198
2455
 
2199
2456
 
2201
2458
    try:
2202
2459
        return int(s)
2203
2460
    except ValueError:
2204
 
        msg = "The levels argument must be an integer."
 
2461
        msg = gettext("The levels argument must be an integer.")
2205
2462
        raise errors.BzrCommandError(msg)
2206
2463
 
2207
2464
 
2317
2574
 
2318
2575
    :Other filtering:
2319
2576
 
2320
 
      The --message option can be used for finding revisions that match a
2321
 
      regular expression in a commit message.
 
2577
      The --match option can be used for finding revisions that match a
 
2578
      regular expression in a commit message, committer, author or bug.
 
2579
      Specifying the option several times will match any of the supplied
 
2580
      expressions. --match-author, --match-bugs, --match-committer and
 
2581
      --match-message can be used to only match a specific field.
2322
2582
 
2323
2583
    :Tips & tricks:
2324
2584
 
2384
2644
                   argname='N',
2385
2645
                   type=_parse_levels),
2386
2646
            Option('message',
2387
 
                   short_name='m',
2388
2647
                   help='Show revisions whose message matches this '
2389
2648
                        'regular expression.',
2390
 
                   type=str),
 
2649
                   type=str,
 
2650
                   hidden=True),
2391
2651
            Option('limit',
2392
2652
                   short_name='l',
2393
2653
                   help='Limit the output to the first N revisions.',
2396
2656
            Option('show-diff',
2397
2657
                   short_name='p',
2398
2658
                   help='Show changes made in each revision as a patch.'),
2399
 
            Option('include-merges',
 
2659
            Option('include-merged',
2400
2660
                   help='Show merged revisions like --levels 0 does.'),
 
2661
            Option('include-merges', hidden=True,
 
2662
                   help='Historical alias for --include-merged.'),
 
2663
            Option('omit-merges',
 
2664
                   help='Do not report commits with more than one parent.'),
2401
2665
            Option('exclude-common-ancestry',
2402
2666
                   help='Display only the revisions that are not part'
2403
 
                   ' of both ancestries (require -rX..Y)'
 
2667
                   ' of both ancestries (require -rX..Y).'
2404
2668
                   ),
2405
2669
            Option('signatures',
2406
 
                   help='Show digital signature validity'),
 
2670
                   help='Show digital signature validity.'),
 
2671
            ListOption('match',
 
2672
                short_name='m',
 
2673
                help='Show revisions whose properties match this '
 
2674
                'expression.',
 
2675
                type=str),
 
2676
            ListOption('match-message',
 
2677
                   help='Show revisions whose message matches this '
 
2678
                   'expression.',
 
2679
                type=str),
 
2680
            ListOption('match-committer',
 
2681
                   help='Show revisions whose committer matches this '
 
2682
                   'expression.',
 
2683
                type=str),
 
2684
            ListOption('match-author',
 
2685
                   help='Show revisions whose authors match this '
 
2686
                   'expression.',
 
2687
                type=str),
 
2688
            ListOption('match-bugs',
 
2689
                   help='Show revisions whose bugs match this '
 
2690
                   'expression.',
 
2691
                type=str)
2407
2692
            ]
2408
2693
    encoding_type = 'replace'
2409
2694
 
2419
2704
            message=None,
2420
2705
            limit=None,
2421
2706
            show_diff=False,
2422
 
            include_merges=False,
 
2707
            include_merged=None,
2423
2708
            authors=None,
2424
2709
            exclude_common_ancestry=False,
2425
2710
            signatures=False,
 
2711
            match=None,
 
2712
            match_message=None,
 
2713
            match_committer=None,
 
2714
            match_author=None,
 
2715
            match_bugs=None,
 
2716
            omit_merges=False,
 
2717
            include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2426
2718
            ):
2427
2719
        from bzrlib.log import (
2428
2720
            Logger,
2430
2722
            _get_info_for_log_files,
2431
2723
            )
2432
2724
        direction = (forward and 'forward') or 'reverse'
 
2725
        if symbol_versioning.deprecated_passed(include_merges):
 
2726
            ui.ui_factory.show_user_warning(
 
2727
                'deprecated_command_option',
 
2728
                deprecated_name='--include-merges',
 
2729
                recommended_name='--include-merged',
 
2730
                deprecated_in_version='2.5',
 
2731
                command=self.invoked_as)
 
2732
            if include_merged is None:
 
2733
                include_merged = include_merges
 
2734
            else:
 
2735
                raise errors.BzrCommandError(gettext(
 
2736
                    '{0} and {1} are mutually exclusive').format(
 
2737
                    '--include-merges', '--include-merged'))
 
2738
        if include_merged is None:
 
2739
            include_merged = False
2433
2740
        if (exclude_common_ancestry
2434
2741
            and (revision is None or len(revision) != 2)):
2435
 
            raise errors.BzrCommandError(
2436
 
                '--exclude-common-ancestry requires -r with two revisions')
2437
 
        if include_merges:
 
2742
            raise errors.BzrCommandError(gettext(
 
2743
                '--exclude-common-ancestry requires -r with two revisions'))
 
2744
        if include_merged:
2438
2745
            if levels is None:
2439
2746
                levels = 0
2440
2747
            else:
2441
 
                raise errors.BzrCommandError(
2442
 
                    '--levels and --include-merges are mutually exclusive')
 
2748
                raise errors.BzrCommandError(gettext(
 
2749
                    '{0} and {1} are mutually exclusive').format(
 
2750
                    '--levels', '--include-merged'))
2443
2751
 
2444
2752
        if change is not None:
2445
2753
            if len(change) > 1:
2446
2754
                raise errors.RangeInChangeOption()
2447
2755
            if revision is not None:
2448
 
                raise errors.BzrCommandError(
2449
 
                    '--revision and --change are mutually exclusive')
 
2756
                raise errors.BzrCommandError(gettext(
 
2757
                    '{0} and {1} are mutually exclusive').format(
 
2758
                    '--revision', '--change'))
2450
2759
            else:
2451
2760
                revision = change
2452
2761
 
2458
2767
                revision, file_list, self.add_cleanup)
2459
2768
            for relpath, file_id, kind in file_info_list:
2460
2769
                if file_id is None:
2461
 
                    raise errors.BzrCommandError(
2462
 
                        "Path unknown at end or start of revision range: %s" %
 
2770
                    raise errors.BzrCommandError(gettext(
 
2771
                        "Path unknown at end or start of revision range: %s") %
2463
2772
                        relpath)
2464
2773
                # If the relpath is the top of the tree, we log everything
2465
2774
                if relpath == '':
2477
2786
                location = revision[0].get_branch()
2478
2787
            else:
2479
2788
                location = '.'
2480
 
            dir, relpath = bzrdir.BzrDir.open_containing(location)
 
2789
            dir, relpath = controldir.ControlDir.open_containing(location)
2481
2790
            b = dir.open_branch()
2482
2791
            self.add_cleanup(b.lock_read().unlock)
2483
2792
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2531
2840
        match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2532
2841
            or delta_type or partial_history)
2533
2842
 
 
2843
        match_dict = {}
 
2844
        if match:
 
2845
            match_dict[''] = match
 
2846
        if match_message:
 
2847
            match_dict['message'] = match_message
 
2848
        if match_committer:
 
2849
            match_dict['committer'] = match_committer
 
2850
        if match_author:
 
2851
            match_dict['author'] = match_author
 
2852
        if match_bugs:
 
2853
            match_dict['bugs'] = match_bugs
 
2854
 
2534
2855
        # Build the LogRequest and execute it
2535
2856
        if len(file_ids) == 0:
2536
2857
            file_ids = None
2539
2860
            start_revision=rev1, end_revision=rev2, limit=limit,
2540
2861
            message_search=message, delta_type=delta_type,
2541
2862
            diff_type=diff_type, _match_using_deltas=match_using_deltas,
2542
 
            exclude_common_ancestry=exclude_common_ancestry,
2543
 
            signature=signatures
 
2863
            exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
 
2864
            signature=signatures, omit_merges=omit_merges,
2544
2865
            )
2545
2866
        Logger(b, rqst).show(lf)
2546
2867
 
2563
2884
            # b is taken from revision[0].get_branch(), and
2564
2885
            # show_log will use its revision_history. Having
2565
2886
            # different branches will lead to weird behaviors.
2566
 
            raise errors.BzrCommandError(
 
2887
            raise errors.BzrCommandError(gettext(
2567
2888
                "bzr %s doesn't accept two revisions in different"
2568
 
                " branches." % command_name)
 
2889
                " branches.") % command_name)
2569
2890
        if start_spec.spec is None:
2570
2891
            # Avoid loading all the history.
2571
2892
            rev1 = RevisionInfo(branch, None, None)
2579
2900
        else:
2580
2901
            rev2 = end_spec.in_history(branch)
2581
2902
    else:
2582
 
        raise errors.BzrCommandError(
2583
 
            'bzr %s --revision takes one or two values.' % command_name)
 
2903
        raise errors.BzrCommandError(gettext(
 
2904
            'bzr %s --revision takes one or two values.') % command_name)
2584
2905
    return rev1, rev2
2585
2906
 
2586
2907
 
2657
2978
            null=False, kind=None, show_ids=False, path=None, directory=None):
2658
2979
 
2659
2980
        if kind and kind not in ('file', 'directory', 'symlink'):
2660
 
            raise errors.BzrCommandError('invalid kind specified')
 
2981
            raise errors.BzrCommandError(gettext('invalid kind specified'))
2661
2982
 
2662
2983
        if verbose and null:
2663
 
            raise errors.BzrCommandError('Cannot set both --verbose and --null')
 
2984
            raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
2664
2985
        all = not (unknown or versioned or ignored)
2665
2986
 
2666
2987
        selection = {'I':ignored, '?':unknown, 'V':versioned}
2669
2990
            fs_path = '.'
2670
2991
        else:
2671
2992
            if from_root:
2672
 
                raise errors.BzrCommandError('cannot specify both --from-root'
2673
 
                                             ' and PATH')
 
2993
                raise errors.BzrCommandError(gettext('cannot specify both --from-root'
 
2994
                                             ' and PATH'))
2674
2995
            fs_path = path
2675
2996
        tree, branch, relpath = \
2676
2997
            _open_directory_or_containing_tree_or_branch(fs_path, directory)
2692
3013
            if view_files:
2693
3014
                apply_view = True
2694
3015
                view_str = views.view_display_str(view_files)
2695
 
                note("Ignoring files outside view. View is %s" % view_str)
 
3016
                note(gettext("Ignoring files outside view. View is %s") % view_str)
2696
3017
 
2697
3018
        self.add_cleanup(tree.lock_read().unlock)
2698
3019
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2845
3166
                self.outf.write("%s\n" % pattern)
2846
3167
            return
2847
3168
        if not name_pattern_list:
2848
 
            raise errors.BzrCommandError("ignore requires at least one "
2849
 
                "NAME_PATTERN or --default-rules.")
 
3169
            raise errors.BzrCommandError(gettext("ignore requires at least one "
 
3170
                "NAME_PATTERN or --default-rules."))
2850
3171
        name_pattern_list = [globbing.normalize_pattern(p)
2851
3172
                             for p in name_pattern_list]
2852
3173
        bad_patterns = ''
 
3174
        bad_patterns_count = 0
2853
3175
        for p in name_pattern_list:
2854
3176
            if not globbing.Globster.is_pattern_valid(p):
 
3177
                bad_patterns_count += 1
2855
3178
                bad_patterns += ('\n  %s' % p)
2856
3179
        if bad_patterns:
2857
 
            msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
 
3180
            msg = (ngettext('Invalid ignore pattern found. %s', 
 
3181
                            'Invalid ignore patterns found. %s',
 
3182
                            bad_patterns_count) % bad_patterns)
2858
3183
            ui.ui_factory.show_error(msg)
2859
3184
            raise errors.InvalidPattern('')
2860
3185
        for name_pattern in name_pattern_list:
2861
3186
            if (name_pattern[0] == '/' or
2862
3187
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
2863
 
                raise errors.BzrCommandError(
2864
 
                    "NAME_PATTERN should not be an absolute path")
 
3188
                raise errors.BzrCommandError(gettext(
 
3189
                    "NAME_PATTERN should not be an absolute path"))
2865
3190
        tree, relpath = WorkingTree.open_containing(directory)
2866
3191
        ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2867
3192
        ignored = globbing.Globster(name_pattern_list)
2874
3199
                if ignored.match(filename):
2875
3200
                    matches.append(filename)
2876
3201
        if len(matches) > 0:
2877
 
            self.outf.write("Warning: the following files are version controlled and"
2878
 
                  " match your ignore pattern:\n%s"
 
3202
            self.outf.write(gettext("Warning: the following files are version "
 
3203
                  "controlled and match your ignore pattern:\n%s"
2879
3204
                  "\nThese files will continue to be version controlled"
2880
 
                  " unless you 'bzr remove' them.\n" % ("\n".join(matches),))
 
3205
                  " unless you 'bzr remove' them.\n") % ("\n".join(matches),))
2881
3206
 
2882
3207
 
2883
3208
class cmd_ignored(Command):
2922
3247
        try:
2923
3248
            revno = int(revno)
2924
3249
        except ValueError:
2925
 
            raise errors.BzrCommandError("not a valid revision-number: %r"
 
3250
            raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
2926
3251
                                         % revno)
2927
3252
        revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2928
3253
        self.outf.write("%s\n" % revid)
2971
3296
        Option('per-file-timestamps',
2972
3297
               help='Set modification time of files to that of the last '
2973
3298
                    'revision in which it was changed.'),
 
3299
        Option('uncommitted',
 
3300
               help='Export the working tree contents rather than that of the '
 
3301
                    'last revision.'),
2974
3302
        ]
2975
3303
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2976
 
        root=None, filters=False, per_file_timestamps=False, directory=u'.'):
 
3304
        root=None, filters=False, per_file_timestamps=False, uncommitted=False,
 
3305
        directory=u'.'):
2977
3306
        from bzrlib.export import export
2978
3307
 
2979
3308
        if branch_or_subdir is None:
2980
 
            tree = WorkingTree.open_containing(directory)[0]
2981
 
            b = tree.branch
2982
 
            subdir = None
 
3309
            branch_or_subdir = directory
 
3310
 
 
3311
        (tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
 
3312
            branch_or_subdir)
 
3313
        if tree is not None:
 
3314
            self.add_cleanup(tree.lock_read().unlock)
 
3315
 
 
3316
        if uncommitted:
 
3317
            if tree is None:
 
3318
                raise errors.BzrCommandError(
 
3319
                    gettext("--uncommitted requires a working tree"))
 
3320
            export_tree = tree
2983
3321
        else:
2984
 
            b, subdir = Branch.open_containing(branch_or_subdir)
2985
 
            tree = None
2986
 
 
2987
 
        rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
 
3322
            export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2988
3323
        try:
2989
 
            export(rev_tree, dest, format, root, subdir, filtered=filters,
 
3324
            export(export_tree, dest, format, root, subdir, filtered=filters,
2990
3325
                   per_file_timestamps=per_file_timestamps)
2991
3326
        except errors.NoSuchExportFormat, e:
2992
 
            raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
 
3327
            raise errors.BzrCommandError(
 
3328
                gettext('Unsupported export format: %s') % e.format)
2993
3329
 
2994
3330
 
2995
3331
class cmd_cat(Command):
3015
3351
    def run(self, filename, revision=None, name_from_revision=False,
3016
3352
            filters=False, directory=None):
3017
3353
        if revision is not None and len(revision) != 1:
3018
 
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
3019
 
                                         " one revision specifier")
 
3354
            raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
 
3355
                                         " one revision specifier"))
3020
3356
        tree, branch, relpath = \
3021
3357
            _open_directory_or_containing_tree_or_branch(filename, directory)
3022
3358
        self.add_cleanup(branch.lock_read().unlock)
3032
3368
 
3033
3369
        old_file_id = rev_tree.path2id(relpath)
3034
3370
 
 
3371
        # TODO: Split out this code to something that generically finds the
 
3372
        # best id for a path across one or more trees; it's like
 
3373
        # find_ids_across_trees but restricted to find just one. -- mbp
 
3374
        # 20110705.
3035
3375
        if name_from_revision:
3036
3376
            # Try in revision if requested
3037
3377
            if old_file_id is None:
3038
 
                raise errors.BzrCommandError(
3039
 
                    "%r is not present in revision %s" % (
 
3378
                raise errors.BzrCommandError(gettext(
 
3379
                    "{0!r} is not present in revision {1}").format(
3040
3380
                        filename, rev_tree.get_revision_id()))
3041
3381
            else:
3042
 
                content = rev_tree.get_file_text(old_file_id)
 
3382
                actual_file_id = old_file_id
3043
3383
        else:
3044
3384
            cur_file_id = tree.path2id(relpath)
3045
 
            found = False
3046
 
            if cur_file_id is not None:
3047
 
                # Then try with the actual file id
3048
 
                try:
3049
 
                    content = rev_tree.get_file_text(cur_file_id)
3050
 
                    found = True
3051
 
                except errors.NoSuchId:
3052
 
                    # The actual file id didn't exist at that time
3053
 
                    pass
3054
 
            if not found and old_file_id is not None:
3055
 
                # Finally try with the old file id
3056
 
                content = rev_tree.get_file_text(old_file_id)
3057
 
                found = True
3058
 
            if not found:
3059
 
                # Can't be found anywhere
3060
 
                raise errors.BzrCommandError(
3061
 
                    "%r is not present in revision %s" % (
 
3385
            if cur_file_id is not None and rev_tree.has_id(cur_file_id):
 
3386
                actual_file_id = cur_file_id
 
3387
            elif old_file_id is not None:
 
3388
                actual_file_id = old_file_id
 
3389
            else:
 
3390
                raise errors.BzrCommandError(gettext(
 
3391
                    "{0!r} is not present in revision {1}").format(
3062
3392
                        filename, rev_tree.get_revision_id()))
3063
3393
        if filtered:
3064
 
            from bzrlib.filters import (
3065
 
                ContentFilterContext,
3066
 
                filtered_output_bytes,
3067
 
                )
3068
 
            filters = rev_tree._content_filter_stack(relpath)
3069
 
            chunks = content.splitlines(True)
3070
 
            content = filtered_output_bytes(chunks, filters,
3071
 
                ContentFilterContext(relpath, rev_tree))
3072
 
            self.cleanup_now()
3073
 
            self.outf.writelines(content)
 
3394
            from bzrlib.filter_tree import ContentFilterTree
 
3395
            filter_tree = ContentFilterTree(rev_tree,
 
3396
                rev_tree._content_filter_stack)
 
3397
            content = filter_tree.get_file_text(actual_file_id)
3074
3398
        else:
3075
 
            self.cleanup_now()
3076
 
            self.outf.write(content)
 
3399
            content = rev_tree.get_file_text(actual_file_id)
 
3400
        self.cleanup_now()
 
3401
        self.outf.write(content)
3077
3402
 
3078
3403
 
3079
3404
class cmd_local_time_offset(Command):
3186
3511
    aliases = ['ci', 'checkin']
3187
3512
 
3188
3513
    def _iter_bug_fix_urls(self, fixes, branch):
 
3514
        default_bugtracker  = None
3189
3515
        # Configure the properties for bug fixing attributes.
3190
3516
        for fixed_bug in fixes:
3191
3517
            tokens = fixed_bug.split(':')
3192
 
            if len(tokens) != 2:
3193
 
                raise errors.BzrCommandError(
 
3518
            if len(tokens) == 1:
 
3519
                if default_bugtracker is None:
 
3520
                    branch_config = branch.get_config()
 
3521
                    default_bugtracker = branch_config.get_user_option(
 
3522
                        "bugtracker")
 
3523
                if default_bugtracker is None:
 
3524
                    raise errors.BzrCommandError(gettext(
 
3525
                        "No tracker specified for bug %s. Use the form "
 
3526
                        "'tracker:id' or specify a default bug tracker "
 
3527
                        "using the `bugtracker` option.\nSee "
 
3528
                        "\"bzr help bugs\" for more information on this "
 
3529
                        "feature. Commit refused.") % fixed_bug)
 
3530
                tag = default_bugtracker
 
3531
                bug_id = tokens[0]
 
3532
            elif len(tokens) != 2:
 
3533
                raise errors.BzrCommandError(gettext(
3194
3534
                    "Invalid bug %s. Must be in the form of 'tracker:id'. "
3195
3535
                    "See \"bzr help bugs\" for more information on this "
3196
 
                    "feature.\nCommit refused." % fixed_bug)
3197
 
            tag, bug_id = tokens
 
3536
                    "feature.\nCommit refused.") % fixed_bug)
 
3537
            else:
 
3538
                tag, bug_id = tokens
3198
3539
            try:
3199
3540
                yield bugtracker.get_bug_url(tag, branch, bug_id)
3200
3541
            except errors.UnknownBugTrackerAbbreviation:
3201
 
                raise errors.BzrCommandError(
3202
 
                    'Unrecognized bug %s. Commit refused.' % fixed_bug)
 
3542
                raise errors.BzrCommandError(gettext(
 
3543
                    'Unrecognized bug %s. Commit refused.') % fixed_bug)
3203
3544
            except errors.MalformedBugIdentifier, e:
3204
 
                raise errors.BzrCommandError(
3205
 
                    "%s\nCommit refused." % (str(e),))
 
3545
                raise errors.BzrCommandError(gettext(
 
3546
                    "%s\nCommit refused.") % (str(e),))
3206
3547
 
3207
3548
    def run(self, message=None, file=None, verbose=False, selected_list=None,
3208
3549
            unchanged=False, strict=False, local=False, fixes=None,
3225
3566
            try:
3226
3567
                commit_stamp, offset = timestamp.parse_patch_date(commit_time)
3227
3568
            except ValueError, e:
3228
 
                raise errors.BzrCommandError(
3229
 
                    "Could not parse --commit-time: " + str(e))
 
3569
                raise errors.BzrCommandError(gettext(
 
3570
                    "Could not parse --commit-time: " + str(e)))
3230
3571
 
3231
3572
        properties = {}
3232
3573
 
3265
3606
                message = message.replace('\r\n', '\n')
3266
3607
                message = message.replace('\r', '\n')
3267
3608
            if file:
3268
 
                raise errors.BzrCommandError(
3269
 
                    "please specify either --message or --file")
 
3609
                raise errors.BzrCommandError(gettext(
 
3610
                    "please specify either --message or --file"))
3270
3611
 
3271
3612
        def get_message(commit_obj):
3272
3613
            """Callback to get commit message"""
3295
3636
                    my_message = edit_commit_message_encoded(text,
3296
3637
                        start_message=start_message)
3297
3638
                if my_message is None:
3298
 
                    raise errors.BzrCommandError("please specify a commit"
3299
 
                        " message with either --message or --file")
3300
 
            if my_message == "":
3301
 
                raise errors.BzrCommandError("empty commit message specified")
 
3639
                    raise errors.BzrCommandError(gettext("please specify a commit"
 
3640
                        " message with either --message or --file"))
 
3641
                if my_message == "":
 
3642
                    raise errors.BzrCommandError(gettext("Empty commit message specified."
 
3643
                            " Please specify a commit message with either"
 
3644
                            " --message or --file or leave a blank message"
 
3645
                            " with --message \"\"."))
3302
3646
            return my_message
3303
3647
 
3304
3648
        # The API permits a commit with a filter of [] to mean 'select nothing'
3315
3659
                        exclude=tree.safe_relpath_files(exclude),
3316
3660
                        lossy=lossy)
3317
3661
        except PointlessCommit:
3318
 
            raise errors.BzrCommandError("No changes to commit."
 
3662
            raise errors.BzrCommandError(gettext("No changes to commit."
3319
3663
                " Please 'bzr add' the files you want to commit, or use"
3320
 
                " --unchanged to force an empty commit.")
 
3664
                " --unchanged to force an empty commit."))
3321
3665
        except ConflictsInTree:
3322
 
            raise errors.BzrCommandError('Conflicts detected in working '
 
3666
            raise errors.BzrCommandError(gettext('Conflicts detected in working '
3323
3667
                'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
3324
 
                ' resolve.')
 
3668
                ' resolve.'))
3325
3669
        except StrictCommitFailed:
3326
 
            raise errors.BzrCommandError("Commit refused because there are"
3327
 
                              " unknown files in the working tree.")
 
3670
            raise errors.BzrCommandError(gettext("Commit refused because there are"
 
3671
                              " unknown files in the working tree."))
3328
3672
        except errors.BoundBranchOutOfDate, e:
3329
 
            e.extra_help = ("\n"
 
3673
            e.extra_help = (gettext("\n"
3330
3674
                'To commit to master branch, run update and then commit.\n'
3331
3675
                'You can also pass --local to commit to continue working '
3332
 
                'disconnected.')
 
3676
                'disconnected.'))
3333
3677
            raise
3334
3678
 
3335
3679
 
3442
3786
        RegistryOption('format',
3443
3787
            help='Upgrade to a specific format.  See "bzr help'
3444
3788
                 ' formats" for details.',
3445
 
            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3446
 
            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
3789
            lazy_registry=('bzrlib.controldir', 'format_registry'),
 
3790
            converter=lambda name: controldir.format_registry.make_bzrdir(name),
3447
3791
            value_switches=True, title='Branch format'),
3448
3792
        Option('clean',
3449
3793
            help='Remove the backup.bzr directory if successful.'),
3490
3834
            if directory is None:
3491
3835
                # use branch if we're inside one; otherwise global config
3492
3836
                try:
3493
 
                    c = Branch.open_containing(u'.')[0].get_config()
 
3837
                    c = Branch.open_containing(u'.')[0].get_config_stack()
3494
3838
                except errors.NotBranchError:
3495
 
                    c = _mod_config.GlobalConfig()
 
3839
                    c = _mod_config.GlobalStack()
3496
3840
            else:
3497
 
                c = Branch.open(directory).get_config()
 
3841
                c = Branch.open(directory).get_config_stack()
 
3842
            identity = c.get('email')
3498
3843
            if email:
3499
 
                self.outf.write(c.user_email() + '\n')
 
3844
                self.outf.write(_mod_config.extract_email_address(identity)
 
3845
                                + '\n')
3500
3846
            else:
3501
 
                self.outf.write(c.username() + '\n')
 
3847
                self.outf.write(identity + '\n')
3502
3848
            return
3503
3849
 
3504
3850
        if email:
3505
 
            raise errors.BzrCommandError("--email can only be used to display existing "
3506
 
                                         "identity")
 
3851
            raise errors.BzrCommandError(gettext("--email can only be used to display existing "
 
3852
                                         "identity"))
3507
3853
 
3508
3854
        # display a warning if an email address isn't included in the given name.
3509
3855
        try:
3515
3861
        # use global config unless --branch given
3516
3862
        if branch:
3517
3863
            if directory is None:
3518
 
                c = Branch.open_containing(u'.')[0].get_config()
 
3864
                c = Branch.open_containing(u'.')[0].get_config_stack()
3519
3865
            else:
3520
 
                c = Branch.open(directory).get_config()
 
3866
                c = Branch.open(directory).get_config_stack()
3521
3867
        else:
3522
 
            c = _mod_config.GlobalConfig()
3523
 
        c.set_user_option('email', name)
 
3868
            c = _mod_config.GlobalStack()
 
3869
        c.set('email', name)
3524
3870
 
3525
3871
 
3526
3872
class cmd_nick(Command):
3588
3934
 
3589
3935
    def remove_alias(self, alias_name):
3590
3936
        if alias_name is None:
3591
 
            raise errors.BzrCommandError(
3592
 
                'bzr alias --remove expects an alias to remove.')
 
3937
            raise errors.BzrCommandError(gettext(
 
3938
                'bzr alias --remove expects an alias to remove.'))
3593
3939
        # If alias is not found, print something like:
3594
3940
        # unalias: foo: not found
3595
3941
        c = _mod_config.GlobalConfig()
3751
4097
            load_list=None, debugflag=None, starting_with=None, subunit=False,
3752
4098
            parallel=None, lsprof_tests=False,
3753
4099
            sync=False):
 
4100
 
 
4101
        # During selftest, disallow proxying, as it can cause severe
 
4102
        # performance penalties and is only needed for thread
 
4103
        # safety. The selftest command is assumed to not use threads
 
4104
        # too heavily. The call should be as early as possible, as
 
4105
        # error reporting for past duplicate imports won't have useful
 
4106
        # backtraces.
 
4107
        lazy_import.disallow_proxying()
 
4108
 
3754
4109
        from bzrlib import tests
3755
4110
 
3756
4111
        if testspecs_list is not None:
3761
4116
            try:
3762
4117
                from bzrlib.tests import SubUnitBzrRunner
3763
4118
            except ImportError:
3764
 
                raise errors.BzrCommandError("subunit not available. subunit "
3765
 
                    "needs to be installed to use --subunit.")
 
4119
                raise errors.BzrCommandError(gettext("subunit not available. subunit "
 
4120
                    "needs to be installed to use --subunit."))
3766
4121
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3767
4122
            # On Windows, disable automatic conversion of '\n' to '\r\n' in
3768
4123
            # stdout, which would corrupt the subunit stream. 
3777
4132
            self.additional_selftest_args.setdefault(
3778
4133
                'suite_decorators', []).append(parallel)
3779
4134
        if benchmark:
3780
 
            raise errors.BzrCommandError(
 
4135
            raise errors.BzrCommandError(gettext(
3781
4136
                "--benchmark is no longer supported from bzr 2.2; "
3782
 
                "use bzr-usertest instead")
 
4137
                "use bzr-usertest instead"))
3783
4138
        test_suite_factory = None
3784
4139
        if not exclude:
3785
4140
            exclude_pattern = None
3848
4203
 
3849
4204
    @display_command
3850
4205
    def run(self):
3851
 
        self.outf.write("It sure does!\n")
 
4206
        self.outf.write(gettext("It sure does!\n"))
3852
4207
 
3853
4208
 
3854
4209
class cmd_find_merge_base(Command):
3872
4227
        graph = branch1.repository.get_graph(branch2.repository)
3873
4228
        base_rev_id = graph.find_unique_lca(last1, last2)
3874
4229
 
3875
 
        self.outf.write('merge base is revision %s\n' % base_rev_id)
 
4230
        self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
3876
4231
 
3877
4232
 
3878
4233
class cmd_merge(Command):
3906
4261
    Merge will do its best to combine the changes in two branches, but there
3907
4262
    are some kinds of problems only a human can fix.  When it encounters those,
3908
4263
    it will mark a conflict.  A conflict means that you need to fix something,
3909
 
    before you should commit.
 
4264
    before you can commit.
3910
4265
 
3911
4266
    Use bzr resolve when you have fixed a problem.  See also bzr conflicts.
3912
4267
 
3913
4268
    If there is no default branch set, the first merge will set it (use
3914
 
    --no-remember to avoid settting it). After that, you can omit the branch
 
4269
    --no-remember to avoid setting it). After that, you can omit the branch
3915
4270
    to use the default.  To change the default, use --remember. The value will
3916
4271
    only be saved if the remote location can be accessed.
3917
4272
 
4003
4358
 
4004
4359
        tree = WorkingTree.open_containing(directory)[0]
4005
4360
        if tree.branch.revno() == 0:
4006
 
            raise errors.BzrCommandError('Merging into empty branches not currently supported, '
4007
 
                                         'https://bugs.launchpad.net/bzr/+bug/308562')
 
4361
            raise errors.BzrCommandError(gettext('Merging into empty branches not currently supported, '
 
4362
                                         'https://bugs.launchpad.net/bzr/+bug/308562'))
4008
4363
 
4009
4364
        try:
4010
4365
            basis_tree = tree.revision_tree(tree.last_revision())
4030
4385
                mergeable = None
4031
4386
            else:
4032
4387
                if uncommitted:
4033
 
                    raise errors.BzrCommandError('Cannot use --uncommitted'
4034
 
                        ' with bundles or merge directives.')
 
4388
                    raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
 
4389
                        ' with bundles or merge directives.'))
4035
4390
 
4036
4391
                if revision is not None:
4037
 
                    raise errors.BzrCommandError(
4038
 
                        'Cannot use -r with merge directives or bundles')
 
4392
                    raise errors.BzrCommandError(gettext(
 
4393
                        'Cannot use -r with merge directives or bundles'))
4039
4394
                merger, verified = _mod_merge.Merger.from_mergeable(tree,
4040
4395
                   mergeable, None)
4041
4396
 
4042
4397
        if merger is None and uncommitted:
4043
4398
            if revision is not None and len(revision) > 0:
4044
 
                raise errors.BzrCommandError('Cannot use --uncommitted and'
4045
 
                    ' --revision at the same time.')
 
4399
                raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
 
4400
                    ' --revision at the same time.'))
4046
4401
            merger = self.get_merger_from_uncommitted(tree, location, None)
4047
4402
            allow_pending = False
4048
4403
 
4061
4416
            if merger.interesting_files:
4062
4417
                if not merger.other_tree.has_filename(
4063
4418
                    merger.interesting_files[0]):
4064
 
                    note("merger: " + str(merger))
 
4419
                    note(gettext("merger: ") + str(merger))
4065
4420
                    raise errors.PathsDoNotExist([location])
4066
 
            note('Nothing to do.')
 
4421
            note(gettext('Nothing to do.'))
4067
4422
            return 0
4068
4423
        if pull and not preview:
4069
4424
            if merger.interesting_files is not None:
4070
 
                raise errors.BzrCommandError('Cannot pull individual files')
 
4425
                raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4071
4426
            if (merger.base_rev_id == tree.last_revision()):
4072
4427
                result = tree.pull(merger.other_branch, False,
4073
4428
                                   merger.other_rev_id)
4074
4429
                result.report(self.outf)
4075
4430
                return 0
4076
4431
        if merger.this_basis is None:
4077
 
            raise errors.BzrCommandError(
 
4432
            raise errors.BzrCommandError(gettext(
4078
4433
                "This branch has no commits."
4079
 
                " (perhaps you would prefer 'bzr pull')")
 
4434
                " (perhaps you would prefer 'bzr pull')"))
4080
4435
        if preview:
4081
4436
            return self._do_preview(merger)
4082
4437
        elif interactive:
4133
4488
    def sanity_check_merger(self, merger):
4134
4489
        if (merger.show_base and
4135
4490
            not merger.merge_type is _mod_merge.Merge3Merger):
4136
 
            raise errors.BzrCommandError("Show-base is not supported for this"
4137
 
                                         " merge type. %s" % merger.merge_type)
 
4491
            raise errors.BzrCommandError(gettext("Show-base is not supported for this"
 
4492
                                         " merge type. %s") % merger.merge_type)
4138
4493
        if merger.reprocess is None:
4139
4494
            if merger.show_base:
4140
4495
                merger.reprocess = False
4142
4497
                # Use reprocess if the merger supports it
4143
4498
                merger.reprocess = merger.merge_type.supports_reprocess
4144
4499
        if merger.reprocess and not merger.merge_type.supports_reprocess:
4145
 
            raise errors.BzrCommandError("Conflict reduction is not supported"
4146
 
                                         " for merge type %s." %
 
4500
            raise errors.BzrCommandError(gettext("Conflict reduction is not supported"
 
4501
                                         " for merge type %s.") %
4147
4502
                                         merger.merge_type)
4148
4503
        if merger.reprocess and merger.show_base:
4149
 
            raise errors.BzrCommandError("Cannot do conflict reduction and"
4150
 
                                         " show base.")
 
4504
            raise errors.BzrCommandError(gettext("Cannot do conflict reduction and"
 
4505
                                         " show base."))
4151
4506
 
4152
4507
    def _get_merger_from_branch(self, tree, location, revision, remember,
4153
4508
                                possible_transports, pb):
4257
4612
            stored_location_type = "parent"
4258
4613
        mutter("%s", stored_location)
4259
4614
        if stored_location is None:
4260
 
            raise errors.BzrCommandError("No location specified or remembered")
 
4615
            raise errors.BzrCommandError(gettext("No location specified or remembered"))
4261
4616
        display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4262
 
        note(u"%s remembered %s location %s", verb_string,
4263
 
                stored_location_type, display_url)
 
4617
        note(gettext("{0} remembered {1} location {2}").format(verb_string,
 
4618
                stored_location_type, display_url))
4264
4619
        return stored_location
4265
4620
 
4266
4621
 
4303
4658
        self.add_cleanup(tree.lock_write().unlock)
4304
4659
        parents = tree.get_parent_ids()
4305
4660
        if len(parents) != 2:
4306
 
            raise errors.BzrCommandError("Sorry, remerge only works after normal"
 
4661
            raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4307
4662
                                         " merges.  Not cherrypicking or"
4308
 
                                         " multi-merges.")
 
4663
                                         " multi-merges."))
4309
4664
        repository = tree.branch.repository
4310
4665
        interesting_ids = None
4311
4666
        new_conflicts = []
4470
4825
 
4471
4826
    @display_command
4472
4827
    def run(self, context=None):
4473
 
        import shellcomplete
 
4828
        from bzrlib import shellcomplete
4474
4829
        shellcomplete.shellcomplete(context)
4475
4830
 
4476
4831
 
4530
4885
            type=_parse_revision_str,
4531
4886
            help='Filter on local branch revisions (inclusive). '
4532
4887
                'See "help revisionspec" for details.'),
4533
 
        Option('include-merges',
 
4888
        Option('include-merged',
4534
4889
               'Show all revisions in addition to the mainline ones.'),
 
4890
        Option('include-merges', hidden=True,
 
4891
               help='Historical alias for --include-merged.'),
4535
4892
        ]
4536
4893
    encoding_type = 'replace'
4537
4894
 
4540
4897
            theirs_only=False,
4541
4898
            log_format=None, long=False, short=False, line=False,
4542
4899
            show_ids=False, verbose=False, this=False, other=False,
4543
 
            include_merges=False, revision=None, my_revision=None,
4544
 
            directory=u'.'):
 
4900
            include_merged=None, revision=None, my_revision=None,
 
4901
            directory=u'.',
 
4902
            include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4545
4903
        from bzrlib.missing import find_unmerged, iter_log_revisions
4546
4904
        def message(s):
4547
4905
            if not is_quiet():
4548
4906
                self.outf.write(s)
4549
4907
 
 
4908
        if symbol_versioning.deprecated_passed(include_merges):
 
4909
            ui.ui_factory.show_user_warning(
 
4910
                'deprecated_command_option',
 
4911
                deprecated_name='--include-merges',
 
4912
                recommended_name='--include-merged',
 
4913
                deprecated_in_version='2.5',
 
4914
                command=self.invoked_as)
 
4915
            if include_merged is None:
 
4916
                include_merged = include_merges
 
4917
            else:
 
4918
                raise errors.BzrCommandError(gettext(
 
4919
                    '{0} and {1} are mutually exclusive').format(
 
4920
                    '--include-merges', '--include-merged'))
 
4921
        if include_merged is None:
 
4922
            include_merged = False
4550
4923
        if this:
4551
4924
            mine_only = this
4552
4925
        if other:
4567
4940
        if other_branch is None:
4568
4941
            other_branch = parent
4569
4942
            if other_branch is None:
4570
 
                raise errors.BzrCommandError("No peer location known"
4571
 
                                             " or specified.")
 
4943
                raise errors.BzrCommandError(gettext("No peer location known"
 
4944
                                             " or specified."))
4572
4945
            display_url = urlutils.unescape_for_display(parent,
4573
4946
                                                        self.outf.encoding)
4574
 
            message("Using saved parent location: "
4575
 
                    + display_url + "\n")
 
4947
            message(gettext("Using saved parent location: {0}\n").format(
 
4948
                    display_url))
4576
4949
 
4577
4950
        remote_branch = Branch.open(other_branch)
4578
4951
        if remote_branch.base == local_branch.base:
4591
4964
        local_extra, remote_extra = find_unmerged(
4592
4965
            local_branch, remote_branch, restrict,
4593
4966
            backward=not reverse,
4594
 
            include_merges=include_merges,
 
4967
            include_merged=include_merged,
4595
4968
            local_revid_range=local_revid_range,
4596
4969
            remote_revid_range=remote_revid_range)
4597
4970
 
4604
4977
 
4605
4978
        status_code = 0
4606
4979
        if local_extra and not theirs_only:
4607
 
            message("You have %d extra revision(s):\n" %
 
4980
            message(ngettext("You have %d extra revision:\n",
 
4981
                             "You have %d extra revisions:\n", 
 
4982
                             len(local_extra)) %
4608
4983
                len(local_extra))
4609
4984
            for revision in iter_log_revisions(local_extra,
4610
4985
                                local_branch.repository,
4618
4993
        if remote_extra and not mine_only:
4619
4994
            if printed_local is True:
4620
4995
                message("\n\n\n")
4621
 
            message("You are missing %d revision(s):\n" %
 
4996
            message(ngettext("You are missing %d revision:\n",
 
4997
                             "You are missing %d revisions:\n",
 
4998
                             len(remote_extra)) %
4622
4999
                len(remote_extra))
4623
5000
            for revision in iter_log_revisions(remote_extra,
4624
5001
                                remote_branch.repository,
4628
5005
 
4629
5006
        if mine_only and not local_extra:
4630
5007
            # We checked local, and found nothing extra
4631
 
            message('This branch is up to date.\n')
 
5008
            message(gettext('This branch has no new revisions.\n'))
4632
5009
        elif theirs_only and not remote_extra:
4633
5010
            # We checked remote, and found nothing extra
4634
 
            message('Other branch is up to date.\n')
 
5011
            message(gettext('Other branch has no new revisions.\n'))
4635
5012
        elif not (mine_only or theirs_only or local_extra or
4636
5013
                  remote_extra):
4637
5014
            # We checked both branches, and neither one had extra
4638
5015
            # revisions
4639
 
            message("Branches are up to date.\n")
 
5016
            message(gettext("Branches are up to date.\n"))
4640
5017
        self.cleanup_now()
4641
5018
        if not status_code and parent is None and other_branch is not None:
4642
5019
            self.add_cleanup(local_branch.lock_write().unlock)
4672
5049
        ]
4673
5050
 
4674
5051
    def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4675
 
        dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
 
5052
        dir = controldir.ControlDir.open_containing(branch_or_repo)[0]
4676
5053
        try:
4677
5054
            branch = dir.open_branch()
4678
5055
            repository = branch.repository
4718
5095
            Option('strict',
4719
5096
                   help='Produce a strict-format testament.')]
4720
5097
    takes_args = ['branch?']
4721
 
    encoding_type = 'exact'
4722
5098
    @display_command
4723
5099
    def run(self, branch=u'.', revision=None, long=False, strict=False):
4724
5100
        from bzrlib.testament import Testament, StrictTestament
4737
5113
            rev_id = revision[0].as_revision_id(b)
4738
5114
        t = testament_class.from_revision(b.repository, rev_id)
4739
5115
        if long:
4740
 
            self.outf.writelines(t.as_text_lines())
 
5116
            sys.stdout.writelines(t.as_text_lines())
4741
5117
        else:
4742
 
            self.outf.write(t.as_short_text())
 
5118
            sys.stdout.write(t.as_short_text())
4743
5119
 
4744
5120
 
4745
5121
class cmd_annotate(Command):
4804
5180
 
4805
5181
    def run(self, revision_id_list=None, revision=None, directory=u'.'):
4806
5182
        if revision_id_list is not None and revision is not None:
4807
 
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
 
5183
            raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
4808
5184
        if revision_id_list is None and revision is None:
4809
 
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
 
5185
            raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
4810
5186
        b = WorkingTree.open_containing(directory)[0].branch
4811
5187
        self.add_cleanup(b.lock_write().unlock)
4812
5188
        return self._run(b, revision_id_list, revision)
4813
5189
 
4814
5190
    def _run(self, b, revision_id_list, revision):
4815
5191
        import bzrlib.gpg as gpg
4816
 
        gpg_strategy = gpg.GPGStrategy(b.get_config())
 
5192
        gpg_strategy = gpg.GPGStrategy(b.get_config_stack())
4817
5193
        if revision_id_list is not None:
4818
5194
            b.repository.start_write_group()
4819
5195
            try:
4844
5220
                if to_revid is None:
4845
5221
                    to_revno = b.revno()
4846
5222
                if from_revno is None or to_revno is None:
4847
 
                    raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
 
5223
                    raise errors.BzrCommandError(gettext('Cannot sign a range of non-revision-history revisions'))
4848
5224
                b.repository.start_write_group()
4849
5225
                try:
4850
5226
                    for revno in range(from_revno, to_revno + 1):
4856
5232
                else:
4857
5233
                    b.repository.commit_write_group()
4858
5234
            else:
4859
 
                raise errors.BzrCommandError('Please supply either one revision, or a range.')
 
5235
                raise errors.BzrCommandError(gettext('Please supply either one revision, or a range.'))
4860
5236
 
4861
5237
 
4862
5238
class cmd_bind(Command):
4881
5257
            try:
4882
5258
                location = b.get_old_bound_location()
4883
5259
            except errors.UpgradeRequired:
4884
 
                raise errors.BzrCommandError('No location supplied.  '
4885
 
                    'This format does not remember old locations.')
 
5260
                raise errors.BzrCommandError(gettext('No location supplied.  '
 
5261
                    'This format does not remember old locations.'))
4886
5262
            else:
4887
5263
                if location is None:
4888
5264
                    if b.get_bound_location() is not None:
4889
 
                        raise errors.BzrCommandError('Branch is already bound')
 
5265
                        raise errors.BzrCommandError(gettext('Branch is already bound'))
4890
5266
                    else:
4891
 
                        raise errors.BzrCommandError('No location supplied '
4892
 
                            'and no previous location known')
 
5267
                        raise errors.BzrCommandError(gettext('No location supplied '
 
5268
                            'and no previous location known'))
4893
5269
        b_other = Branch.open(location)
4894
5270
        try:
4895
5271
            b.bind(b_other)
4896
5272
        except errors.DivergedBranches:
4897
 
            raise errors.BzrCommandError('These branches have diverged.'
4898
 
                                         ' Try merging, and then bind again.')
 
5273
            raise errors.BzrCommandError(gettext('These branches have diverged.'
 
5274
                                         ' Try merging, and then bind again.'))
4899
5275
        if b.get_config().has_explicit_nickname():
4900
5276
            b.nick = b_other.nick
4901
5277
 
4914
5290
    def run(self, directory=u'.'):
4915
5291
        b, relpath = Branch.open_containing(directory)
4916
5292
        if not b.unbind():
4917
 
            raise errors.BzrCommandError('Local branch is not bound')
 
5293
            raise errors.BzrCommandError(gettext('Local branch is not bound'))
4918
5294
 
4919
5295
 
4920
5296
class cmd_uncommit(Command):
4941
5317
    takes_options = ['verbose', 'revision',
4942
5318
                    Option('dry-run', help='Don\'t actually make changes.'),
4943
5319
                    Option('force', help='Say yes to all questions.'),
 
5320
                    Option('keep-tags',
 
5321
                           help='Keep tags that point to removed revisions.'),
4944
5322
                    Option('local',
4945
5323
                           help="Only remove the commits from the local branch"
4946
5324
                                " when in a checkout."
4950
5328
    aliases = []
4951
5329
    encoding_type = 'replace'
4952
5330
 
4953
 
    def run(self, location=None,
4954
 
            dry_run=False, verbose=False,
4955
 
            revision=None, force=False, local=False):
 
5331
    def run(self, location=None, dry_run=False, verbose=False,
 
5332
            revision=None, force=False, local=False, keep_tags=False):
4956
5333
        if location is None:
4957
5334
            location = u'.'
4958
 
        control, relpath = bzrdir.BzrDir.open_containing(location)
 
5335
        control, relpath = controldir.ControlDir.open_containing(location)
4959
5336
        try:
4960
5337
            tree = control.open_workingtree()
4961
5338
            b = tree.branch
4967
5344
            self.add_cleanup(tree.lock_write().unlock)
4968
5345
        else:
4969
5346
            self.add_cleanup(b.lock_write().unlock)
4970
 
        return self._run(b, tree, dry_run, verbose, revision, force, local=local)
 
5347
        return self._run(b, tree, dry_run, verbose, revision, force,
 
5348
                         local, keep_tags)
4971
5349
 
4972
 
    def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
 
5350
    def _run(self, b, tree, dry_run, verbose, revision, force, local,
 
5351
             keep_tags):
4973
5352
        from bzrlib.log import log_formatter, show_log
4974
5353
        from bzrlib.uncommit import uncommit
4975
5354
 
4990
5369
                rev_id = b.get_rev_id(revno)
4991
5370
 
4992
5371
        if rev_id is None or _mod_revision.is_null(rev_id):
4993
 
            self.outf.write('No revisions to uncommit.\n')
 
5372
            self.outf.write(gettext('No revisions to uncommit.\n'))
4994
5373
            return 1
4995
5374
 
4996
5375
        lf = log_formatter('short',
5005
5384
                 end_revision=last_revno)
5006
5385
 
5007
5386
        if dry_run:
5008
 
            self.outf.write('Dry-run, pretending to remove'
5009
 
                            ' the above revisions.\n')
 
5387
            self.outf.write(gettext('Dry-run, pretending to remove'
 
5388
                            ' the above revisions.\n'))
5010
5389
        else:
5011
 
            self.outf.write('The above revision(s) will be removed.\n')
 
5390
            self.outf.write(gettext('The above revision(s) will be removed.\n'))
5012
5391
 
5013
5392
        if not force:
5014
5393
            if not ui.ui_factory.confirm_action(
5015
 
                    u'Uncommit these revisions',
 
5394
                    gettext(u'Uncommit these revisions'),
5016
5395
                    'bzrlib.builtins.uncommit',
5017
5396
                    {}):
5018
 
                self.outf.write('Canceled\n')
 
5397
                self.outf.write(gettext('Canceled\n'))
5019
5398
                return 0
5020
5399
 
5021
5400
        mutter('Uncommitting from {%s} to {%s}',
5022
5401
               last_rev_id, rev_id)
5023
5402
        uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5024
 
                 revno=revno, local=local)
5025
 
        self.outf.write('You can restore the old tip by running:\n'
5026
 
             '  bzr pull . -r revid:%s\n' % last_rev_id)
 
5403
                 revno=revno, local=local, keep_tags=keep_tags)
 
5404
        self.outf.write(gettext('You can restore the old tip by running:\n'
 
5405
             '  bzr pull . -r revid:%s\n') % last_rev_id)
5027
5406
 
5028
5407
 
5029
5408
class cmd_break_lock(Command):
5063
5442
            conf = _mod_config.LockableConfig(file_name=location)
5064
5443
            conf.break_lock()
5065
5444
        else:
5066
 
            control, relpath = bzrdir.BzrDir.open_containing(location)
 
5445
            control, relpath = controldir.ControlDir.open_containing(location)
5067
5446
            try:
5068
5447
                control.break_lock()
5069
5448
            except NotImplementedError:
5113
5492
                    'option leads to global uncontrolled write access to your '
5114
5493
                    'file system.'
5115
5494
                ),
 
5495
        Option('client-timeout', type=float,
 
5496
               help='Override the default idle client timeout (5min).'),
5116
5497
        ]
5117
5498
 
5118
5499
    def get_host_and_port(self, port):
5135
5516
        return host, port
5136
5517
 
5137
5518
    def run(self, port=None, inet=False, directory=None, allow_writes=False,
5138
 
            protocol=None):
 
5519
            protocol=None, client_timeout=None):
5139
5520
        from bzrlib import transport
5140
5521
        if directory is None:
5141
5522
            directory = os.getcwd()
5142
5523
        if protocol is None:
5143
5524
            protocol = transport.transport_server_registry.get()
5144
5525
        host, port = self.get_host_and_port(port)
5145
 
        url = urlutils.local_path_to_url(directory)
 
5526
        url = transport.location_to_url(directory)
5146
5527
        if not allow_writes:
5147
5528
            url = 'readonly+' + url
5148
 
        t = transport.get_transport(url)
5149
 
        protocol(t, host, port, inet)
 
5529
        t = transport.get_transport_from_url(url)
 
5530
        try:
 
5531
            protocol(t, host, port, inet, client_timeout)
 
5532
        except TypeError, e:
 
5533
            # We use symbol_versioning.deprecated_in just so that people
 
5534
            # grepping can find it here.
 
5535
            # symbol_versioning.deprecated_in((2, 5, 0))
 
5536
            symbol_versioning.warn(
 
5537
                'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
 
5538
                'Most likely it needs to be updated to support a'
 
5539
                ' "timeout" parameter (added in bzr 2.5.0)'
 
5540
                % (e, protocol.__module__, protocol),
 
5541
                DeprecationWarning)
 
5542
            protocol(t, host, port, inet)
5150
5543
 
5151
5544
 
5152
5545
class cmd_join(Command):
5175
5568
        containing_tree = WorkingTree.open_containing(parent_dir)[0]
5176
5569
        repo = containing_tree.branch.repository
5177
5570
        if not repo.supports_rich_root():
5178
 
            raise errors.BzrCommandError(
 
5571
            raise errors.BzrCommandError(gettext(
5179
5572
                "Can't join trees because %s doesn't support rich root data.\n"
5180
 
                "You can use bzr upgrade on the repository."
 
5573
                "You can use bzr upgrade on the repository.")
5181
5574
                % (repo,))
5182
5575
        if reference:
5183
5576
            try:
5185
5578
            except errors.BadReferenceTarget, e:
5186
5579
                # XXX: Would be better to just raise a nicely printable
5187
5580
                # exception from the real origin.  Also below.  mbp 20070306
5188
 
                raise errors.BzrCommandError("Cannot join %s.  %s" %
5189
 
                                             (tree, e.reason))
 
5581
                raise errors.BzrCommandError(
 
5582
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5190
5583
        else:
5191
5584
            try:
5192
5585
                containing_tree.subsume(sub_tree)
5193
5586
            except errors.BadSubsumeSource, e:
5194
 
                raise errors.BzrCommandError("Cannot join %s.  %s" %
5195
 
                                             (tree, e.reason))
 
5587
                raise errors.BzrCommandError(
 
5588
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5196
5589
 
5197
5590
 
5198
5591
class cmd_split(Command):
5282
5675
        if submit_branch is None:
5283
5676
            submit_branch = branch.get_parent()
5284
5677
        if submit_branch is None:
5285
 
            raise errors.BzrCommandError('No submit branch specified or known')
 
5678
            raise errors.BzrCommandError(gettext('No submit branch specified or known'))
5286
5679
 
5287
5680
        stored_public_branch = branch.get_public_branch()
5288
5681
        if public_branch is None:
5290
5683
        elif stored_public_branch is None:
5291
5684
            branch.set_public_branch(public_branch)
5292
5685
        if not include_bundle and public_branch is None:
5293
 
            raise errors.BzrCommandError('No public branch specified or'
5294
 
                                         ' known')
 
5686
            raise errors.BzrCommandError(gettext('No public branch specified or'
 
5687
                                         ' known'))
5295
5688
        base_revision_id = None
5296
5689
        if revision is not None:
5297
5690
            if len(revision) > 2:
5298
 
                raise errors.BzrCommandError('bzr merge-directive takes '
5299
 
                    'at most two one revision identifiers')
 
5691
                raise errors.BzrCommandError(gettext('bzr merge-directive takes '
 
5692
                    'at most two one revision identifiers'))
5300
5693
            revision_id = revision[-1].as_revision_id(branch)
5301
5694
            if len(revision) == 2:
5302
5695
                base_revision_id = revision[0].as_revision_id(branch)
5304
5697
            revision_id = branch.last_revision()
5305
5698
        revision_id = ensure_null(revision_id)
5306
5699
        if revision_id == NULL_REVISION:
5307
 
            raise errors.BzrCommandError('No revisions to bundle.')
 
5700
            raise errors.BzrCommandError(gettext('No revisions to bundle.'))
5308
5701
        directive = merge_directive.MergeDirective2.from_objects(
5309
5702
            branch.repository, revision_id, time.time(),
5310
5703
            osutils.local_time_offset(), submit_branch,
5318
5711
                self.outf.writelines(directive.to_lines())
5319
5712
        else:
5320
5713
            message = directive.to_email(mail_to, branch, sign)
5321
 
            s = SMTPConnection(branch.get_config())
 
5714
            s = SMTPConnection(branch.get_config_stack())
5322
5715
            s.send_email(message)
5323
5716
 
5324
5717
 
5356
5749
 
5357
5750
    Both the submit branch and the public branch follow the usual behavior with
5358
5751
    respect to --remember: If there is no default location set, the first send
5359
 
    will set it (use --no-remember to avoid settting it). After that, you can
 
5752
    will set it (use --no-remember to avoid setting it). After that, you can
5360
5753
    omit the location to use the default.  To change the default, use
5361
5754
    --remember. The value will only be saved if the location can be accessed.
5362
5755
 
5564
5957
        self.add_cleanup(branch.lock_write().unlock)
5565
5958
        if delete:
5566
5959
            if tag_name is None:
5567
 
                raise errors.BzrCommandError("No tag specified to delete.")
 
5960
                raise errors.BzrCommandError(gettext("No tag specified to delete."))
5568
5961
            branch.tags.delete_tag(tag_name)
5569
 
            note('Deleted tag %s.' % tag_name)
 
5962
            note(gettext('Deleted tag %s.') % tag_name)
5570
5963
        else:
5571
5964
            if revision:
5572
5965
                if len(revision) != 1:
5573
 
                    raise errors.BzrCommandError(
 
5966
                    raise errors.BzrCommandError(gettext(
5574
5967
                        "Tags can only be placed on a single revision, "
5575
 
                        "not on a range")
 
5968
                        "not on a range"))
5576
5969
                revision_id = revision[0].as_revision_id(branch)
5577
5970
            else:
5578
5971
                revision_id = branch.last_revision()
5579
5972
            if tag_name is None:
5580
5973
                tag_name = branch.automatic_tag_name(revision_id)
5581
5974
                if tag_name is None:
5582
 
                    raise errors.BzrCommandError(
5583
 
                        "Please specify a tag name.")
5584
 
            if (not force) and branch.tags.has_tag(tag_name):
 
5975
                    raise errors.BzrCommandError(gettext(
 
5976
                        "Please specify a tag name."))
 
5977
            try:
 
5978
                existing_target = branch.tags.lookup_tag(tag_name)
 
5979
            except errors.NoSuchTag:
 
5980
                existing_target = None
 
5981
            if not force and existing_target not in (None, revision_id):
5585
5982
                raise errors.TagAlreadyExists(tag_name)
5586
 
            branch.tags.set_tag(tag_name, revision_id)
5587
 
            note('Created tag %s.' % tag_name)
 
5983
            if existing_target == revision_id:
 
5984
                note(gettext('Tag %s already exists for that revision.') % tag_name)
 
5985
            else:
 
5986
                branch.tags.set_tag(tag_name, revision_id)
 
5987
                if existing_target is None:
 
5988
                    note(gettext('Created tag %s.') % tag_name)
 
5989
                else:
 
5990
                    note(gettext('Updated tag %s.') % tag_name)
5588
5991
 
5589
5992
 
5590
5993
class cmd_tags(Command):
5628
6031
                    revno = branch.revision_id_to_dotted_revno(revid)
5629
6032
                    if isinstance(revno, tuple):
5630
6033
                        revno = '.'.join(map(str, revno))
5631
 
                except (errors.NoSuchRevision, errors.GhostRevisionsHaveNoRevno):
 
6034
                except (errors.NoSuchRevision,
 
6035
                        errors.GhostRevisionsHaveNoRevno,
 
6036
                        errors.UnsupportedOperation):
5632
6037
                    # Bad tag data/merges can lead to tagged revisions
5633
6038
                    # which are not in this branch. Fail gracefully ...
5634
6039
                    revno = '?'
5682
6087
    takes_args = ['location?']
5683
6088
    takes_options = [
5684
6089
        RegistryOption.from_kwargs(
5685
 
            'target_type',
5686
 
            title='Target type',
5687
 
            help='The type to reconfigure the directory to.',
 
6090
            'tree_type',
 
6091
            title='Tree type',
 
6092
            help='The relation between branch and tree.',
5688
6093
            value_switches=True, enum_switch=False,
5689
6094
            branch='Reconfigure to be an unbound branch with no working tree.',
5690
6095
            tree='Reconfigure to be an unbound branch with a working tree.',
5691
6096
            checkout='Reconfigure to be a bound branch with a working tree.',
5692
6097
            lightweight_checkout='Reconfigure to be a lightweight'
5693
6098
                ' checkout (with no local history).',
 
6099
            ),
 
6100
        RegistryOption.from_kwargs(
 
6101
            'repository_type',
 
6102
            title='Repository type',
 
6103
            help='Location fo the repository.',
 
6104
            value_switches=True, enum_switch=False,
5694
6105
            standalone='Reconfigure to be a standalone branch '
5695
6106
                '(i.e. stop using shared repository).',
5696
6107
            use_shared='Reconfigure to use a shared repository.',
 
6108
            ),
 
6109
        RegistryOption.from_kwargs(
 
6110
            'repository_trees',
 
6111
            title='Trees in Repository',
 
6112
            help='Whether new branches in the repository have trees.',
 
6113
            value_switches=True, enum_switch=False,
5697
6114
            with_trees='Reconfigure repository to create '
5698
6115
                'working trees on branches by default.',
5699
6116
            with_no_trees='Reconfigure repository to not create '
5713
6130
            ),
5714
6131
        ]
5715
6132
 
5716
 
    def run(self, location=None, target_type=None, bind_to=None, force=False,
5717
 
            stacked_on=None,
5718
 
            unstacked=None):
5719
 
        directory = bzrdir.BzrDir.open(location)
 
6133
    def run(self, location=None, bind_to=None, force=False,
 
6134
            tree_type=None, repository_type=None, repository_trees=None,
 
6135
            stacked_on=None, unstacked=None):
 
6136
        directory = controldir.ControlDir.open(location)
5720
6137
        if stacked_on and unstacked:
5721
 
            raise errors.BzrCommandError("Can't use both --stacked-on and --unstacked")
 
6138
            raise errors.BzrCommandError(gettext("Can't use both --stacked-on and --unstacked"))
5722
6139
        elif stacked_on is not None:
5723
6140
            reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5724
6141
        elif unstacked:
5726
6143
        # At the moment you can use --stacked-on and a different
5727
6144
        # reconfiguration shape at the same time; there seems no good reason
5728
6145
        # to ban it.
5729
 
        if target_type is None:
 
6146
        if (tree_type is None and
 
6147
            repository_type is None and
 
6148
            repository_trees is None):
5730
6149
            if stacked_on or unstacked:
5731
6150
                return
5732
6151
            else:
5733
 
                raise errors.BzrCommandError('No target configuration '
5734
 
                    'specified')
5735
 
        elif target_type == 'branch':
 
6152
                raise errors.BzrCommandError(gettext('No target configuration '
 
6153
                    'specified'))
 
6154
        reconfiguration = None
 
6155
        if tree_type == 'branch':
5736
6156
            reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5737
 
        elif target_type == 'tree':
 
6157
        elif tree_type == 'tree':
5738
6158
            reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5739
 
        elif target_type == 'checkout':
 
6159
        elif tree_type == 'checkout':
5740
6160
            reconfiguration = reconfigure.Reconfigure.to_checkout(
5741
6161
                directory, bind_to)
5742
 
        elif target_type == 'lightweight-checkout':
 
6162
        elif tree_type == 'lightweight-checkout':
5743
6163
            reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5744
6164
                directory, bind_to)
5745
 
        elif target_type == 'use-shared':
 
6165
        if reconfiguration:
 
6166
            reconfiguration.apply(force)
 
6167
            reconfiguration = None
 
6168
        if repository_type == 'use-shared':
5746
6169
            reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5747
 
        elif target_type == 'standalone':
 
6170
        elif repository_type == 'standalone':
5748
6171
            reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5749
 
        elif target_type == 'with-trees':
 
6172
        if reconfiguration:
 
6173
            reconfiguration.apply(force)
 
6174
            reconfiguration = None
 
6175
        if repository_trees == 'with-trees':
5750
6176
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5751
6177
                directory, True)
5752
 
        elif target_type == 'with-no-trees':
 
6178
        elif repository_trees == 'with-no-trees':
5753
6179
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5754
6180
                directory, False)
5755
 
        reconfiguration.apply(force)
 
6181
        if reconfiguration:
 
6182
            reconfiguration.apply(force)
 
6183
            reconfiguration = None
5756
6184
 
5757
6185
 
5758
6186
class cmd_switch(Command):
5793
6221
        from bzrlib import switch
5794
6222
        tree_location = directory
5795
6223
        revision = _get_one_revision('switch', revision)
5796
 
        control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
 
6224
        possible_transports = []
 
6225
        control_dir = controldir.ControlDir.open_containing(tree_location,
 
6226
            possible_transports=possible_transports)[0]
5797
6227
        if to_location is None:
5798
6228
            if revision is None:
5799
 
                raise errors.BzrCommandError('You must supply either a'
5800
 
                                             ' revision or a location')
 
6229
                raise errors.BzrCommandError(gettext('You must supply either a'
 
6230
                                             ' revision or a location'))
5801
6231
            to_location = tree_location
5802
6232
        try:
5803
 
            branch = control_dir.open_branch()
 
6233
            branch = control_dir.open_branch(
 
6234
                possible_transports=possible_transports)
5804
6235
            had_explicit_nick = branch.get_config().has_explicit_nickname()
5805
6236
        except errors.NotBranchError:
5806
6237
            branch = None
5807
6238
            had_explicit_nick = False
5808
6239
        if create_branch:
5809
6240
            if branch is None:
5810
 
                raise errors.BzrCommandError('cannot create branch without'
5811
 
                                             ' source branch')
5812
 
            to_location = directory_service.directories.dereference(
5813
 
                              to_location)
5814
 
            if '/' not in to_location and '\\' not in to_location:
5815
 
                # This path is meant to be relative to the existing branch
5816
 
                this_url = self._get_branch_location(control_dir)
5817
 
                to_location = urlutils.join(this_url, '..', to_location)
 
6241
                raise errors.BzrCommandError(
 
6242
                    gettext('cannot create branch without source branch'))
 
6243
            to_location = lookup_new_sibling_branch(control_dir, to_location,
 
6244
                 possible_transports=possible_transports)
5818
6245
            to_branch = branch.bzrdir.sprout(to_location,
5819
 
                                 possible_transports=[branch.bzrdir.root_transport],
5820
 
                                 source_branch=branch).open_branch()
 
6246
                 possible_transports=possible_transports,
 
6247
                 source_branch=branch).open_branch()
5821
6248
        else:
5822
 
            try:
5823
 
                to_branch = Branch.open(to_location)
5824
 
            except errors.NotBranchError:
5825
 
                this_url = self._get_branch_location(control_dir)
5826
 
                to_branch = Branch.open(
5827
 
                    urlutils.join(this_url, '..', to_location))
 
6249
            to_branch = lookup_sibling_branch(control_dir, to_location)
5828
6250
        if revision is not None:
5829
6251
            revision = revision.as_revision_id(to_branch)
5830
6252
        switch.switch(control_dir, to_branch, force, revision_id=revision)
5831
6253
        if had_explicit_nick:
5832
6254
            branch = control_dir.open_branch() #get the new branch!
5833
6255
            branch.nick = to_branch.nick
5834
 
        note('Switched to branch: %s',
 
6256
        note(gettext('Switched to branch: %s'),
5835
6257
            urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5836
6258
 
5837
 
    def _get_branch_location(self, control_dir):
5838
 
        """Return location of branch for this control dir."""
5839
 
        try:
5840
 
            this_branch = control_dir.open_branch()
5841
 
            # This may be a heavy checkout, where we want the master branch
5842
 
            master_location = this_branch.get_bound_location()
5843
 
            if master_location is not None:
5844
 
                return master_location
5845
 
            # If not, use a local sibling
5846
 
            return this_branch.base
5847
 
        except errors.NotBranchError:
5848
 
            format = control_dir.find_branch_format()
5849
 
            if getattr(format, 'get_reference', None) is not None:
5850
 
                return format.get_reference(control_dir)
5851
 
            else:
5852
 
                return control_dir.root_transport.base
5853
6259
 
5854
6260
 
5855
6261
class cmd_view(Command):
5946
6352
            name = current_view
5947
6353
        if delete:
5948
6354
            if file_list:
5949
 
                raise errors.BzrCommandError(
5950
 
                    "Both --delete and a file list specified")
 
6355
                raise errors.BzrCommandError(gettext(
 
6356
                    "Both --delete and a file list specified"))
5951
6357
            elif switch:
5952
 
                raise errors.BzrCommandError(
5953
 
                    "Both --delete and --switch specified")
 
6358
                raise errors.BzrCommandError(gettext(
 
6359
                    "Both --delete and --switch specified"))
5954
6360
            elif all:
5955
6361
                tree.views.set_view_info(None, {})
5956
 
                self.outf.write("Deleted all views.\n")
 
6362
                self.outf.write(gettext("Deleted all views.\n"))
5957
6363
            elif name is None:
5958
 
                raise errors.BzrCommandError("No current view to delete")
 
6364
                raise errors.BzrCommandError(gettext("No current view to delete"))
5959
6365
            else:
5960
6366
                tree.views.delete_view(name)
5961
 
                self.outf.write("Deleted '%s' view.\n" % name)
 
6367
                self.outf.write(gettext("Deleted '%s' view.\n") % name)
5962
6368
        elif switch:
5963
6369
            if file_list:
5964
 
                raise errors.BzrCommandError(
5965
 
                    "Both --switch and a file list specified")
 
6370
                raise errors.BzrCommandError(gettext(
 
6371
                    "Both --switch and a file list specified"))
5966
6372
            elif all:
5967
 
                raise errors.BzrCommandError(
5968
 
                    "Both --switch and --all specified")
 
6373
                raise errors.BzrCommandError(gettext(
 
6374
                    "Both --switch and --all specified"))
5969
6375
            elif switch == 'off':
5970
6376
                if current_view is None:
5971
 
                    raise errors.BzrCommandError("No current view to disable")
 
6377
                    raise errors.BzrCommandError(gettext("No current view to disable"))
5972
6378
                tree.views.set_view_info(None, view_dict)
5973
 
                self.outf.write("Disabled '%s' view.\n" % (current_view))
 
6379
                self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
5974
6380
            else:
5975
6381
                tree.views.set_view_info(switch, view_dict)
5976
6382
                view_str = views.view_display_str(tree.views.lookup_view())
5977
 
                self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
 
6383
                self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
5978
6384
        elif all:
5979
6385
            if view_dict:
5980
 
                self.outf.write('Views defined:\n')
 
6386
                self.outf.write(gettext('Views defined:\n'))
5981
6387
                for view in sorted(view_dict):
5982
6388
                    if view == current_view:
5983
6389
                        active = "=>"
5986
6392
                    view_str = views.view_display_str(view_dict[view])
5987
6393
                    self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5988
6394
            else:
5989
 
                self.outf.write('No views defined.\n')
 
6395
                self.outf.write(gettext('No views defined.\n'))
5990
6396
        elif file_list:
5991
6397
            if name is None:
5992
6398
                # No name given and no current view set
5993
6399
                name = 'my'
5994
6400
            elif name == 'off':
5995
 
                raise errors.BzrCommandError(
5996
 
                    "Cannot change the 'off' pseudo view")
 
6401
                raise errors.BzrCommandError(gettext(
 
6402
                    "Cannot change the 'off' pseudo view"))
5997
6403
            tree.views.set_view(name, sorted(file_list))
5998
6404
            view_str = views.view_display_str(tree.views.lookup_view())
5999
 
            self.outf.write("Using '%s' view: %s\n" % (name, view_str))
 
6405
            self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
6000
6406
        else:
6001
6407
            # list the files
6002
6408
            if name is None:
6003
6409
                # No name given and no current view set
6004
 
                self.outf.write('No current view.\n')
 
6410
                self.outf.write(gettext('No current view.\n'))
6005
6411
            else:
6006
6412
                view_str = views.view_display_str(tree.views.lookup_view(name))
6007
 
                self.outf.write("'%s' view is: %s\n" % (name, view_str))
 
6413
                self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
6008
6414
 
6009
6415
 
6010
6416
class cmd_hooks(Command):
6024
6430
                        self.outf.write("    %s\n" %
6025
6431
                                        (some_hooks.get_hook_name(hook),))
6026
6432
                else:
6027
 
                    self.outf.write("    <no hooks installed>\n")
 
6433
                    self.outf.write(gettext("    <no hooks installed>\n"))
6028
6434
 
6029
6435
 
6030
6436
class cmd_remove_branch(Command):
6131
6537
        manager = tree.get_shelf_manager()
6132
6538
        shelves = manager.active_shelves()
6133
6539
        if len(shelves) == 0:
6134
 
            note('No shelved changes.')
 
6540
            note(gettext('No shelved changes.'))
6135
6541
            return 0
6136
6542
        for shelf_id in reversed(shelves):
6137
6543
            message = manager.get_metadata(shelf_id).get('message')
6226
6632
        if path is not None:
6227
6633
            branchdir = path
6228
6634
        tree, branch, relpath =(
6229
 
            bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
 
6635
            controldir.ControlDir.open_containing_tree_or_branch(branchdir))
6230
6636
        if path is not None:
6231
6637
            path = relpath
6232
6638
        if tree is None:
6260
6666
    __doc__ = """Export command helps and error messages in po format."""
6261
6667
 
6262
6668
    hidden = True
 
6669
    takes_options = [Option('plugin', 
 
6670
                            help='Export help text from named command '\
 
6671
                                 '(defaults to all built in commands).',
 
6672
                            type=str),
 
6673
                     Option('include-duplicates',
 
6674
                            help='Output multiple copies of the same msgid '
 
6675
                                 'string if it appears more than once.'),
 
6676
                            ]
6263
6677
 
6264
 
    def run(self):
 
6678
    def run(self, plugin=None, include_duplicates=False):
6265
6679
        from bzrlib.export_pot import export_pot
6266
 
        export_pot(self.outf)
 
6680
        export_pot(self.outf, plugin, include_duplicates)
6267
6681
 
6268
6682
 
6269
6683
def _register_lazy_builtins():