~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
18
18
 
19
19
import os
20
20
 
 
21
import bzrlib.bzrdir
 
22
 
21
23
from bzrlib.lazy_import import lazy_import
22
24
lazy_import(globals(), """
23
25
import cStringIO
 
26
import errno
24
27
import sys
25
28
import time
26
29
 
29
32
    bugtracker,
30
33
    bundle,
31
34
    btree_index,
32
 
    bzrdir,
 
35
    controldir,
33
36
    directory_service,
34
37
    delta,
35
38
    config as _mod_config,
44
47
    rename_map,
45
48
    revision as _mod_revision,
46
49
    static_tuple,
47
 
    symbol_versioning,
48
50
    timestamp,
49
51
    transport,
50
52
    ui,
51
53
    urlutils,
52
54
    views,
 
55
    gpg,
53
56
    )
54
57
from bzrlib.branch import Branch
55
58
from bzrlib.conflicts import ConflictList
57
60
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
58
61
from bzrlib.smtp_connection import SMTPConnection
59
62
from bzrlib.workingtree import WorkingTree
 
63
from bzrlib.i18n import gettext, ngettext
60
64
""")
61
65
 
62
66
from bzrlib.commands import (
72
76
    _parse_revision_str,
73
77
    )
74
78
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
 
79
from bzrlib import (
 
80
    symbol_versioning,
 
81
    )
75
82
 
76
83
 
77
84
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
109
116
            if view_files:
110
117
                file_list = view_files
111
118
                view_str = views.view_display_str(view_files)
112
 
                note("Ignoring files outside view. View is %s" % view_str)
 
119
                note(gettext("Ignoring files outside view. View is %s") % view_str)
113
120
    return tree, file_list
114
121
 
115
122
 
117
124
    if revisions is None:
118
125
        return None
119
126
    if len(revisions) != 1:
120
 
        raise errors.BzrCommandError(
121
 
            'bzr %s --revision takes exactly one revision identifier' % (
 
127
        raise errors.BzrCommandError(gettext(
 
128
            'bzr %s --revision takes exactly one revision identifier') % (
122
129
                command_name,))
123
130
    return revisions[0]
124
131
 
193
200
    the --directory option is used to specify a different branch."""
194
201
    if directory is not None:
195
202
        return (None, Branch.open(directory), filename)
196
 
    return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
 
203
    return controldir.ControlDir.open_containing_tree_or_branch(filename)
197
204
 
198
205
 
199
206
# TODO: Make sure no commands unconditionally use the working directory as a
229
236
    unknown
230
237
        Not versioned and not matching an ignore pattern.
231
238
 
232
 
    Additionally for directories, symlinks and files with an executable
233
 
    bit, Bazaar indicates their type using a trailing character: '/', '@'
234
 
    or '*' respectively.
 
239
    Additionally for directories, symlinks and files with a changed
 
240
    executable bit, Bazaar indicates their type using a trailing
 
241
    character: '/', '@' or '*' respectively. These decorations can be
 
242
    disabled using the '--no-classify' option.
235
243
 
236
244
    To see ignored files use 'bzr ignored'.  For details on the
237
245
    changes to file texts, use 'bzr diff'.
250
258
    To skip the display of pending merge information altogether, use
251
259
    the no-pending option or specify a file/directory.
252
260
 
253
 
    If a revision argument is given, the status is calculated against
254
 
    that revision, or between two revisions if two are provided.
 
261
    To compare the working directory to a specific revision, pass a
 
262
    single revision to the revision argument.
 
263
 
 
264
    To see which files have changed in a specific revision, or between
 
265
    two revisions, pass a revision range to the revision argument.
 
266
    This will produce the same results as calling 'bzr diff --summarize'.
255
267
    """
256
268
 
257
269
    # TODO: --no-recurse, --recurse options
264
276
                            short_name='V'),
265
277
                     Option('no-pending', help='Don\'t show pending merges.',
266
278
                           ),
 
279
                     Option('no-classify',
 
280
                            help='Do not mark object type using indicator.',
 
281
                           ),
267
282
                     ]
268
283
    aliases = ['st', 'stat']
269
284
 
272
287
 
273
288
    @display_command
274
289
    def run(self, show_ids=False, file_list=None, revision=None, short=False,
275
 
            versioned=False, no_pending=False, verbose=False):
 
290
            versioned=False, no_pending=False, verbose=False,
 
291
            no_classify=False):
276
292
        from bzrlib.status import show_tree_status
277
293
 
278
294
        if revision and len(revision) > 2:
279
 
            raise errors.BzrCommandError('bzr status --revision takes exactly'
280
 
                                         ' one or two revision specifiers')
 
295
            raise errors.BzrCommandError(gettext('bzr status --revision takes exactly'
 
296
                                         ' one or two revision specifiers'))
281
297
 
282
298
        tree, relfile_list = WorkingTree.open_containing_paths(file_list)
283
299
        # Avoid asking for specific files when that is not needed.
292
308
        show_tree_status(tree, show_ids=show_ids,
293
309
                         specific_files=relfile_list, revision=revision,
294
310
                         to_file=self.outf, short=short, versioned=versioned,
295
 
                         show_pending=(not no_pending), verbose=verbose)
 
311
                         show_pending=(not no_pending), verbose=verbose,
 
312
                         classify=not no_classify)
296
313
 
297
314
 
298
315
class cmd_cat_revision(Command):
319
336
    @display_command
320
337
    def run(self, revision_id=None, revision=None, directory=u'.'):
321
338
        if revision_id is not None and revision is not None:
322
 
            raise errors.BzrCommandError('You can only supply one of'
323
 
                                         ' revision_id or --revision')
 
339
            raise errors.BzrCommandError(gettext('You can only supply one of'
 
340
                                         ' revision_id or --revision'))
324
341
        if revision_id is None and revision is None:
325
 
            raise errors.BzrCommandError('You must supply either'
326
 
                                         ' --revision or a revision_id')
327
 
        b = WorkingTree.open_containing(directory)[0].branch
 
342
            raise errors.BzrCommandError(gettext('You must supply either'
 
343
                                         ' --revision or a revision_id'))
 
344
 
 
345
        b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
328
346
 
329
347
        revisions = b.repository.revisions
330
348
        if revisions is None:
331
 
            raise errors.BzrCommandError('Repository %r does not support '
332
 
                'access to raw revision texts')
 
349
            raise errors.BzrCommandError(gettext('Repository %r does not support '
 
350
                'access to raw revision texts'))
333
351
 
334
352
        b.repository.lock_read()
335
353
        try:
339
357
                try:
340
358
                    self.print_revision(revisions, revision_id)
341
359
                except errors.NoSuchRevision:
342
 
                    msg = "The repository %s contains no revision %s." % (
 
360
                    msg = gettext("The repository {0} contains no revision {1}.").format(
343
361
                        b.repository.base, revision_id)
344
362
                    raise errors.BzrCommandError(msg)
345
363
            elif revision is not None:
346
364
                for rev in revision:
347
365
                    if rev is None:
348
366
                        raise errors.BzrCommandError(
349
 
                            'You cannot specify a NULL revision.')
 
367
                            gettext('You cannot specify a NULL revision.'))
350
368
                    rev_id = rev.as_revision_id(b)
351
369
                    self.print_revision(revisions, rev_id)
352
370
        finally:
408
426
                self.outf.write(page_bytes[:header_end])
409
427
                page_bytes = data
410
428
            self.outf.write('\nPage %d\n' % (page_idx,))
411
 
            decomp_bytes = zlib.decompress(page_bytes)
412
 
            self.outf.write(decomp_bytes)
413
 
            self.outf.write('\n')
 
429
            if len(page_bytes) == 0:
 
430
                self.outf.write('(empty)\n');
 
431
            else:
 
432
                decomp_bytes = zlib.decompress(page_bytes)
 
433
                self.outf.write(decomp_bytes)
 
434
                self.outf.write('\n')
414
435
 
415
436
    def _dump_entries(self, trans, basename):
416
437
        try:
455
476
            location_list=['.']
456
477
 
457
478
        for location in location_list:
458
 
            d = bzrdir.BzrDir.open(location)
459
 
            
 
479
            d = controldir.ControlDir.open(location)
 
480
 
460
481
            try:
461
482
                working = d.open_workingtree()
462
483
            except errors.NoWorkingTree:
463
 
                raise errors.BzrCommandError("No working tree to remove")
 
484
                raise errors.BzrCommandError(gettext("No working tree to remove"))
464
485
            except errors.NotLocalUrl:
465
 
                raise errors.BzrCommandError("You cannot remove the working tree"
466
 
                                             " of a remote path")
 
486
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
487
                                             " of a remote path"))
467
488
            if not force:
468
489
                if (working.has_changes()):
469
490
                    raise errors.UncommittedChanges(working)
471
492
                    raise errors.ShelvedChanges(working)
472
493
 
473
494
            if working.user_url != working.branch.user_url:
474
 
                raise errors.BzrCommandError("You cannot remove the working tree"
475
 
                                             " from a lightweight checkout")
 
495
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
496
                                             " from a lightweight checkout"))
476
497
 
477
498
            d.destroy_workingtree()
478
499
 
479
500
 
 
501
class cmd_repair_workingtree(Command):
 
502
    __doc__ = """Reset the working tree state file.
 
503
 
 
504
    This is not meant to be used normally, but more as a way to recover from
 
505
    filesystem corruption, etc. This rebuilds the working inventory back to a
 
506
    'known good' state. Any new modifications (adding a file, renaming, etc)
 
507
    will be lost, though modified files will still be detected as such.
 
508
 
 
509
    Most users will want something more like "bzr revert" or "bzr update"
 
510
    unless the state file has become corrupted.
 
511
 
 
512
    By default this attempts to recover the current state by looking at the
 
513
    headers of the state file. If the state file is too corrupted to even do
 
514
    that, you can supply --revision to force the state of the tree.
 
515
    """
 
516
 
 
517
    takes_options = ['revision', 'directory',
 
518
        Option('force',
 
519
               help='Reset the tree even if it doesn\'t appear to be'
 
520
                    ' corrupted.'),
 
521
    ]
 
522
    hidden = True
 
523
 
 
524
    def run(self, revision=None, directory='.', force=False):
 
525
        tree, _ = WorkingTree.open_containing(directory)
 
526
        self.add_cleanup(tree.lock_tree_write().unlock)
 
527
        if not force:
 
528
            try:
 
529
                tree.check_state()
 
530
            except errors.BzrError:
 
531
                pass # There seems to be a real error here, so we'll reset
 
532
            else:
 
533
                # Refuse
 
534
                raise errors.BzrCommandError(gettext(
 
535
                    'The tree does not appear to be corrupt. You probably'
 
536
                    ' want "bzr revert" instead. Use "--force" if you are'
 
537
                    ' sure you want to reset the working tree.'))
 
538
        if revision is None:
 
539
            revision_ids = None
 
540
        else:
 
541
            revision_ids = [r.as_revision_id(tree.branch) for r in revision]
 
542
        try:
 
543
            tree.reset_state(revision_ids)
 
544
        except errors.BzrError, e:
 
545
            if revision_ids is None:
 
546
                extra = (gettext(', the header appears corrupt, try passing -r -1'
 
547
                         ' to set the state to the last commit'))
 
548
            else:
 
549
                extra = ''
 
550
            raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
 
551
 
 
552
 
480
553
class cmd_revno(Command):
481
554
    __doc__ = """Show current revision number.
482
555
 
486
559
    _see_also = ['info']
487
560
    takes_args = ['location?']
488
561
    takes_options = [
489
 
        Option('tree', help='Show revno of working tree'),
 
562
        Option('tree', help='Show revno of working tree.'),
 
563
        'revision',
490
564
        ]
491
565
 
492
566
    @display_command
493
 
    def run(self, tree=False, location=u'.'):
 
567
    def run(self, tree=False, location=u'.', revision=None):
 
568
        if revision is not None and tree:
 
569
            raise errors.BzrCommandError(gettext("--tree and --revision can "
 
570
                "not be used together"))
 
571
 
494
572
        if tree:
495
573
            try:
496
574
                wt = WorkingTree.open_containing(location)[0]
497
575
                self.add_cleanup(wt.lock_read().unlock)
498
576
            except (errors.NoWorkingTree, errors.NotLocalUrl):
499
577
                raise errors.NoWorkingTree(location)
 
578
            b = wt.branch
500
579
            revid = wt.last_revision()
501
 
            try:
502
 
                revno_t = wt.branch.revision_id_to_dotted_revno(revid)
503
 
            except errors.NoSuchRevision:
504
 
                revno_t = ('???',)
505
 
            revno = ".".join(str(n) for n in revno_t)
506
580
        else:
507
581
            b = Branch.open_containing(location)[0]
508
582
            self.add_cleanup(b.lock_read().unlock)
509
 
            revno = b.revno()
 
583
            if revision:
 
584
                if len(revision) != 1:
 
585
                    raise errors.BzrCommandError(gettext(
 
586
                        "Tags can only be placed on a single revision, "
 
587
                        "not on a range"))
 
588
                revid = revision[0].as_revision_id(b)
 
589
            else:
 
590
                revid = b.last_revision()
 
591
        try:
 
592
            revno_t = b.revision_id_to_dotted_revno(revid)
 
593
        except errors.NoSuchRevision:
 
594
            revno_t = ('???',)
 
595
        revno = ".".join(str(n) for n in revno_t)
510
596
        self.cleanup_now()
511
 
        self.outf.write(str(revno) + '\n')
 
597
        self.outf.write(revno + '\n')
512
598
 
513
599
 
514
600
class cmd_revision_info(Command):
521
607
        custom_help('directory',
522
608
            help='Branch to examine, '
523
609
                 'rather than the one containing the working directory.'),
524
 
        Option('tree', help='Show revno of working tree'),
 
610
        Option('tree', help='Show revno of working tree.'),
525
611
        ]
526
612
 
527
613
    @display_command
583
669
    are added.  This search proceeds recursively into versioned
584
670
    directories.  If no names are given '.' is assumed.
585
671
 
 
672
    A warning will be printed when nested trees are encountered,
 
673
    unless they are explicitly ignored.
 
674
 
586
675
    Therefore simply saying 'bzr add' will version all files that
587
676
    are currently unknown.
588
677
 
604
693
    
605
694
    Any files matching patterns in the ignore list will not be added
606
695
    unless they are explicitly mentioned.
 
696
    
 
697
    In recursive mode, files larger than the configuration option 
 
698
    add.maximum_file_size will be skipped. Named items are never skipped due
 
699
    to file size.
607
700
    """
608
701
    takes_args = ['file*']
609
702
    takes_options = [
636
729
            action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
637
730
                          to_file=self.outf, should_print=(not is_quiet()))
638
731
        else:
639
 
            action = bzrlib.add.AddAction(to_file=self.outf,
 
732
            action = bzrlib.add.AddWithSkipLargeAction(to_file=self.outf,
640
733
                should_print=(not is_quiet()))
641
734
 
642
735
        if base_tree:
649
742
            if verbose:
650
743
                for glob in sorted(ignored.keys()):
651
744
                    for path in ignored[glob]:
652
 
                        self.outf.write("ignored %s matching \"%s\"\n"
653
 
                                        % (path, glob))
 
745
                        self.outf.write(
 
746
                         gettext("ignored {0} matching \"{1}\"\n").format(
 
747
                         path, glob))
654
748
 
655
749
 
656
750
class cmd_mkdir(Command):
660
754
    """
661
755
 
662
756
    takes_args = ['dir+']
 
757
    takes_options = [
 
758
        Option(
 
759
            'parents',
 
760
            help='No error if existing, make parent directories as needed.',
 
761
            short_name='p'
 
762
            )
 
763
        ]
663
764
    encoding_type = 'replace'
664
765
 
665
 
    def run(self, dir_list):
666
 
        for d in dir_list:
667
 
            wt, dd = WorkingTree.open_containing(d)
668
 
            base = os.path.dirname(dd)
669
 
            id = wt.path2id(base)
670
 
            if id != None:
671
 
                os.mkdir(d)
672
 
                wt.add([dd])
673
 
                self.outf.write('added %s\n' % d)
 
766
    @classmethod
 
767
    def add_file_with_parents(cls, wt, relpath):
 
768
        if wt.path2id(relpath) is not None:
 
769
            return
 
770
        cls.add_file_with_parents(wt, osutils.dirname(relpath))
 
771
        wt.add([relpath])
 
772
 
 
773
    @classmethod
 
774
    def add_file_single(cls, wt, relpath):
 
775
        wt.add([relpath])
 
776
 
 
777
    def run(self, dir_list, parents=False):
 
778
        if parents:
 
779
            add_file = self.add_file_with_parents
 
780
        else:
 
781
            add_file = self.add_file_single
 
782
        for dir in dir_list:
 
783
            wt, relpath = WorkingTree.open_containing(dir)
 
784
            if parents:
 
785
                try:
 
786
                    os.makedirs(dir)
 
787
                except OSError, e:
 
788
                    if e.errno != errno.EEXIST:
 
789
                        raise
674
790
            else:
675
 
                raise errors.NotVersionedError(path=base)
 
791
                os.mkdir(dir)
 
792
            add_file(wt, relpath)
 
793
            if not is_quiet():
 
794
                self.outf.write(gettext('added %s\n') % dir)
676
795
 
677
796
 
678
797
class cmd_relpath(Command):
714
833
    @display_command
715
834
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
716
835
        if kind and kind not in ['file', 'directory', 'symlink']:
717
 
            raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
 
836
            raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
718
837
 
719
838
        revision = _get_one_revision('inventory', revision)
720
839
        work_tree, file_list = WorkingTree.open_containing_paths(file_list)
733
852
                                      require_versioned=True)
734
853
            # find_ids_across_trees may include some paths that don't
735
854
            # exist in 'tree'.
736
 
            entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
737
 
                             for file_id in file_ids if file_id in tree)
 
855
            entries = sorted(
 
856
                (tree.id2path(file_id), tree.inventory[file_id])
 
857
                for file_id in file_ids if tree.has_id(file_id))
738
858
        else:
739
859
            entries = tree.inventory.entries()
740
860
 
783
903
        if auto:
784
904
            return self.run_auto(names_list, after, dry_run)
785
905
        elif dry_run:
786
 
            raise errors.BzrCommandError('--dry-run requires --auto.')
 
906
            raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
787
907
        if names_list is None:
788
908
            names_list = []
789
909
        if len(names_list) < 2:
790
 
            raise errors.BzrCommandError("missing file argument")
 
910
            raise errors.BzrCommandError(gettext("missing file argument"))
791
911
        tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
 
912
        for file_name in rel_names[0:-1]:
 
913
            if file_name == '':
 
914
                raise errors.BzrCommandError(gettext("can not move root of branch"))
792
915
        self.add_cleanup(tree.lock_tree_write().unlock)
793
916
        self._run(tree, names_list, rel_names, after)
794
917
 
795
918
    def run_auto(self, names_list, after, dry_run):
796
919
        if names_list is not None and len(names_list) > 1:
797
 
            raise errors.BzrCommandError('Only one path may be specified to'
798
 
                                         ' --auto.')
 
920
            raise errors.BzrCommandError(gettext('Only one path may be specified to'
 
921
                                         ' --auto.'))
799
922
        if after:
800
 
            raise errors.BzrCommandError('--after cannot be specified with'
801
 
                                         ' --auto.')
 
923
            raise errors.BzrCommandError(gettext('--after cannot be specified with'
 
924
                                         ' --auto.'))
802
925
        work_tree, file_list = WorkingTree.open_containing_paths(
803
926
            names_list, default_directory='.')
804
927
        self.add_cleanup(work_tree.lock_tree_write().unlock)
834
957
                    self.outf.write("%s => %s\n" % (src, dest))
835
958
        else:
836
959
            if len(names_list) != 2:
837
 
                raise errors.BzrCommandError('to mv multiple files the'
 
960
                raise errors.BzrCommandError(gettext('to mv multiple files the'
838
961
                                             ' destination must be a versioned'
839
 
                                             ' directory')
 
962
                                             ' directory'))
840
963
 
841
964
            # for cicp file-systems: the src references an existing inventory
842
965
            # item:
901
1024
    match the remote one, use pull --overwrite. This will work even if the two
902
1025
    branches have diverged.
903
1026
 
904
 
    If there is no default location set, the first pull will set it.  After
905
 
    that, you can omit the location to use the default.  To change the
906
 
    default, use --remember. The value will only be saved if the remote
907
 
    location can be accessed.
 
1027
    If there is no default location set, the first pull will set it (use
 
1028
    --no-remember to avoid setting it). After that, you can omit the
 
1029
    location to use the default.  To change the default, use --remember. The
 
1030
    value will only be saved if the remote location can be accessed.
 
1031
 
 
1032
    The --verbose option will display the revisions pulled using the log_format
 
1033
    configuration option. You can use a different format by overriding it with
 
1034
    -Olog_format=<other_format>.
908
1035
 
909
1036
    Note: The location can be specified either in the form of a branch,
910
1037
    or in the form of a path to a file containing a merge directive generated
923
1050
                 "branch.  Local pulls are not applied to "
924
1051
                 "the master branch."
925
1052
            ),
 
1053
        Option('show-base',
 
1054
            help="Show base revision text in conflicts.")
926
1055
        ]
927
1056
    takes_args = ['location?']
928
1057
    encoding_type = 'replace'
929
1058
 
930
 
    def run(self, location=None, remember=False, overwrite=False,
 
1059
    def run(self, location=None, remember=None, overwrite=False,
931
1060
            revision=None, verbose=False,
932
 
            directory=None, local=False):
 
1061
            directory=None, local=False,
 
1062
            show_base=False):
933
1063
        # FIXME: too much stuff is in the command class
934
1064
        revision_id = None
935
1065
        mergeable = None
944
1074
            branch_to = Branch.open_containing(directory)[0]
945
1075
            self.add_cleanup(branch_to.lock_write().unlock)
946
1076
 
 
1077
        if tree_to is None and show_base:
 
1078
            raise errors.BzrCommandError(gettext("Need working tree for --show-base."))
 
1079
 
947
1080
        if local and not branch_to.get_bound_location():
948
1081
            raise errors.LocalRequiresBoundBranch()
949
1082
 
958
1091
        stored_loc = branch_to.get_parent()
959
1092
        if location is None:
960
1093
            if stored_loc is None:
961
 
                raise errors.BzrCommandError("No pull location known or"
962
 
                                             " specified.")
 
1094
                raise errors.BzrCommandError(gettext("No pull location known or"
 
1095
                                             " specified."))
963
1096
            else:
964
1097
                display_url = urlutils.unescape_for_display(stored_loc,
965
1098
                        self.outf.encoding)
966
1099
                if not is_quiet():
967
 
                    self.outf.write("Using saved parent location: %s\n" % display_url)
 
1100
                    self.outf.write(gettext("Using saved parent location: %s\n") % display_url)
968
1101
                location = stored_loc
969
1102
 
970
1103
        revision = _get_one_revision('pull', revision)
971
1104
        if mergeable is not None:
972
1105
            if revision is not None:
973
 
                raise errors.BzrCommandError(
974
 
                    'Cannot use -r with merge directives or bundles')
 
1106
                raise errors.BzrCommandError(gettext(
 
1107
                    'Cannot use -r with merge directives or bundles'))
975
1108
            mergeable.install_revisions(branch_to.repository)
976
1109
            base_revision_id, revision_id, verified = \
977
1110
                mergeable.get_merge_request(branch_to.repository)
980
1113
            branch_from = Branch.open(location,
981
1114
                possible_transports=possible_transports)
982
1115
            self.add_cleanup(branch_from.lock_read().unlock)
983
 
 
984
 
            if branch_to.get_parent() is None or remember:
 
1116
            # Remembers if asked explicitly or no previous location is set
 
1117
            if (remember
 
1118
                or (remember is None and branch_to.get_parent() is None)):
985
1119
                branch_to.set_parent(branch_from.base)
986
1120
 
987
1121
        if revision is not None:
994
1128
                view_info=view_info)
995
1129
            result = tree_to.pull(
996
1130
                branch_from, overwrite, revision_id, change_reporter,
997
 
                possible_transports=possible_transports, local=local)
 
1131
                local=local, show_base=show_base)
998
1132
        else:
999
1133
            result = branch_to.pull(
1000
1134
                branch_from, overwrite, revision_id, local=local)
1004
1138
            log.show_branch_change(
1005
1139
                branch_to, self.outf, result.old_revno,
1006
1140
                result.old_revid)
 
1141
        if getattr(result, 'tag_conflicts', None):
 
1142
            return 1
 
1143
        else:
 
1144
            return 0
1007
1145
 
1008
1146
 
1009
1147
class cmd_push(Command):
1026
1164
    do a merge (see bzr help merge) from the other branch, and commit that.
1027
1165
    After that you will be able to do a push without '--overwrite'.
1028
1166
 
1029
 
    If there is no default push location set, the first push will set it.
1030
 
    After that, you can omit the location to use the default.  To change the
1031
 
    default, use --remember. The value will only be saved if the remote
1032
 
    location can be accessed.
 
1167
    If there is no default push location set, the first push will set it (use
 
1168
    --no-remember to avoid setting it).  After that, you can omit the
 
1169
    location to use the default.  To change the default, use --remember. The
 
1170
    value will only be saved if the remote location can be accessed.
 
1171
 
 
1172
    The --verbose option will display the revisions pushed using the log_format
 
1173
    configuration option. You can use a different format by overriding it with
 
1174
    -Olog_format=<other_format>.
1033
1175
    """
1034
1176
 
1035
1177
    _see_also = ['pull', 'update', 'working-trees']
1056
1198
        Option('strict',
1057
1199
               help='Refuse to push if there are uncommitted changes in'
1058
1200
               ' the working tree, --no-strict disables the check.'),
 
1201
        Option('no-tree',
 
1202
               help="Don't populate the working tree, even for protocols"
 
1203
               " that support it."),
1059
1204
        ]
1060
1205
    takes_args = ['location?']
1061
1206
    encoding_type = 'replace'
1062
1207
 
1063
 
    def run(self, location=None, remember=False, overwrite=False,
 
1208
    def run(self, location=None, remember=None, overwrite=False,
1064
1209
        create_prefix=False, verbose=False, revision=None,
1065
1210
        use_existing_dir=False, directory=None, stacked_on=None,
1066
 
        stacked=False, strict=None):
 
1211
        stacked=False, strict=None, no_tree=False):
1067
1212
        from bzrlib.push import _show_push_branch
1068
1213
 
1069
1214
        if directory is None:
1070
1215
            directory = '.'
1071
1216
        # Get the source branch
1072
1217
        (tree, br_from,
1073
 
         _unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
 
1218
         _unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
1074
1219
        # Get the tip's revision_id
1075
1220
        revision = _get_one_revision('push', revision)
1076
1221
        if revision is not None:
1097
1242
                    # error by the feedback given to them. RBC 20080227.
1098
1243
                    stacked_on = parent_url
1099
1244
            if not stacked_on:
1100
 
                raise errors.BzrCommandError(
1101
 
                    "Could not determine branch to refer to.")
 
1245
                raise errors.BzrCommandError(gettext(
 
1246
                    "Could not determine branch to refer to."))
1102
1247
 
1103
1248
        # Get the destination location
1104
1249
        if location is None:
1105
1250
            stored_loc = br_from.get_push_location()
1106
1251
            if stored_loc is None:
1107
 
                raise errors.BzrCommandError(
1108
 
                    "No push location known or specified.")
 
1252
                raise errors.BzrCommandError(gettext(
 
1253
                    "No push location known or specified."))
1109
1254
            else:
1110
1255
                display_url = urlutils.unescape_for_display(stored_loc,
1111
1256
                        self.outf.encoding)
1112
 
                self.outf.write("Using saved push location: %s\n" % display_url)
 
1257
                note(gettext("Using saved push location: %s") % display_url)
1113
1258
                location = stored_loc
1114
1259
 
1115
1260
        _show_push_branch(br_from, revision_id, location, self.outf,
1116
1261
            verbose=verbose, overwrite=overwrite, remember=remember,
1117
1262
            stacked_on=stacked_on, create_prefix=create_prefix,
1118
 
            use_existing_dir=use_existing_dir)
 
1263
            use_existing_dir=use_existing_dir, no_tree=no_tree)
1119
1264
 
1120
1265
 
1121
1266
class cmd_branch(Command):
1130
1275
 
1131
1276
    To retrieve the branch as of a particular revision, supply the --revision
1132
1277
    parameter, as in "branch foo/bar -r 5".
 
1278
 
 
1279
    The synonyms 'clone' and 'get' for this command are deprecated.
1133
1280
    """
1134
1281
 
1135
1282
    _see_also = ['checkout']
1165
1312
            files_from=None):
1166
1313
        from bzrlib import switch as _mod_switch
1167
1314
        from bzrlib.tag import _merge_tags_if_possible
1168
 
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
 
1315
        if self.invoked_as in ['get', 'clone']:
 
1316
            ui.ui_factory.show_user_warning(
 
1317
                'deprecated_command',
 
1318
                deprecated_name=self.invoked_as,
 
1319
                recommended_name='branch',
 
1320
                deprecated_in_version='2.4')
 
1321
        accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1169
1322
            from_location)
1170
1323
        if not (hardlink or files_from):
1171
1324
            # accelerator_tree is usually slower because you have to read N
1184
1337
            # RBC 20060209
1185
1338
            revision_id = br_from.last_revision()
1186
1339
        if to_location is None:
1187
 
            to_location = urlutils.derive_to_location(from_location)
 
1340
            to_location = getattr(br_from, "name", None)
 
1341
            if to_location is None:
 
1342
                to_location = urlutils.derive_to_location(from_location)
1188
1343
        to_transport = transport.get_transport(to_location)
1189
1344
        try:
1190
1345
            to_transport.mkdir('.')
1191
1346
        except errors.FileExists:
1192
 
            if not use_existing_dir:
1193
 
                raise errors.BzrCommandError('Target directory "%s" '
1194
 
                    'already exists.' % to_location)
 
1347
            try:
 
1348
                to_dir = controldir.ControlDir.open_from_transport(
 
1349
                    to_transport)
 
1350
            except errors.NotBranchError:
 
1351
                if not use_existing_dir:
 
1352
                    raise errors.BzrCommandError(gettext('Target directory "%s" '
 
1353
                        'already exists.') % to_location)
 
1354
                else:
 
1355
                    to_dir = None
1195
1356
            else:
1196
1357
                try:
1197
 
                    bzrdir.BzrDir.open_from_transport(to_transport)
 
1358
                    to_dir.open_branch()
1198
1359
                except errors.NotBranchError:
1199
1360
                    pass
1200
1361
                else:
1201
1362
                    raise errors.AlreadyBranchError(to_location)
1202
1363
        except errors.NoSuchFile:
1203
 
            raise errors.BzrCommandError('Parent of "%s" does not exist.'
 
1364
            raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1204
1365
                                         % to_location)
1205
 
        try:
1206
 
            # preserve whatever source format we have.
1207
 
            dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1208
 
                                        possible_transports=[to_transport],
1209
 
                                        accelerator_tree=accelerator_tree,
1210
 
                                        hardlink=hardlink, stacked=stacked,
1211
 
                                        force_new_repo=standalone,
1212
 
                                        create_tree_if_local=not no_tree,
1213
 
                                        source_branch=br_from)
1214
 
            branch = dir.open_branch()
1215
 
        except errors.NoSuchRevision:
1216
 
            to_transport.delete_tree('.')
1217
 
            msg = "The branch %s has no revision %s." % (from_location,
1218
 
                revision)
1219
 
            raise errors.BzrCommandError(msg)
 
1366
        else:
 
1367
            to_dir = None
 
1368
        if to_dir is None:
 
1369
            try:
 
1370
                # preserve whatever source format we have.
 
1371
                to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
 
1372
                                            possible_transports=[to_transport],
 
1373
                                            accelerator_tree=accelerator_tree,
 
1374
                                            hardlink=hardlink, stacked=stacked,
 
1375
                                            force_new_repo=standalone,
 
1376
                                            create_tree_if_local=not no_tree,
 
1377
                                            source_branch=br_from)
 
1378
                branch = to_dir.open_branch(
 
1379
                    possible_transports=[
 
1380
                        br_from.bzrdir.root_transport, to_transport])
 
1381
            except errors.NoSuchRevision:
 
1382
                to_transport.delete_tree('.')
 
1383
                msg = gettext("The branch {0} has no revision {1}.").format(
 
1384
                    from_location, revision)
 
1385
                raise errors.BzrCommandError(msg)
 
1386
        else:
 
1387
            branch = br_from.sprout(to_dir, revision_id=revision_id)
1220
1388
        _merge_tags_if_possible(br_from, branch)
1221
1389
        # If the source branch is stacked, the new branch may
1222
1390
        # be stacked whether we asked for that explicitly or not.
1223
1391
        # We therefore need a try/except here and not just 'if stacked:'
1224
1392
        try:
1225
 
            note('Created new stacked branch referring to %s.' %
 
1393
            note(gettext('Created new stacked branch referring to %s.') %
1226
1394
                branch.get_stacked_on_url())
1227
1395
        except (errors.NotStacked, errors.UnstackableBranchFormat,
1228
1396
            errors.UnstackableRepositoryFormat), e:
1229
 
            note('Branched %d revision(s).' % branch.revno())
 
1397
            note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1230
1398
        if bind:
1231
1399
            # Bind to the parent
1232
1400
            parent_branch = Branch.open(from_location)
1233
1401
            branch.bind(parent_branch)
1234
 
            note('New branch bound to %s' % from_location)
 
1402
            note(gettext('New branch bound to %s') % from_location)
1235
1403
        if switch:
1236
1404
            # Switch to the new branch
1237
1405
            wt, _ = WorkingTree.open_containing('.')
1238
1406
            _mod_switch.switch(wt.bzrdir, branch)
1239
 
            note('Switched to branch: %s',
 
1407
            note(gettext('Switched to branch: %s'),
1240
1408
                urlutils.unescape_for_display(branch.base, 'utf-8'))
1241
1409
 
1242
1410
 
 
1411
class cmd_branches(Command):
 
1412
    __doc__ = """List the branches available at the current location.
 
1413
 
 
1414
    This command will print the names of all the branches at the current
 
1415
    location.
 
1416
    """
 
1417
 
 
1418
    takes_args = ['location?']
 
1419
    takes_options = [
 
1420
                  Option('recursive', short_name='R',
 
1421
                         help='Recursively scan for branches rather than '
 
1422
                              'just looking in the specified location.')]
 
1423
 
 
1424
    def run(self, location=".", recursive=False):
 
1425
        if recursive:
 
1426
            t = transport.get_transport(location)
 
1427
            if not t.listable():
 
1428
                raise errors.BzrCommandError(
 
1429
                    "Can't scan this type of location.")
 
1430
            for b in controldir.ControlDir.find_branches(t):
 
1431
                self.outf.write("%s\n" % urlutils.unescape_for_display(
 
1432
                    urlutils.relative_url(t.base, b.base),
 
1433
                    self.outf.encoding).rstrip("/"))
 
1434
        else:
 
1435
            dir = controldir.ControlDir.open_containing(location)[0]
 
1436
            for branch in dir.list_branches():
 
1437
                if branch.name is None:
 
1438
                    self.outf.write(gettext(" (default)\n"))
 
1439
                else:
 
1440
                    self.outf.write(" %s\n" % branch.name.encode(
 
1441
                        self.outf.encoding))
 
1442
 
 
1443
 
1243
1444
class cmd_checkout(Command):
1244
1445
    __doc__ = """Create a new checkout of an existing branch.
1245
1446
 
1284
1485
        if branch_location is None:
1285
1486
            branch_location = osutils.getcwd()
1286
1487
            to_location = branch_location
1287
 
        accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
 
1488
        accelerator_tree, source = controldir.ControlDir.open_tree_or_branch(
1288
1489
            branch_location)
1289
1490
        if not (hardlink or files_from):
1290
1491
            # accelerator_tree is usually slower because you have to read N
1345
1546
 
1346
1547
 
1347
1548
class cmd_update(Command):
1348
 
    __doc__ = """Update a tree to have the latest code committed to its branch.
1349
 
 
1350
 
    This will perform a merge into the working tree, and may generate
1351
 
    conflicts. If you have any local changes, you will still
1352
 
    need to commit them after the update for the update to be complete.
1353
 
 
1354
 
    If you want to discard your local changes, you can just do a
1355
 
    'bzr revert' instead of 'bzr commit' after the update.
1356
 
 
1357
 
    If you want to restore a file that has been removed locally, use
1358
 
    'bzr revert' instead of 'bzr update'.
1359
 
 
1360
 
    If the tree's branch is bound to a master branch, it will also update
 
1549
    __doc__ = """Update a working tree to a new revision.
 
1550
 
 
1551
    This will perform a merge of the destination revision (the tip of the
 
1552
    branch, or the specified revision) into the working tree, and then make
 
1553
    that revision the basis revision for the working tree.  
 
1554
 
 
1555
    You can use this to visit an older revision, or to update a working tree
 
1556
    that is out of date from its branch.
 
1557
    
 
1558
    If there are any uncommitted changes in the tree, they will be carried
 
1559
    across and remain as uncommitted changes after the update.  To discard
 
1560
    these changes, use 'bzr revert'.  The uncommitted changes may conflict
 
1561
    with the changes brought in by the change in basis revision.
 
1562
 
 
1563
    If the tree's branch is bound to a master branch, bzr will also update
1361
1564
    the branch from the master.
 
1565
 
 
1566
    You cannot update just a single file or directory, because each Bazaar
 
1567
    working tree has just a single basis revision.  If you want to restore a
 
1568
    file that has been removed locally, use 'bzr revert' instead of 'bzr
 
1569
    update'.  If you want to restore a file to its state in a previous
 
1570
    revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
 
1571
    out the old content of that file to a new location.
 
1572
 
 
1573
    The 'dir' argument, if given, must be the location of the root of a
 
1574
    working tree to update.  By default, the working tree that contains the 
 
1575
    current working directory is used.
1362
1576
    """
1363
1577
 
1364
1578
    _see_also = ['pull', 'working-trees', 'status-flags']
1365
1579
    takes_args = ['dir?']
1366
 
    takes_options = ['revision']
 
1580
    takes_options = ['revision',
 
1581
                     Option('show-base',
 
1582
                            help="Show base revision text in conflicts."),
 
1583
                     ]
1367
1584
    aliases = ['up']
1368
1585
 
1369
 
    def run(self, dir='.', revision=None):
 
1586
    def run(self, dir=None, revision=None, show_base=None):
1370
1587
        if revision is not None and len(revision) != 1:
1371
 
            raise errors.BzrCommandError(
1372
 
                        "bzr update --revision takes exactly one revision")
1373
 
        tree = WorkingTree.open_containing(dir)[0]
 
1588
            raise errors.BzrCommandError(gettext(
 
1589
                "bzr update --revision takes exactly one revision"))
 
1590
        if dir is None:
 
1591
            tree = WorkingTree.open_containing('.')[0]
 
1592
        else:
 
1593
            tree, relpath = WorkingTree.open_containing(dir)
 
1594
            if relpath:
 
1595
                # See bug 557886.
 
1596
                raise errors.BzrCommandError(gettext(
 
1597
                    "bzr update can only update a whole tree, "
 
1598
                    "not a file or subdirectory"))
1374
1599
        branch = tree.branch
1375
1600
        possible_transports = []
1376
1601
        master = branch.get_master_branch(
1400
1625
            revision_id = branch.last_revision()
1401
1626
        if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1402
1627
            revno = branch.revision_id_to_dotted_revno(revision_id)
1403
 
            note("Tree is up to date at revision %s of branch %s" %
1404
 
                ('.'.join(map(str, revno)), branch_location))
 
1628
            note(gettext("Tree is up to date at revision {0} of branch {1}"
 
1629
                        ).format('.'.join(map(str, revno)), branch_location))
1405
1630
            return 0
1406
1631
        view_info = _get_view_info_for_change_reporter(tree)
1407
1632
        change_reporter = delta._ChangeReporter(
1412
1637
                change_reporter,
1413
1638
                possible_transports=possible_transports,
1414
1639
                revision=revision_id,
1415
 
                old_tip=old_tip)
 
1640
                old_tip=old_tip,
 
1641
                show_base=show_base)
1416
1642
        except errors.NoSuchRevision, e:
1417
 
            raise errors.BzrCommandError(
 
1643
            raise errors.BzrCommandError(gettext(
1418
1644
                                  "branch has no revision %s\n"
1419
1645
                                  "bzr update --revision only works"
1420
 
                                  " for a revision in the branch history"
 
1646
                                  " for a revision in the branch history")
1421
1647
                                  % (e.revision))
1422
1648
        revno = tree.branch.revision_id_to_dotted_revno(
1423
1649
            _mod_revision.ensure_null(tree.last_revision()))
1424
 
        note('Updated to revision %s of branch %s' %
1425
 
             ('.'.join(map(str, revno)), branch_location))
 
1650
        note(gettext('Updated to revision {0} of branch {1}').format(
 
1651
             '.'.join(map(str, revno)), branch_location))
1426
1652
        parent_ids = tree.get_parent_ids()
1427
1653
        if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1428
 
            note('Your local commits will now show as pending merges with '
1429
 
                 "'bzr status', and can be committed with 'bzr commit'.")
 
1654
            note(gettext('Your local commits will now show as pending merges with '
 
1655
                 "'bzr status', and can be committed with 'bzr commit'."))
1430
1656
        if conflicts != 0:
1431
1657
            return 1
1432
1658
        else:
1473
1699
        else:
1474
1700
            noise_level = 0
1475
1701
        from bzrlib.info import show_bzrdir_info
1476
 
        show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
 
1702
        show_bzrdir_info(controldir.ControlDir.open_containing(location)[0],
1477
1703
                         verbose=noise_level, outfile=self.outf)
1478
1704
 
1479
1705
 
1494
1720
            title='Deletion Strategy', value_switches=True, enum_switch=False,
1495
1721
            safe='Backup changed files (default).',
1496
1722
            keep='Delete from bzr but leave the working copy.',
 
1723
            no_backup='Don\'t backup changed files.',
1497
1724
            force='Delete all the specified files, even if they can not be '
1498
 
                'recovered and even if they are non-empty directories.')]
 
1725
                'recovered and even if they are non-empty directories. '
 
1726
                '(deprecated, use no-backup)')]
1499
1727
    aliases = ['rm', 'del']
1500
1728
    encoding_type = 'replace'
1501
1729
 
1502
1730
    def run(self, file_list, verbose=False, new=False,
1503
1731
        file_deletion_strategy='safe'):
 
1732
        if file_deletion_strategy == 'force':
 
1733
            note(gettext("(The --force option is deprecated, rather use --no-backup "
 
1734
                "in future.)"))
 
1735
            file_deletion_strategy = 'no-backup'
 
1736
 
1504
1737
        tree, file_list = WorkingTree.open_containing_paths(file_list)
1505
1738
 
1506
1739
        if file_list is not None:
1514
1747
                specific_files=file_list).added
1515
1748
            file_list = sorted([f[0] for f in added], reverse=True)
1516
1749
            if len(file_list) == 0:
1517
 
                raise errors.BzrCommandError('No matching files.')
 
1750
                raise errors.BzrCommandError(gettext('No matching files.'))
1518
1751
        elif file_list is None:
1519
1752
            # missing files show up in iter_changes(basis) as
1520
1753
            # versioned-with-no-kind.
1527
1760
            file_deletion_strategy = 'keep'
1528
1761
        tree.remove(file_list, verbose=verbose, to_file=self.outf,
1529
1762
            keep_files=file_deletion_strategy=='keep',
1530
 
            force=file_deletion_strategy=='force')
 
1763
            force=(file_deletion_strategy=='no-backup'))
1531
1764
 
1532
1765
 
1533
1766
class cmd_file_id(Command):
1604
1837
 
1605
1838
    def run(self, branch=".", canonicalize_chks=False):
1606
1839
        from bzrlib.reconcile import reconcile
1607
 
        dir = bzrdir.BzrDir.open(branch)
 
1840
        dir = controldir.ControlDir.open(branch)
1608
1841
        reconcile(dir, canonicalize_chks=canonicalize_chks)
1609
1842
 
1610
1843
 
1619
1852
    @display_command
1620
1853
    def run(self, location="."):
1621
1854
        branch = Branch.open_containing(location)[0]
1622
 
        for revid in branch.revision_history():
 
1855
        self.add_cleanup(branch.lock_read().unlock)
 
1856
        graph = branch.repository.get_graph()
 
1857
        history = list(graph.iter_lefthand_ancestry(branch.last_revision(),
 
1858
            [_mod_revision.NULL_REVISION]))
 
1859
        for revid in reversed(history):
1623
1860
            self.outf.write(revid)
1624
1861
            self.outf.write('\n')
1625
1862
 
1643
1880
            b = wt.branch
1644
1881
            last_revision = wt.last_revision()
1645
1882
 
1646
 
        revision_ids = b.repository.get_ancestry(last_revision)
1647
 
        revision_ids.pop(0)
1648
 
        for revision_id in revision_ids:
 
1883
        self.add_cleanup(b.repository.lock_read().unlock)
 
1884
        graph = b.repository.get_graph()
 
1885
        revisions = [revid for revid, parents in
 
1886
            graph.iter_ancestry([last_revision])]
 
1887
        for revision_id in reversed(revisions):
 
1888
            if _mod_revision.is_null(revision_id):
 
1889
                continue
1649
1890
            self.outf.write(revision_id + '\n')
1650
1891
 
1651
1892
 
1682
1923
                help='Specify a format for this branch. '
1683
1924
                'See "help formats".',
1684
1925
                lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1685
 
                converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
1926
                converter=lambda name: controldir.format_registry.make_bzrdir(name),
1686
1927
                value_switches=True,
1687
1928
                title="Branch format",
1688
1929
                ),
1689
1930
         Option('append-revisions-only',
1690
1931
                help='Never change revnos or the existing log.'
1691
 
                '  Append revisions to it only.')
 
1932
                '  Append revisions to it only.'),
 
1933
         Option('no-tree',
 
1934
                'Create a branch without a working tree.')
1692
1935
         ]
1693
1936
    def run(self, location=None, format=None, append_revisions_only=False,
1694
 
            create_prefix=False):
 
1937
            create_prefix=False, no_tree=False):
1695
1938
        if format is None:
1696
 
            format = bzrdir.format_registry.make_bzrdir('default')
 
1939
            format = controldir.format_registry.make_bzrdir('default')
1697
1940
        if location is None:
1698
1941
            location = u'.'
1699
1942
 
1708
1951
            to_transport.ensure_base()
1709
1952
        except errors.NoSuchFile:
1710
1953
            if not create_prefix:
1711
 
                raise errors.BzrCommandError("Parent directory of %s"
 
1954
                raise errors.BzrCommandError(gettext("Parent directory of %s"
1712
1955
                    " does not exist."
1713
1956
                    "\nYou may supply --create-prefix to create all"
1714
 
                    " leading parent directories."
 
1957
                    " leading parent directories.")
1715
1958
                    % location)
1716
1959
            to_transport.create_prefix()
1717
1960
 
1718
1961
        try:
1719
 
            a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
 
1962
            a_bzrdir = controldir.ControlDir.open_from_transport(to_transport)
1720
1963
        except errors.NotBranchError:
1721
1964
            # really a NotBzrDir error...
1722
 
            create_branch = bzrdir.BzrDir.create_branch_convenience
 
1965
            create_branch = controldir.ControlDir.create_branch_convenience
 
1966
            if no_tree:
 
1967
                force_new_tree = False
 
1968
            else:
 
1969
                force_new_tree = None
1723
1970
            branch = create_branch(to_transport.base, format=format,
1724
 
                                   possible_transports=[to_transport])
 
1971
                                   possible_transports=[to_transport],
 
1972
                                   force_new_tree=force_new_tree)
1725
1973
            a_bzrdir = branch.bzrdir
1726
1974
        else:
1727
1975
            from bzrlib.transport.local import LocalTransport
1731
1979
                        raise errors.BranchExistsWithoutWorkingTree(location)
1732
1980
                raise errors.AlreadyBranchError(location)
1733
1981
            branch = a_bzrdir.create_branch()
1734
 
            a_bzrdir.create_workingtree()
 
1982
            if not no_tree and not a_bzrdir.has_workingtree():
 
1983
                a_bzrdir.create_workingtree()
1735
1984
        if append_revisions_only:
1736
1985
            try:
1737
1986
                branch.set_append_revisions_only(True)
1738
1987
            except errors.UpgradeRequired:
1739
 
                raise errors.BzrCommandError('This branch format cannot be set'
1740
 
                    ' to append-revisions-only.  Try --default.')
 
1988
                raise errors.BzrCommandError(gettext('This branch format cannot be set'
 
1989
                    ' to append-revisions-only.  Try --default.'))
1741
1990
        if not is_quiet():
1742
1991
            from bzrlib.info import describe_layout, describe_format
1743
1992
            try:
1747
1996
            repository = branch.repository
1748
1997
            layout = describe_layout(repository, branch, tree).lower()
1749
1998
            format = describe_format(a_bzrdir, repository, branch, tree)
1750
 
            self.outf.write("Created a %s (format: %s)\n" % (layout, format))
 
1999
            self.outf.write(gettext("Created a {0} (format: {1})\n").format(
 
2000
                  layout, format))
1751
2001
            if repository.is_shared():
1752
2002
                #XXX: maybe this can be refactored into transport.path_or_url()
1753
2003
                url = repository.bzrdir.root_transport.external_url()
1755
2005
                    url = urlutils.local_path_from_url(url)
1756
2006
                except errors.InvalidURL:
1757
2007
                    pass
1758
 
                self.outf.write("Using shared repository: %s\n" % url)
 
2008
                self.outf.write(gettext("Using shared repository: %s\n") % url)
1759
2009
 
1760
2010
 
1761
2011
class cmd_init_repository(Command):
1791
2041
    takes_options = [RegistryOption('format',
1792
2042
                            help='Specify a format for this repository. See'
1793
2043
                                 ' "bzr help formats" for details.',
1794
 
                            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1795
 
                            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
2044
                            lazy_registry=('bzrlib.controldir', 'format_registry'),
 
2045
                            converter=lambda name: controldir.format_registry.make_bzrdir(name),
1796
2046
                            value_switches=True, title='Repository format'),
1797
2047
                     Option('no-trees',
1798
2048
                             help='Branches in the repository will default to'
1802
2052
 
1803
2053
    def run(self, location, format=None, no_trees=False):
1804
2054
        if format is None:
1805
 
            format = bzrdir.format_registry.make_bzrdir('default')
 
2055
            format = controldir.format_registry.make_bzrdir('default')
1806
2056
 
1807
2057
        if location is None:
1808
2058
            location = '.'
1831
2081
    "bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1832
2082
    produces patches suitable for "patch -p1".
1833
2083
 
 
2084
    Note that when using the -r argument with a range of revisions, the
 
2085
    differences are computed between the two specified revisions.  That
 
2086
    is, the command does not show the changes introduced by the first 
 
2087
    revision in the range.  This differs from the interpretation of 
 
2088
    revision ranges used by "bzr log" which includes the first revision
 
2089
    in the range.
 
2090
 
1834
2091
    :Exit values:
1835
2092
        1 - changed
1836
2093
        2 - unrepresentable changes
1854
2111
 
1855
2112
            bzr diff -r1..3 xxx
1856
2113
 
1857
 
        To see the changes introduced in revision X::
 
2114
        The changes introduced by revision 2 (equivalent to -r1..2)::
 
2115
 
 
2116
            bzr diff -c2
 
2117
 
 
2118
        To see the changes introduced by revision X::
1858
2119
        
1859
2120
            bzr diff -cX
1860
2121
 
1864
2125
 
1865
2126
            bzr diff -r<chosen_parent>..X
1866
2127
 
1867
 
        The changes introduced by revision 2 (equivalent to -r1..2)::
 
2128
        The changes between the current revision and the previous revision
 
2129
        (equivalent to -c-1 and -r-2..-1)
1868
2130
 
1869
 
            bzr diff -c2
 
2131
            bzr diff -r-2..
1870
2132
 
1871
2133
        Show just the differences for file NEWS::
1872
2134
 
1916
2178
            type=unicode,
1917
2179
            ),
1918
2180
        RegistryOption('format',
 
2181
            short_name='F',
1919
2182
            help='Diff format to use.',
1920
2183
            lazy_registry=('bzrlib.diff', 'format_registry'),
1921
 
            value_switches=False, title='Diff format'),
 
2184
            title='Diff format'),
1922
2185
        ]
1923
2186
    aliases = ['di', 'dif']
1924
2187
    encoding_type = 'exact'
1939
2202
        elif ':' in prefix:
1940
2203
            old_label, new_label = prefix.split(":")
1941
2204
        else:
1942
 
            raise errors.BzrCommandError(
 
2205
            raise errors.BzrCommandError(gettext(
1943
2206
                '--prefix expects two values separated by a colon'
1944
 
                ' (eg "old/:new/")')
 
2207
                ' (eg "old/:new/")'))
1945
2208
 
1946
2209
        if revision and len(revision) > 2:
1947
 
            raise errors.BzrCommandError('bzr diff --revision takes exactly'
1948
 
                                         ' one or two revision specifiers')
 
2210
            raise errors.BzrCommandError(gettext('bzr diff --revision takes exactly'
 
2211
                                         ' one or two revision specifiers'))
1949
2212
 
1950
2213
        if using is not None and format is not None:
1951
 
            raise errors.BzrCommandError('--using and --format are mutually '
1952
 
                'exclusive.')
 
2214
            raise errors.BzrCommandError(gettext(
 
2215
                '{0} and {1} are mutually exclusive').format(
 
2216
                '--using', '--format'))
1953
2217
 
1954
2218
        (old_tree, new_tree,
1955
2219
         old_branch, new_branch,
2005
2269
    @display_command
2006
2270
    def run(self, null=False, directory=u'.'):
2007
2271
        tree = WorkingTree.open_containing(directory)[0]
 
2272
        self.add_cleanup(tree.lock_read().unlock)
2008
2273
        td = tree.changes_from(tree.basis_tree())
 
2274
        self.cleanup_now()
2009
2275
        for path, id, kind, text_modified, meta_modified in td.modified:
2010
2276
            if null:
2011
2277
                self.outf.write(path + '\0')
2030
2296
        basis_inv = basis.inventory
2031
2297
        inv = wt.inventory
2032
2298
        for file_id in inv:
2033
 
            if file_id in basis_inv:
 
2299
            if basis_inv.has_id(file_id):
2034
2300
                continue
2035
2301
            if inv.is_root(file_id) and len(basis_inv) == 0:
2036
2302
                continue
2061
2327
    try:
2062
2328
        return int(limitstring)
2063
2329
    except ValueError:
2064
 
        msg = "The limit argument must be an integer."
 
2330
        msg = gettext("The limit argument must be an integer.")
2065
2331
        raise errors.BzrCommandError(msg)
2066
2332
 
2067
2333
 
2069
2335
    try:
2070
2336
        return int(s)
2071
2337
    except ValueError:
2072
 
        msg = "The levels argument must be an integer."
 
2338
        msg = gettext("The levels argument must be an integer.")
2073
2339
        raise errors.BzrCommandError(msg)
2074
2340
 
2075
2341
 
2185
2451
 
2186
2452
    :Other filtering:
2187
2453
 
2188
 
      The --message option can be used for finding revisions that match a
2189
 
      regular expression in a commit message.
 
2454
      The --match option can be used for finding revisions that match a
 
2455
      regular expression in a commit message, committer, author or bug.
 
2456
      Specifying the option several times will match any of the supplied
 
2457
      expressions. --match-author, --match-bugs, --match-committer and
 
2458
      --match-message can be used to only match a specific field.
2190
2459
 
2191
2460
    :Tips & tricks:
2192
2461
 
2252
2521
                   argname='N',
2253
2522
                   type=_parse_levels),
2254
2523
            Option('message',
2255
 
                   short_name='m',
2256
2524
                   help='Show revisions whose message matches this '
2257
2525
                        'regular expression.',
2258
 
                   type=str),
 
2526
                   type=str,
 
2527
                   hidden=True),
2259
2528
            Option('limit',
2260
2529
                   short_name='l',
2261
2530
                   help='Limit the output to the first N revisions.',
2264
2533
            Option('show-diff',
2265
2534
                   short_name='p',
2266
2535
                   help='Show changes made in each revision as a patch.'),
2267
 
            Option('include-merges',
 
2536
            Option('include-merged',
2268
2537
                   help='Show merged revisions like --levels 0 does.'),
 
2538
            Option('include-merges', hidden=True,
 
2539
                   help='Historical alias for --include-merged.'),
 
2540
            Option('omit-merges',
 
2541
                   help='Do not report commits with more than one parent.'),
2269
2542
            Option('exclude-common-ancestry',
2270
2543
                   help='Display only the revisions that are not part'
2271
 
                   ' of both ancestries (require -rX..Y)'
2272
 
                   )
 
2544
                   ' of both ancestries (require -rX..Y).'
 
2545
                   ),
 
2546
            Option('signatures',
 
2547
                   help='Show digital signature validity.'),
 
2548
            ListOption('match',
 
2549
                short_name='m',
 
2550
                help='Show revisions whose properties match this '
 
2551
                'expression.',
 
2552
                type=str),
 
2553
            ListOption('match-message',
 
2554
                   help='Show revisions whose message matches this '
 
2555
                   'expression.',
 
2556
                type=str),
 
2557
            ListOption('match-committer',
 
2558
                   help='Show revisions whose committer matches this '
 
2559
                   'expression.',
 
2560
                type=str),
 
2561
            ListOption('match-author',
 
2562
                   help='Show revisions whose authors match this '
 
2563
                   'expression.',
 
2564
                type=str),
 
2565
            ListOption('match-bugs',
 
2566
                   help='Show revisions whose bugs match this '
 
2567
                   'expression.',
 
2568
                type=str)
2273
2569
            ]
2274
2570
    encoding_type = 'replace'
2275
2571
 
2285
2581
            message=None,
2286
2582
            limit=None,
2287
2583
            show_diff=False,
2288
 
            include_merges=False,
 
2584
            include_merged=None,
2289
2585
            authors=None,
2290
2586
            exclude_common_ancestry=False,
 
2587
            signatures=False,
 
2588
            match=None,
 
2589
            match_message=None,
 
2590
            match_committer=None,
 
2591
            match_author=None,
 
2592
            match_bugs=None,
 
2593
            omit_merges=False,
 
2594
            include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2291
2595
            ):
2292
2596
        from bzrlib.log import (
2293
2597
            Logger,
2295
2599
            _get_info_for_log_files,
2296
2600
            )
2297
2601
        direction = (forward and 'forward') or 'reverse'
 
2602
        if symbol_versioning.deprecated_passed(include_merges):
 
2603
            ui.ui_factory.show_user_warning(
 
2604
                'deprecated_command_option',
 
2605
                deprecated_name='--include-merges',
 
2606
                recommended_name='--include-merged',
 
2607
                deprecated_in_version='2.5',
 
2608
                command=self.invoked_as)
 
2609
            if include_merged is None:
 
2610
                include_merged = include_merges
 
2611
            else:
 
2612
                raise errors.BzrCommandError(gettext(
 
2613
                    '{0} and {1} are mutually exclusive').format(
 
2614
                    '--include-merges', '--include-merged'))
 
2615
        if include_merged is None:
 
2616
            include_merged = False
2298
2617
        if (exclude_common_ancestry
2299
2618
            and (revision is None or len(revision) != 2)):
2300
 
            raise errors.BzrCommandError(
2301
 
                '--exclude-common-ancestry requires -r with two revisions')
2302
 
        if include_merges:
 
2619
            raise errors.BzrCommandError(gettext(
 
2620
                '--exclude-common-ancestry requires -r with two revisions'))
 
2621
        if include_merged:
2303
2622
            if levels is None:
2304
2623
                levels = 0
2305
2624
            else:
2306
 
                raise errors.BzrCommandError(
2307
 
                    '--levels and --include-merges are mutually exclusive')
 
2625
                raise errors.BzrCommandError(gettext(
 
2626
                    '{0} and {1} are mutually exclusive').format(
 
2627
                    '--levels', '--include-merged'))
2308
2628
 
2309
2629
        if change is not None:
2310
2630
            if len(change) > 1:
2311
2631
                raise errors.RangeInChangeOption()
2312
2632
            if revision is not None:
2313
 
                raise errors.BzrCommandError(
2314
 
                    '--revision and --change are mutually exclusive')
 
2633
                raise errors.BzrCommandError(gettext(
 
2634
                    '{0} and {1} are mutually exclusive').format(
 
2635
                    '--revision', '--change'))
2315
2636
            else:
2316
2637
                revision = change
2317
2638
 
2323
2644
                revision, file_list, self.add_cleanup)
2324
2645
            for relpath, file_id, kind in file_info_list:
2325
2646
                if file_id is None:
2326
 
                    raise errors.BzrCommandError(
2327
 
                        "Path unknown at end or start of revision range: %s" %
 
2647
                    raise errors.BzrCommandError(gettext(
 
2648
                        "Path unknown at end or start of revision range: %s") %
2328
2649
                        relpath)
2329
2650
                # If the relpath is the top of the tree, we log everything
2330
2651
                if relpath == '':
2342
2663
                location = revision[0].get_branch()
2343
2664
            else:
2344
2665
                location = '.'
2345
 
            dir, relpath = bzrdir.BzrDir.open_containing(location)
 
2666
            dir, relpath = controldir.ControlDir.open_containing(location)
2346
2667
            b = dir.open_branch()
2347
2668
            self.add_cleanup(b.lock_read().unlock)
2348
2669
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2349
2670
 
 
2671
        if b.get_config().validate_signatures_in_log():
 
2672
            signatures = True
 
2673
 
 
2674
        if signatures:
 
2675
            if not gpg.GPGStrategy.verify_signatures_available():
 
2676
                raise errors.GpgmeNotInstalled(None)
 
2677
 
2350
2678
        # Decide on the type of delta & diff filtering to use
2351
2679
        # TODO: add an --all-files option to make this configurable & consistent
2352
2680
        if not verbose:
2389
2717
        match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2390
2718
            or delta_type or partial_history)
2391
2719
 
 
2720
        match_dict = {}
 
2721
        if match:
 
2722
            match_dict[''] = match
 
2723
        if match_message:
 
2724
            match_dict['message'] = match_message
 
2725
        if match_committer:
 
2726
            match_dict['committer'] = match_committer
 
2727
        if match_author:
 
2728
            match_dict['author'] = match_author
 
2729
        if match_bugs:
 
2730
            match_dict['bugs'] = match_bugs
 
2731
 
2392
2732
        # Build the LogRequest and execute it
2393
2733
        if len(file_ids) == 0:
2394
2734
            file_ids = None
2397
2737
            start_revision=rev1, end_revision=rev2, limit=limit,
2398
2738
            message_search=message, delta_type=delta_type,
2399
2739
            diff_type=diff_type, _match_using_deltas=match_using_deltas,
2400
 
            exclude_common_ancestry=exclude_common_ancestry,
 
2740
            exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
 
2741
            signature=signatures, omit_merges=omit_merges,
2401
2742
            )
2402
2743
        Logger(b, rqst).show(lf)
2403
2744
 
2420
2761
            # b is taken from revision[0].get_branch(), and
2421
2762
            # show_log will use its revision_history. Having
2422
2763
            # different branches will lead to weird behaviors.
2423
 
            raise errors.BzrCommandError(
 
2764
            raise errors.BzrCommandError(gettext(
2424
2765
                "bzr %s doesn't accept two revisions in different"
2425
 
                " branches." % command_name)
 
2766
                " branches.") % command_name)
2426
2767
        if start_spec.spec is None:
2427
2768
            # Avoid loading all the history.
2428
2769
            rev1 = RevisionInfo(branch, None, None)
2436
2777
        else:
2437
2778
            rev2 = end_spec.in_history(branch)
2438
2779
    else:
2439
 
        raise errors.BzrCommandError(
2440
 
            'bzr %s --revision takes one or two values.' % command_name)
 
2780
        raise errors.BzrCommandError(gettext(
 
2781
            'bzr %s --revision takes one or two values.') % command_name)
2441
2782
    return rev1, rev2
2442
2783
 
2443
2784
 
2514
2855
            null=False, kind=None, show_ids=False, path=None, directory=None):
2515
2856
 
2516
2857
        if kind and kind not in ('file', 'directory', 'symlink'):
2517
 
            raise errors.BzrCommandError('invalid kind specified')
 
2858
            raise errors.BzrCommandError(gettext('invalid kind specified'))
2518
2859
 
2519
2860
        if verbose and null:
2520
 
            raise errors.BzrCommandError('Cannot set both --verbose and --null')
 
2861
            raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
2521
2862
        all = not (unknown or versioned or ignored)
2522
2863
 
2523
2864
        selection = {'I':ignored, '?':unknown, 'V':versioned}
2526
2867
            fs_path = '.'
2527
2868
        else:
2528
2869
            if from_root:
2529
 
                raise errors.BzrCommandError('cannot specify both --from-root'
2530
 
                                             ' and PATH')
 
2870
                raise errors.BzrCommandError(gettext('cannot specify both --from-root'
 
2871
                                             ' and PATH'))
2531
2872
            fs_path = path
2532
2873
        tree, branch, relpath = \
2533
2874
            _open_directory_or_containing_tree_or_branch(fs_path, directory)
2549
2890
            if view_files:
2550
2891
                apply_view = True
2551
2892
                view_str = views.view_display_str(view_files)
2552
 
                note("Ignoring files outside view. View is %s" % view_str)
 
2893
                note(gettext("Ignoring files outside view. View is %s") % view_str)
2553
2894
 
2554
2895
        self.add_cleanup(tree.lock_read().unlock)
2555
2896
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2641
2982
    Patterns prefixed with '!!' act as regular ignore patterns, but have
2642
2983
    precedence over the '!' exception patterns.
2643
2984
 
2644
 
    Note: ignore patterns containing shell wildcards must be quoted from
2645
 
    the shell on Unix.
 
2985
    :Notes: 
 
2986
        
 
2987
    * Ignore patterns containing shell wildcards must be quoted from
 
2988
      the shell on Unix.
 
2989
 
 
2990
    * Ignore patterns starting with "#" act as comments in the ignore file.
 
2991
      To ignore patterns that begin with that character, use the "RE:" prefix.
2646
2992
 
2647
2993
    :Examples:
2648
2994
        Ignore the top level Makefile::
2657
3003
 
2658
3004
            bzr ignore "!special.class"
2659
3005
 
 
3006
        Ignore files whose name begins with the "#" character::
 
3007
 
 
3008
            bzr ignore "RE:^#"
 
3009
 
2660
3010
        Ignore .o files under the lib directory::
2661
3011
 
2662
3012
            bzr ignore "lib/**/*.o"
2670
3020
            bzr ignore "RE:(?!debian/).*"
2671
3021
        
2672
3022
        Ignore everything except the "local" toplevel directory,
2673
 
        but always ignore "*~" autosave files, even under local/::
 
3023
        but always ignore autosave files ending in ~, even under local/::
2674
3024
        
2675
3025
            bzr ignore "*"
2676
3026
            bzr ignore "!./local"
2693
3043
                self.outf.write("%s\n" % pattern)
2694
3044
            return
2695
3045
        if not name_pattern_list:
2696
 
            raise errors.BzrCommandError("ignore requires at least one "
2697
 
                "NAME_PATTERN or --default-rules.")
 
3046
            raise errors.BzrCommandError(gettext("ignore requires at least one "
 
3047
                "NAME_PATTERN or --default-rules."))
2698
3048
        name_pattern_list = [globbing.normalize_pattern(p)
2699
3049
                             for p in name_pattern_list]
2700
3050
        bad_patterns = ''
 
3051
        bad_patterns_count = 0
2701
3052
        for p in name_pattern_list:
2702
3053
            if not globbing.Globster.is_pattern_valid(p):
 
3054
                bad_patterns_count += 1
2703
3055
                bad_patterns += ('\n  %s' % p)
2704
3056
        if bad_patterns:
2705
 
            msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
 
3057
            msg = (ngettext('Invalid ignore pattern found. %s', 
 
3058
                            'Invalid ignore patterns found. %s',
 
3059
                            bad_patterns_count) % bad_patterns)
2706
3060
            ui.ui_factory.show_error(msg)
2707
3061
            raise errors.InvalidPattern('')
2708
3062
        for name_pattern in name_pattern_list:
2709
3063
            if (name_pattern[0] == '/' or
2710
3064
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
2711
 
                raise errors.BzrCommandError(
2712
 
                    "NAME_PATTERN should not be an absolute path")
 
3065
                raise errors.BzrCommandError(gettext(
 
3066
                    "NAME_PATTERN should not be an absolute path"))
2713
3067
        tree, relpath = WorkingTree.open_containing(directory)
2714
3068
        ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2715
3069
        ignored = globbing.Globster(name_pattern_list)
2722
3076
                if ignored.match(filename):
2723
3077
                    matches.append(filename)
2724
3078
        if len(matches) > 0:
2725
 
            self.outf.write("Warning: the following files are version controlled and"
2726
 
                  " match your ignore pattern:\n%s"
 
3079
            self.outf.write(gettext("Warning: the following files are version "
 
3080
                  "controlled and match your ignore pattern:\n%s"
2727
3081
                  "\nThese files will continue to be version controlled"
2728
 
                  " unless you 'bzr remove' them.\n" % ("\n".join(matches),))
 
3082
                  " unless you 'bzr remove' them.\n") % ("\n".join(matches),))
2729
3083
 
2730
3084
 
2731
3085
class cmd_ignored(Command):
2770
3124
        try:
2771
3125
            revno = int(revno)
2772
3126
        except ValueError:
2773
 
            raise errors.BzrCommandError("not a valid revision-number: %r"
 
3127
            raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
2774
3128
                                         % revno)
2775
3129
        revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2776
3130
        self.outf.write("%s\n" % revid)
2804
3158
         zip                          .zip
2805
3159
      =================       =========================
2806
3160
    """
 
3161
    encoding = 'exact'
2807
3162
    takes_args = ['dest', 'branch_or_subdir?']
2808
3163
    takes_options = ['directory',
2809
3164
        Option('format',
2818
3173
        Option('per-file-timestamps',
2819
3174
               help='Set modification time of files to that of the last '
2820
3175
                    'revision in which it was changed.'),
 
3176
        Option('uncommitted',
 
3177
               help='Export the working tree contents rather than that of the '
 
3178
                    'last revision.'),
2821
3179
        ]
2822
3180
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2823
 
        root=None, filters=False, per_file_timestamps=False, directory=u'.'):
 
3181
        root=None, filters=False, per_file_timestamps=False, uncommitted=False,
 
3182
        directory=u'.'):
2824
3183
        from bzrlib.export import export
2825
3184
 
2826
3185
        if branch_or_subdir is None:
2827
 
            tree = WorkingTree.open_containing(directory)[0]
2828
 
            b = tree.branch
2829
 
            subdir = None
 
3186
            branch_or_subdir = directory
 
3187
 
 
3188
        (tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
 
3189
            branch_or_subdir)
 
3190
        if tree is not None:
 
3191
            self.add_cleanup(tree.lock_read().unlock)
 
3192
 
 
3193
        if uncommitted:
 
3194
            if tree is None:
 
3195
                raise errors.BzrCommandError(
 
3196
                    gettext("--uncommitted requires a working tree"))
 
3197
            export_tree = tree
2830
3198
        else:
2831
 
            b, subdir = Branch.open_containing(branch_or_subdir)
2832
 
            tree = None
2833
 
 
2834
 
        rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
 
3199
            export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2835
3200
        try:
2836
 
            export(rev_tree, dest, format, root, subdir, filtered=filters,
 
3201
            export(export_tree, dest, format, root, subdir, filtered=filters,
2837
3202
                   per_file_timestamps=per_file_timestamps)
2838
3203
        except errors.NoSuchExportFormat, e:
2839
 
            raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
 
3204
            raise errors.BzrCommandError(
 
3205
                gettext('Unsupported export format: %s') % e.format)
2840
3206
 
2841
3207
 
2842
3208
class cmd_cat(Command):
2862
3228
    def run(self, filename, revision=None, name_from_revision=False,
2863
3229
            filters=False, directory=None):
2864
3230
        if revision is not None and len(revision) != 1:
2865
 
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
2866
 
                                         " one revision specifier")
 
3231
            raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
 
3232
                                         " one revision specifier"))
2867
3233
        tree, branch, relpath = \
2868
3234
            _open_directory_or_containing_tree_or_branch(filename, directory)
2869
3235
        self.add_cleanup(branch.lock_read().unlock)
2879
3245
 
2880
3246
        old_file_id = rev_tree.path2id(relpath)
2881
3247
 
 
3248
        # TODO: Split out this code to something that generically finds the
 
3249
        # best id for a path across one or more trees; it's like
 
3250
        # find_ids_across_trees but restricted to find just one. -- mbp
 
3251
        # 20110705.
2882
3252
        if name_from_revision:
2883
3253
            # Try in revision if requested
2884
3254
            if old_file_id is None:
2885
 
                raise errors.BzrCommandError(
2886
 
                    "%r is not present in revision %s" % (
 
3255
                raise errors.BzrCommandError(gettext(
 
3256
                    "{0!r} is not present in revision {1}").format(
2887
3257
                        filename, rev_tree.get_revision_id()))
2888
3258
            else:
2889
 
                content = rev_tree.get_file_text(old_file_id)
 
3259
                actual_file_id = old_file_id
2890
3260
        else:
2891
3261
            cur_file_id = tree.path2id(relpath)
2892
 
            found = False
2893
 
            if cur_file_id is not None:
2894
 
                # Then try with the actual file id
2895
 
                try:
2896
 
                    content = rev_tree.get_file_text(cur_file_id)
2897
 
                    found = True
2898
 
                except errors.NoSuchId:
2899
 
                    # The actual file id didn't exist at that time
2900
 
                    pass
2901
 
            if not found and old_file_id is not None:
2902
 
                # Finally try with the old file id
2903
 
                content = rev_tree.get_file_text(old_file_id)
2904
 
                found = True
2905
 
            if not found:
2906
 
                # Can't be found anywhere
2907
 
                raise errors.BzrCommandError(
2908
 
                    "%r is not present in revision %s" % (
 
3262
            if cur_file_id is not None and rev_tree.has_id(cur_file_id):
 
3263
                actual_file_id = cur_file_id
 
3264
            elif old_file_id is not None:
 
3265
                actual_file_id = old_file_id
 
3266
            else:
 
3267
                raise errors.BzrCommandError(gettext(
 
3268
                    "{0!r} is not present in revision {1}").format(
2909
3269
                        filename, rev_tree.get_revision_id()))
2910
3270
        if filtered:
2911
 
            from bzrlib.filters import (
2912
 
                ContentFilterContext,
2913
 
                filtered_output_bytes,
2914
 
                )
2915
 
            filters = rev_tree._content_filter_stack(relpath)
2916
 
            chunks = content.splitlines(True)
2917
 
            content = filtered_output_bytes(chunks, filters,
2918
 
                ContentFilterContext(relpath, rev_tree))
2919
 
            self.cleanup_now()
2920
 
            self.outf.writelines(content)
 
3271
            from bzrlib.filter_tree import ContentFilterTree
 
3272
            filter_tree = ContentFilterTree(rev_tree,
 
3273
                rev_tree._content_filter_stack)
 
3274
            content = filter_tree.get_file_text(actual_file_id)
2921
3275
        else:
2922
 
            self.cleanup_now()
2923
 
            self.outf.write(content)
 
3276
            content = rev_tree.get_file_text(actual_file_id)
 
3277
        self.cleanup_now()
 
3278
        self.outf.write(content)
2924
3279
 
2925
3280
 
2926
3281
class cmd_local_time_offset(Command):
2987
3342
      to trigger updates to external systems like bug trackers. The --fixes
2988
3343
      option can be used to record the association between a revision and
2989
3344
      one or more bugs. See ``bzr help bugs`` for details.
2990
 
 
2991
 
      A selective commit may fail in some cases where the committed
2992
 
      tree would be invalid. Consider::
2993
 
  
2994
 
        bzr init foo
2995
 
        mkdir foo/bar
2996
 
        bzr add foo/bar
2997
 
        bzr commit foo -m "committing foo"
2998
 
        bzr mv foo/bar foo/baz
2999
 
        mkdir foo/bar
3000
 
        bzr add foo/bar
3001
 
        bzr commit foo/bar -m "committing bar but not baz"
3002
 
  
3003
 
      In the example above, the last commit will fail by design. This gives
3004
 
      the user the opportunity to decide whether they want to commit the
3005
 
      rename at the same time, separately first, or not at all. (As a general
3006
 
      rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
3007
3345
    """
3008
 
    # TODO: Run hooks on tree to-be-committed, and after commit.
3009
 
 
3010
 
    # TODO: Strict commit that fails if there are deleted files.
3011
 
    #       (what does "deleted files" mean ??)
3012
 
 
3013
 
    # TODO: Give better message for -s, --summary, used by tla people
3014
 
 
3015
 
    # XXX: verbose currently does nothing
3016
3346
 
3017
3347
    _see_also = ['add', 'bugs', 'hooks', 'uncommit']
3018
3348
    takes_args = ['selected*']
3050
3380
             Option('show-diff', short_name='p',
3051
3381
                    help='When no message is supplied, show the diff along'
3052
3382
                    ' with the status summary in the message editor.'),
 
3383
             Option('lossy', 
 
3384
                    help='When committing to a foreign version control '
 
3385
                    'system do not push data that can not be natively '
 
3386
                    'represented.'),
3053
3387
             ]
3054
3388
    aliases = ['ci', 'checkin']
3055
3389
 
3056
3390
    def _iter_bug_fix_urls(self, fixes, branch):
 
3391
        default_bugtracker  = None
3057
3392
        # Configure the properties for bug fixing attributes.
3058
3393
        for fixed_bug in fixes:
3059
3394
            tokens = fixed_bug.split(':')
3060
 
            if len(tokens) != 2:
3061
 
                raise errors.BzrCommandError(
 
3395
            if len(tokens) == 1:
 
3396
                if default_bugtracker is None:
 
3397
                    branch_config = branch.get_config()
 
3398
                    default_bugtracker = branch_config.get_user_option(
 
3399
                        "bugtracker")
 
3400
                if default_bugtracker is None:
 
3401
                    raise errors.BzrCommandError(gettext(
 
3402
                        "No tracker specified for bug %s. Use the form "
 
3403
                        "'tracker:id' or specify a default bug tracker "
 
3404
                        "using the `bugtracker` option.\nSee "
 
3405
                        "\"bzr help bugs\" for more information on this "
 
3406
                        "feature. Commit refused.") % fixed_bug)
 
3407
                tag = default_bugtracker
 
3408
                bug_id = tokens[0]
 
3409
            elif len(tokens) != 2:
 
3410
                raise errors.BzrCommandError(gettext(
3062
3411
                    "Invalid bug %s. Must be in the form of 'tracker:id'. "
3063
3412
                    "See \"bzr help bugs\" for more information on this "
3064
 
                    "feature.\nCommit refused." % fixed_bug)
3065
 
            tag, bug_id = tokens
 
3413
                    "feature.\nCommit refused.") % fixed_bug)
 
3414
            else:
 
3415
                tag, bug_id = tokens
3066
3416
            try:
3067
3417
                yield bugtracker.get_bug_url(tag, branch, bug_id)
3068
3418
            except errors.UnknownBugTrackerAbbreviation:
3069
 
                raise errors.BzrCommandError(
3070
 
                    'Unrecognized bug %s. Commit refused.' % fixed_bug)
 
3419
                raise errors.BzrCommandError(gettext(
 
3420
                    'Unrecognized bug %s. Commit refused.') % fixed_bug)
3071
3421
            except errors.MalformedBugIdentifier, e:
3072
 
                raise errors.BzrCommandError(
3073
 
                    "%s\nCommit refused." % (str(e),))
 
3422
                raise errors.BzrCommandError(gettext(
 
3423
                    "%s\nCommit refused.") % (str(e),))
3074
3424
 
3075
3425
    def run(self, message=None, file=None, verbose=False, selected_list=None,
3076
3426
            unchanged=False, strict=False, local=False, fixes=None,
3077
 
            author=None, show_diff=False, exclude=None, commit_time=None):
 
3427
            author=None, show_diff=False, exclude=None, commit_time=None,
 
3428
            lossy=False):
3078
3429
        from bzrlib.errors import (
3079
3430
            PointlessCommit,
3080
3431
            ConflictsInTree,
3083
3434
        from bzrlib.msgeditor import (
3084
3435
            edit_commit_message_encoded,
3085
3436
            generate_commit_message_template,
3086
 
            make_commit_message_template_encoded
 
3437
            make_commit_message_template_encoded,
 
3438
            set_commit_message,
3087
3439
        )
3088
3440
 
3089
3441
        commit_stamp = offset = None
3091
3443
            try:
3092
3444
                commit_stamp, offset = timestamp.parse_patch_date(commit_time)
3093
3445
            except ValueError, e:
3094
 
                raise errors.BzrCommandError(
3095
 
                    "Could not parse --commit-time: " + str(e))
3096
 
 
3097
 
        # TODO: Need a blackbox test for invoking the external editor; may be
3098
 
        # slightly problematic to run this cross-platform.
3099
 
 
3100
 
        # TODO: do more checks that the commit will succeed before
3101
 
        # spending the user's valuable time typing a commit message.
 
3446
                raise errors.BzrCommandError(gettext(
 
3447
                    "Could not parse --commit-time: " + str(e)))
3102
3448
 
3103
3449
        properties = {}
3104
3450
 
3137
3483
                message = message.replace('\r\n', '\n')
3138
3484
                message = message.replace('\r', '\n')
3139
3485
            if file:
3140
 
                raise errors.BzrCommandError(
3141
 
                    "please specify either --message or --file")
 
3486
                raise errors.BzrCommandError(gettext(
 
3487
                    "please specify either --message or --file"))
3142
3488
 
3143
3489
        def get_message(commit_obj):
3144
3490
            """Callback to get commit message"""
3161
3507
                # make_commit_message_template_encoded returns user encoding.
3162
3508
                # We probably want to be using edit_commit_message instead to
3163
3509
                # avoid this.
3164
 
                start_message = generate_commit_message_template(commit_obj)
3165
 
                my_message = edit_commit_message_encoded(text,
3166
 
                    start_message=start_message)
3167
 
                if my_message is None:
3168
 
                    raise errors.BzrCommandError("please specify a commit"
3169
 
                        " message with either --message or --file")
3170
 
            if my_message == "":
3171
 
                raise errors.BzrCommandError("empty commit message specified")
 
3510
                my_message = set_commit_message(commit_obj)
 
3511
                if my_message is None:
 
3512
                    start_message = generate_commit_message_template(commit_obj)
 
3513
                    my_message = edit_commit_message_encoded(text,
 
3514
                        start_message=start_message)
 
3515
                if my_message is None:
 
3516
                    raise errors.BzrCommandError(gettext("please specify a commit"
 
3517
                        " message with either --message or --file"))
 
3518
                if my_message == "":
 
3519
                    raise errors.BzrCommandError(gettext("Empty commit message specified."
 
3520
                            " Please specify a commit message with either"
 
3521
                            " --message or --file or leave a blank message"
 
3522
                            " with --message \"\"."))
3172
3523
            return my_message
3173
3524
 
3174
3525
        # The API permits a commit with a filter of [] to mean 'select nothing'
3182
3533
                        reporter=None, verbose=verbose, revprops=properties,
3183
3534
                        authors=author, timestamp=commit_stamp,
3184
3535
                        timezone=offset,
3185
 
                        exclude=tree.safe_relpath_files(exclude))
 
3536
                        exclude=tree.safe_relpath_files(exclude),
 
3537
                        lossy=lossy)
3186
3538
        except PointlessCommit:
3187
 
            raise errors.BzrCommandError("No changes to commit."
3188
 
                              " Use --unchanged to commit anyhow.")
 
3539
            raise errors.BzrCommandError(gettext("No changes to commit."
 
3540
                " Please 'bzr add' the files you want to commit, or use"
 
3541
                " --unchanged to force an empty commit."))
3189
3542
        except ConflictsInTree:
3190
 
            raise errors.BzrCommandError('Conflicts detected in working '
 
3543
            raise errors.BzrCommandError(gettext('Conflicts detected in working '
3191
3544
                'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
3192
 
                ' resolve.')
 
3545
                ' resolve.'))
3193
3546
        except StrictCommitFailed:
3194
 
            raise errors.BzrCommandError("Commit refused because there are"
3195
 
                              " unknown files in the working tree.")
 
3547
            raise errors.BzrCommandError(gettext("Commit refused because there are"
 
3548
                              " unknown files in the working tree."))
3196
3549
        except errors.BoundBranchOutOfDate, e:
3197
 
            e.extra_help = ("\n"
 
3550
            e.extra_help = (gettext("\n"
3198
3551
                'To commit to master branch, run update and then commit.\n'
3199
3552
                'You can also pass --local to commit to continue working '
3200
 
                'disconnected.')
 
3553
                'disconnected.'))
3201
3554
            raise
3202
3555
 
3203
3556
 
3272
3625
 
3273
3626
 
3274
3627
class cmd_upgrade(Command):
3275
 
    __doc__ = """Upgrade branch storage to current format.
3276
 
 
3277
 
    The check command or bzr developers may sometimes advise you to run
3278
 
    this command. When the default format has changed you may also be warned
3279
 
    during other operations to upgrade.
 
3628
    __doc__ = """Upgrade a repository, branch or working tree to a newer format.
 
3629
 
 
3630
    When the default format has changed after a major new release of
 
3631
    Bazaar, you may be informed during certain operations that you
 
3632
    should upgrade. Upgrading to a newer format may improve performance
 
3633
    or make new features available. It may however limit interoperability
 
3634
    with older repositories or with older versions of Bazaar.
 
3635
 
 
3636
    If you wish to upgrade to a particular format rather than the
 
3637
    current default, that can be specified using the --format option.
 
3638
    As a consequence, you can use the upgrade command this way to
 
3639
    "downgrade" to an earlier format, though some conversions are
 
3640
    a one way process (e.g. changing from the 1.x default to the
 
3641
    2.x default) so downgrading is not always possible.
 
3642
 
 
3643
    A backup.bzr.~#~ directory is created at the start of the conversion
 
3644
    process (where # is a number). By default, this is left there on
 
3645
    completion. If the conversion fails, delete the new .bzr directory
 
3646
    and rename this one back in its place. Use the --clean option to ask
 
3647
    for the backup.bzr directory to be removed on successful conversion.
 
3648
    Alternatively, you can delete it by hand if everything looks good
 
3649
    afterwards.
 
3650
 
 
3651
    If the location given is a shared repository, dependent branches
 
3652
    are also converted provided the repository converts successfully.
 
3653
    If the conversion of a branch fails, remaining branches are still
 
3654
    tried.
 
3655
 
 
3656
    For more information on upgrades, see the Bazaar Upgrade Guide,
 
3657
    http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
3280
3658
    """
3281
3659
 
3282
 
    _see_also = ['check']
 
3660
    _see_also = ['check', 'reconcile', 'formats']
3283
3661
    takes_args = ['url?']
3284
3662
    takes_options = [
3285
 
                    RegistryOption('format',
3286
 
                        help='Upgrade to a specific format.  See "bzr help'
3287
 
                             ' formats" for details.',
3288
 
                        lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3289
 
                        converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3290
 
                        value_switches=True, title='Branch format'),
3291
 
                    ]
 
3663
        RegistryOption('format',
 
3664
            help='Upgrade to a specific format.  See "bzr help'
 
3665
                 ' formats" for details.',
 
3666
            lazy_registry=('bzrlib.controldir', 'format_registry'),
 
3667
            converter=lambda name: controldir.format_registry.make_bzrdir(name),
 
3668
            value_switches=True, title='Branch format'),
 
3669
        Option('clean',
 
3670
            help='Remove the backup.bzr directory if successful.'),
 
3671
        Option('dry-run',
 
3672
            help="Show what would be done, but don't actually do anything."),
 
3673
    ]
3292
3674
 
3293
 
    def run(self, url='.', format=None):
 
3675
    def run(self, url='.', format=None, clean=False, dry_run=False):
3294
3676
        from bzrlib.upgrade import upgrade
3295
 
        upgrade(url, format)
 
3677
        exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
 
3678
        if exceptions:
 
3679
            if len(exceptions) == 1:
 
3680
                # Compatibility with historical behavior
 
3681
                raise exceptions[0]
 
3682
            else:
 
3683
                return 3
3296
3684
 
3297
3685
 
3298
3686
class cmd_whoami(Command):
3323
3711
            if directory is None:
3324
3712
                # use branch if we're inside one; otherwise global config
3325
3713
                try:
3326
 
                    c = Branch.open_containing(u'.')[0].get_config()
 
3714
                    c = Branch.open_containing(u'.')[0].get_config_stack()
3327
3715
                except errors.NotBranchError:
3328
 
                    c = _mod_config.GlobalConfig()
 
3716
                    c = _mod_config.GlobalStack()
3329
3717
            else:
3330
 
                c = Branch.open(directory).get_config()
 
3718
                c = Branch.open(directory).get_config_stack()
 
3719
            identity = c.get('email')
3331
3720
            if email:
3332
 
                self.outf.write(c.user_email() + '\n')
 
3721
                self.outf.write(_mod_config.extract_email_address(identity)
 
3722
                                + '\n')
3333
3723
            else:
3334
 
                self.outf.write(c.username() + '\n')
 
3724
                self.outf.write(identity + '\n')
3335
3725
            return
3336
3726
 
 
3727
        if email:
 
3728
            raise errors.BzrCommandError(gettext("--email can only be used to display existing "
 
3729
                                         "identity"))
 
3730
 
3337
3731
        # display a warning if an email address isn't included in the given name.
3338
3732
        try:
3339
3733
            _mod_config.extract_email_address(name)
3344
3738
        # use global config unless --branch given
3345
3739
        if branch:
3346
3740
            if directory is None:
3347
 
                c = Branch.open_containing(u'.')[0].get_config()
 
3741
                c = Branch.open_containing(u'.')[0].get_config_stack()
3348
3742
            else:
3349
 
                c = Branch.open(directory).get_config()
 
3743
                c = Branch.open(directory).get_config_stack()
3350
3744
        else:
3351
 
            c = _mod_config.GlobalConfig()
3352
 
        c.set_user_option('email', name)
 
3745
            c = _mod_config.GlobalStack()
 
3746
        c.set('email', name)
3353
3747
 
3354
3748
 
3355
3749
class cmd_nick(Command):
3417
3811
 
3418
3812
    def remove_alias(self, alias_name):
3419
3813
        if alias_name is None:
3420
 
            raise errors.BzrCommandError(
3421
 
                'bzr alias --remove expects an alias to remove.')
 
3814
            raise errors.BzrCommandError(gettext(
 
3815
                'bzr alias --remove expects an alias to remove.'))
3422
3816
        # If alias is not found, print something like:
3423
3817
        # unalias: foo: not found
3424
3818
        c = _mod_config.GlobalConfig()
3503
3897
        if typestring == "sftp":
3504
3898
            from bzrlib.tests import stub_sftp
3505
3899
            return stub_sftp.SFTPAbsoluteServer
3506
 
        if typestring == "memory":
 
3900
        elif typestring == "memory":
3507
3901
            from bzrlib.tests import test_server
3508
3902
            return memory.MemoryServer
3509
 
        if typestring == "fakenfs":
 
3903
        elif typestring == "fakenfs":
3510
3904
            from bzrlib.tests import test_server
3511
3905
            return test_server.FakeNFSServer
3512
3906
        msg = "No known transport type %s. Supported types are: sftp\n" %\
3546
3940
                     Option('randomize', type=str, argname="SEED",
3547
3941
                            help='Randomize the order of tests using the given'
3548
3942
                                 ' seed or "now" for the current time.'),
3549
 
                     Option('exclude', type=str, argname="PATTERN",
3550
 
                            short_name='x',
3551
 
                            help='Exclude tests that match this regular'
3552
 
                                 ' expression.'),
 
3943
                     ListOption('exclude', type=str, argname="PATTERN",
 
3944
                                short_name='x',
 
3945
                                help='Exclude tests that match this regular'
 
3946
                                ' expression.'),
3553
3947
                     Option('subunit',
3554
3948
                        help='Output test progress via subunit.'),
3555
3949
                     Option('strict', help='Fail on missing dependencies or '
3562
3956
                                param_name='starting_with', short_name='s',
3563
3957
                                help=
3564
3958
                                'Load only the tests starting with TESTID.'),
 
3959
                     Option('sync',
 
3960
                            help="By default we disable fsync and fdatasync"
 
3961
                                 " while running the test suite.")
3565
3962
                     ]
3566
3963
    encoding_type = 'replace'
3567
3964
 
3575
3972
            first=False, list_only=False,
3576
3973
            randomize=None, exclude=None, strict=False,
3577
3974
            load_list=None, debugflag=None, starting_with=None, subunit=False,
3578
 
            parallel=None, lsprof_tests=False):
 
3975
            parallel=None, lsprof_tests=False,
 
3976
            sync=False):
3579
3977
        from bzrlib import tests
3580
3978
 
3581
3979
        if testspecs_list is not None:
3586
3984
            try:
3587
3985
                from bzrlib.tests import SubUnitBzrRunner
3588
3986
            except ImportError:
3589
 
                raise errors.BzrCommandError("subunit not available. subunit "
3590
 
                    "needs to be installed to use --subunit.")
 
3987
                raise errors.BzrCommandError(gettext("subunit not available. subunit "
 
3988
                    "needs to be installed to use --subunit."))
3591
3989
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3592
3990
            # On Windows, disable automatic conversion of '\n' to '\r\n' in
3593
3991
            # stdout, which would corrupt the subunit stream. 
3602
4000
            self.additional_selftest_args.setdefault(
3603
4001
                'suite_decorators', []).append(parallel)
3604
4002
        if benchmark:
3605
 
            raise errors.BzrCommandError(
 
4003
            raise errors.BzrCommandError(gettext(
3606
4004
                "--benchmark is no longer supported from bzr 2.2; "
3607
 
                "use bzr-usertest instead")
 
4005
                "use bzr-usertest instead"))
3608
4006
        test_suite_factory = None
 
4007
        if not exclude:
 
4008
            exclude_pattern = None
 
4009
        else:
 
4010
            exclude_pattern = '(' + '|'.join(exclude) + ')'
 
4011
        if not sync:
 
4012
            self._disable_fsync()
3609
4013
        selftest_kwargs = {"verbose": verbose,
3610
4014
                          "pattern": pattern,
3611
4015
                          "stop_on_failure": one,
3616
4020
                          "matching_tests_first": first,
3617
4021
                          "list_only": list_only,
3618
4022
                          "random_seed": randomize,
3619
 
                          "exclude_pattern": exclude,
 
4023
                          "exclude_pattern": exclude_pattern,
3620
4024
                          "strict": strict,
3621
4025
                          "load_list": load_list,
3622
4026
                          "debug_flags": debugflag,
3633
4037
            cleanup()
3634
4038
        return int(not result)
3635
4039
 
 
4040
    def _disable_fsync(self):
 
4041
        """Change the 'os' functionality to not synchronize."""
 
4042
        self._orig_fsync = getattr(os, 'fsync', None)
 
4043
        if self._orig_fsync is not None:
 
4044
            os.fsync = lambda filedes: None
 
4045
        self._orig_fdatasync = getattr(os, 'fdatasync', None)
 
4046
        if self._orig_fdatasync is not None:
 
4047
            os.fdatasync = lambda filedes: None
 
4048
 
3636
4049
 
3637
4050
class cmd_version(Command):
3638
4051
    __doc__ = """Show version of bzr."""
3658
4071
 
3659
4072
    @display_command
3660
4073
    def run(self):
3661
 
        self.outf.write("It sure does!\n")
 
4074
        self.outf.write(gettext("It sure does!\n"))
3662
4075
 
3663
4076
 
3664
4077
class cmd_find_merge_base(Command):
3682
4095
        graph = branch1.repository.get_graph(branch2.repository)
3683
4096
        base_rev_id = graph.find_unique_lca(last1, last2)
3684
4097
 
3685
 
        self.outf.write('merge base is revision %s\n' % base_rev_id)
 
4098
        self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
3686
4099
 
3687
4100
 
3688
4101
class cmd_merge(Command):
3691
4104
    The source of the merge can be specified either in the form of a branch,
3692
4105
    or in the form of a path to a file containing a merge directive generated
3693
4106
    with bzr send. If neither is specified, the default is the upstream branch
3694
 
    or the branch most recently merged using --remember.
3695
 
 
3696
 
    When merging a branch, by default the tip will be merged. To pick a different
3697
 
    revision, pass --revision. If you specify two values, the first will be used as
3698
 
    BASE and the second one as OTHER. Merging individual revisions, or a subset of
3699
 
    available revisions, like this is commonly referred to as "cherrypicking".
3700
 
 
3701
 
    Revision numbers are always relative to the branch being merged.
3702
 
 
3703
 
    By default, bzr will try to merge in all new work from the other
3704
 
    branch, automatically determining an appropriate base.  If this
3705
 
    fails, you may need to give an explicit base.
 
4107
    or the branch most recently merged using --remember.  The source of the
 
4108
    merge may also be specified in the form of a path to a file in another
 
4109
    branch:  in this case, only the modifications to that file are merged into
 
4110
    the current working tree.
 
4111
 
 
4112
    When merging from a branch, by default bzr will try to merge in all new
 
4113
    work from the other branch, automatically determining an appropriate base
 
4114
    revision.  If this fails, you may need to give an explicit base.
 
4115
 
 
4116
    To pick a different ending revision, pass "--revision OTHER".  bzr will
 
4117
    try to merge in all new work up to and including revision OTHER.
 
4118
 
 
4119
    If you specify two values, "--revision BASE..OTHER", only revisions BASE
 
4120
    through OTHER, excluding BASE but including OTHER, will be merged.  If this
 
4121
    causes some revisions to be skipped, i.e. if the destination branch does
 
4122
    not already contain revision BASE, such a merge is commonly referred to as
 
4123
    a "cherrypick". Unlike a normal merge, Bazaar does not currently track
 
4124
    cherrypicks. The changes look like a normal commit, and the history of the
 
4125
    changes from the other branch is not stored in the commit.
 
4126
 
 
4127
    Revision numbers are always relative to the source branch.
3706
4128
 
3707
4129
    Merge will do its best to combine the changes in two branches, but there
3708
4130
    are some kinds of problems only a human can fix.  When it encounters those,
3711
4133
 
3712
4134
    Use bzr resolve when you have fixed a problem.  See also bzr conflicts.
3713
4135
 
3714
 
    If there is no default branch set, the first merge will set it. After
3715
 
    that, you can omit the branch to use the default.  To change the
3716
 
    default, use --remember. The value will only be saved if the remote
3717
 
    location can be accessed.
 
4136
    If there is no default branch set, the first merge will set it (use
 
4137
    --no-remember to avoid setting it). After that, you can omit the branch
 
4138
    to use the default.  To change the default, use --remember. The value will
 
4139
    only be saved if the remote location can be accessed.
3718
4140
 
3719
4141
    The results of the merge are placed into the destination working
3720
4142
    directory, where they can be reviewed (with bzr diff), tested, and then
3721
4143
    committed to record the result of the merge.
3722
4144
 
3723
4145
    merge refuses to run if there are any uncommitted changes, unless
3724
 
    --force is given. The --force option can also be used to create a
 
4146
    --force is given.  If --force is given, then the changes from the source 
 
4147
    will be merged with the current working tree, including any uncommitted
 
4148
    changes in the tree.  The --force option can also be used to create a
3725
4149
    merge revision which has more than two parents.
3726
4150
 
3727
4151
    If one would like to merge changes from the working tree of the other
3732
4156
    you to apply each diff hunk and file change, similar to "shelve".
3733
4157
 
3734
4158
    :Examples:
3735
 
        To merge the latest revision from bzr.dev::
 
4159
        To merge all new revisions from bzr.dev::
3736
4160
 
3737
4161
            bzr merge ../bzr.dev
3738
4162
 
3785
4209
    ]
3786
4210
 
3787
4211
    def run(self, location=None, revision=None, force=False,
3788
 
            merge_type=None, show_base=False, reprocess=None, remember=False,
 
4212
            merge_type=None, show_base=False, reprocess=None, remember=None,
3789
4213
            uncommitted=False, pull=False,
3790
4214
            directory=None,
3791
4215
            preview=False,
3799
4223
        merger = None
3800
4224
        allow_pending = True
3801
4225
        verified = 'inapplicable'
 
4226
 
3802
4227
        tree = WorkingTree.open_containing(directory)[0]
 
4228
        if tree.branch.revno() == 0:
 
4229
            raise errors.BzrCommandError(gettext('Merging into empty branches not currently supported, '
 
4230
                                         'https://bugs.launchpad.net/bzr/+bug/308562'))
3803
4231
 
3804
4232
        try:
3805
4233
            basis_tree = tree.revision_tree(tree.last_revision())
3825
4253
                mergeable = None
3826
4254
            else:
3827
4255
                if uncommitted:
3828
 
                    raise errors.BzrCommandError('Cannot use --uncommitted'
3829
 
                        ' with bundles or merge directives.')
 
4256
                    raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
 
4257
                        ' with bundles or merge directives.'))
3830
4258
 
3831
4259
                if revision is not None:
3832
 
                    raise errors.BzrCommandError(
3833
 
                        'Cannot use -r with merge directives or bundles')
 
4260
                    raise errors.BzrCommandError(gettext(
 
4261
                        'Cannot use -r with merge directives or bundles'))
3834
4262
                merger, verified = _mod_merge.Merger.from_mergeable(tree,
3835
4263
                   mergeable, None)
3836
4264
 
3837
4265
        if merger is None and uncommitted:
3838
4266
            if revision is not None and len(revision) > 0:
3839
 
                raise errors.BzrCommandError('Cannot use --uncommitted and'
3840
 
                    ' --revision at the same time.')
 
4267
                raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
 
4268
                    ' --revision at the same time.'))
3841
4269
            merger = self.get_merger_from_uncommitted(tree, location, None)
3842
4270
            allow_pending = False
3843
4271
 
3851
4279
        self.sanity_check_merger(merger)
3852
4280
        if (merger.base_rev_id == merger.other_rev_id and
3853
4281
            merger.other_rev_id is not None):
3854
 
            note('Nothing to do.')
 
4282
            # check if location is a nonexistent file (and not a branch) to
 
4283
            # disambiguate the 'Nothing to do'
 
4284
            if merger.interesting_files:
 
4285
                if not merger.other_tree.has_filename(
 
4286
                    merger.interesting_files[0]):
 
4287
                    note(gettext("merger: ") + str(merger))
 
4288
                    raise errors.PathsDoNotExist([location])
 
4289
            note(gettext('Nothing to do.'))
3855
4290
            return 0
3856
 
        if pull:
 
4291
        if pull and not preview:
3857
4292
            if merger.interesting_files is not None:
3858
 
                raise errors.BzrCommandError('Cannot pull individual files')
 
4293
                raise errors.BzrCommandError(gettext('Cannot pull individual files'))
3859
4294
            if (merger.base_rev_id == tree.last_revision()):
3860
4295
                result = tree.pull(merger.other_branch, False,
3861
4296
                                   merger.other_rev_id)
3862
4297
                result.report(self.outf)
3863
4298
                return 0
3864
4299
        if merger.this_basis is None:
3865
 
            raise errors.BzrCommandError(
 
4300
            raise errors.BzrCommandError(gettext(
3866
4301
                "This branch has no commits."
3867
 
                " (perhaps you would prefer 'bzr pull')")
 
4302
                " (perhaps you would prefer 'bzr pull')"))
3868
4303
        if preview:
3869
4304
            return self._do_preview(merger)
3870
4305
        elif interactive:
3921
4356
    def sanity_check_merger(self, merger):
3922
4357
        if (merger.show_base and
3923
4358
            not merger.merge_type is _mod_merge.Merge3Merger):
3924
 
            raise errors.BzrCommandError("Show-base is not supported for this"
3925
 
                                         " merge type. %s" % merger.merge_type)
 
4359
            raise errors.BzrCommandError(gettext("Show-base is not supported for this"
 
4360
                                         " merge type. %s") % merger.merge_type)
3926
4361
        if merger.reprocess is None:
3927
4362
            if merger.show_base:
3928
4363
                merger.reprocess = False
3930
4365
                # Use reprocess if the merger supports it
3931
4366
                merger.reprocess = merger.merge_type.supports_reprocess
3932
4367
        if merger.reprocess and not merger.merge_type.supports_reprocess:
3933
 
            raise errors.BzrCommandError("Conflict reduction is not supported"
3934
 
                                         " for merge type %s." %
 
4368
            raise errors.BzrCommandError(gettext("Conflict reduction is not supported"
 
4369
                                         " for merge type %s.") %
3935
4370
                                         merger.merge_type)
3936
4371
        if merger.reprocess and merger.show_base:
3937
 
            raise errors.BzrCommandError("Cannot do conflict reduction and"
3938
 
                                         " show base.")
 
4372
            raise errors.BzrCommandError(gettext("Cannot do conflict reduction and"
 
4373
                                         " show base."))
3939
4374
 
3940
4375
    def _get_merger_from_branch(self, tree, location, revision, remember,
3941
4376
                                possible_transports, pb):
3968
4403
        if other_revision_id is None:
3969
4404
            other_revision_id = _mod_revision.ensure_null(
3970
4405
                other_branch.last_revision())
3971
 
        # Remember where we merge from
3972
 
        if ((remember or tree.branch.get_submit_branch() is None) and
3973
 
             user_location is not None):
 
4406
        # Remember where we merge from. We need to remember if:
 
4407
        # - user specify a location (and we don't merge from the parent
 
4408
        #   branch)
 
4409
        # - user ask to remember or there is no previous location set to merge
 
4410
        #   from and user didn't ask to *not* remember
 
4411
        if (user_location is not None
 
4412
            and ((remember
 
4413
                  or (remember is None
 
4414
                      and tree.branch.get_submit_branch() is None)))):
3974
4415
            tree.branch.set_submit_branch(other_branch.base)
3975
 
        _merge_tags_if_possible(other_branch, tree.branch)
 
4416
        # Merge tags (but don't set them in the master branch yet, the user
 
4417
        # might revert this merge).  Commit will propagate them.
 
4418
        _merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
3976
4419
        merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3977
4420
            other_revision_id, base_revision_id, other_branch, base_branch)
3978
4421
        if other_path != '':
4037
4480
            stored_location_type = "parent"
4038
4481
        mutter("%s", stored_location)
4039
4482
        if stored_location is None:
4040
 
            raise errors.BzrCommandError("No location specified or remembered")
 
4483
            raise errors.BzrCommandError(gettext("No location specified or remembered"))
4041
4484
        display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4042
 
        note(u"%s remembered %s location %s", verb_string,
4043
 
                stored_location_type, display_url)
 
4485
        note(gettext("{0} remembered {1} location {2}").format(verb_string,
 
4486
                stored_location_type, display_url))
4044
4487
        return stored_location
4045
4488
 
4046
4489
 
4083
4526
        self.add_cleanup(tree.lock_write().unlock)
4084
4527
        parents = tree.get_parent_ids()
4085
4528
        if len(parents) != 2:
4086
 
            raise errors.BzrCommandError("Sorry, remerge only works after normal"
 
4529
            raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4087
4530
                                         " merges.  Not cherrypicking or"
4088
 
                                         " multi-merges.")
 
4531
                                         " multi-merges."))
4089
4532
        repository = tree.branch.repository
4090
4533
        interesting_ids = None
4091
4534
        new_conflicts = []
4146
4589
    last committed revision is used.
4147
4590
 
4148
4591
    To remove only some changes, without reverting to a prior version, use
4149
 
    merge instead.  For example, "merge . --revision -2..-3" will remove the
4150
 
    changes introduced by -2, without affecting the changes introduced by -1.
4151
 
    Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
 
4592
    merge instead.  For example, "merge . -r -2..-3" (don't forget the ".")
 
4593
    will remove the changes introduced by the second last commit (-2), without
 
4594
    affecting the changes introduced by the last commit (-1).  To remove
 
4595
    certain changes on a hunk-by-hunk basis, see the shelve command.
4152
4596
 
4153
4597
    By default, any files that have been manually changed will be backed up
4154
4598
    first.  (Files changed only by merge are not backed up.)  Backup files have
4184
4628
    target branches.
4185
4629
    """
4186
4630
 
4187
 
    _see_also = ['cat', 'export']
 
4631
    _see_also = ['cat', 'export', 'merge', 'shelve']
4188
4632
    takes_options = [
4189
4633
        'revision',
4190
4634
        Option('no-backup', "Do not save backups of reverted files."),
4309
4753
            type=_parse_revision_str,
4310
4754
            help='Filter on local branch revisions (inclusive). '
4311
4755
                'See "help revisionspec" for details.'),
4312
 
        Option('include-merges',
 
4756
        Option('include-merged',
4313
4757
               'Show all revisions in addition to the mainline ones.'),
 
4758
        Option('include-merges', hidden=True,
 
4759
               help='Historical alias for --include-merged.'),
4314
4760
        ]
4315
4761
    encoding_type = 'replace'
4316
4762
 
4319
4765
            theirs_only=False,
4320
4766
            log_format=None, long=False, short=False, line=False,
4321
4767
            show_ids=False, verbose=False, this=False, other=False,
4322
 
            include_merges=False, revision=None, my_revision=None,
4323
 
            directory=u'.'):
 
4768
            include_merged=None, revision=None, my_revision=None,
 
4769
            directory=u'.',
 
4770
            include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4324
4771
        from bzrlib.missing import find_unmerged, iter_log_revisions
4325
4772
        def message(s):
4326
4773
            if not is_quiet():
4327
4774
                self.outf.write(s)
4328
4775
 
 
4776
        if symbol_versioning.deprecated_passed(include_merges):
 
4777
            ui.ui_factory.show_user_warning(
 
4778
                'deprecated_command_option',
 
4779
                deprecated_name='--include-merges',
 
4780
                recommended_name='--include-merged',
 
4781
                deprecated_in_version='2.5',
 
4782
                command=self.invoked_as)
 
4783
            if include_merged is None:
 
4784
                include_merged = include_merges
 
4785
            else:
 
4786
                raise errors.BzrCommandError(gettext(
 
4787
                    '{0} and {1} are mutually exclusive').format(
 
4788
                    '--include-merges', '--include-merged'))
 
4789
        if include_merged is None:
 
4790
            include_merged = False
4329
4791
        if this:
4330
4792
            mine_only = this
4331
4793
        if other:
4346
4808
        if other_branch is None:
4347
4809
            other_branch = parent
4348
4810
            if other_branch is None:
4349
 
                raise errors.BzrCommandError("No peer location known"
4350
 
                                             " or specified.")
 
4811
                raise errors.BzrCommandError(gettext("No peer location known"
 
4812
                                             " or specified."))
4351
4813
            display_url = urlutils.unescape_for_display(parent,
4352
4814
                                                        self.outf.encoding)
4353
 
            message("Using saved parent location: "
4354
 
                    + display_url + "\n")
 
4815
            message(gettext("Using saved parent location: {0}\n").format(
 
4816
                    display_url))
4355
4817
 
4356
4818
        remote_branch = Branch.open(other_branch)
4357
4819
        if remote_branch.base == local_branch.base:
4370
4832
        local_extra, remote_extra = find_unmerged(
4371
4833
            local_branch, remote_branch, restrict,
4372
4834
            backward=not reverse,
4373
 
            include_merges=include_merges,
 
4835
            include_merged=include_merged,
4374
4836
            local_revid_range=local_revid_range,
4375
4837
            remote_revid_range=remote_revid_range)
4376
4838
 
4383
4845
 
4384
4846
        status_code = 0
4385
4847
        if local_extra and not theirs_only:
4386
 
            message("You have %d extra revision(s):\n" %
 
4848
            message(ngettext("You have %d extra revision:\n",
 
4849
                             "You have %d extra revisions:\n", 
 
4850
                             len(local_extra)) %
4387
4851
                len(local_extra))
4388
4852
            for revision in iter_log_revisions(local_extra,
4389
4853
                                local_branch.repository,
4397
4861
        if remote_extra and not mine_only:
4398
4862
            if printed_local is True:
4399
4863
                message("\n\n\n")
4400
 
            message("You are missing %d revision(s):\n" %
 
4864
            message(ngettext("You are missing %d revision:\n",
 
4865
                             "You are missing %d revisions:\n",
 
4866
                             len(remote_extra)) %
4401
4867
                len(remote_extra))
4402
4868
            for revision in iter_log_revisions(remote_extra,
4403
4869
                                remote_branch.repository,
4407
4873
 
4408
4874
        if mine_only and not local_extra:
4409
4875
            # We checked local, and found nothing extra
4410
 
            message('This branch is up to date.\n')
 
4876
            message(gettext('This branch has no new revisions.\n'))
4411
4877
        elif theirs_only and not remote_extra:
4412
4878
            # We checked remote, and found nothing extra
4413
 
            message('Other branch is up to date.\n')
 
4879
            message(gettext('Other branch has no new revisions.\n'))
4414
4880
        elif not (mine_only or theirs_only or local_extra or
4415
4881
                  remote_extra):
4416
4882
            # We checked both branches, and neither one had extra
4417
4883
            # revisions
4418
 
            message("Branches are up to date.\n")
 
4884
            message(gettext("Branches are up to date.\n"))
4419
4885
        self.cleanup_now()
4420
4886
        if not status_code and parent is None and other_branch is not None:
4421
4887
            self.add_cleanup(local_branch.lock_write().unlock)
4451
4917
        ]
4452
4918
 
4453
4919
    def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4454
 
        dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
 
4920
        dir = controldir.ControlDir.open_containing(branch_or_repo)[0]
4455
4921
        try:
4456
4922
            branch = dir.open_branch()
4457
4923
            repository = branch.repository
4483
4949
 
4484
4950
    @display_command
4485
4951
    def run(self, verbose=False):
4486
 
        import bzrlib.plugin
4487
 
        from inspect import getdoc
4488
 
        result = []
4489
 
        for name, plugin in bzrlib.plugin.plugins().items():
4490
 
            version = plugin.__version__
4491
 
            if version == 'unknown':
4492
 
                version = ''
4493
 
            name_ver = '%s %s' % (name, version)
4494
 
            d = getdoc(plugin.module)
4495
 
            if d:
4496
 
                doc = d.split('\n')[0]
4497
 
            else:
4498
 
                doc = '(no description)'
4499
 
            result.append((name_ver, doc, plugin.path()))
4500
 
        for name_ver, doc, path in sorted(result):
4501
 
            self.outf.write("%s\n" % name_ver)
4502
 
            self.outf.write("   %s\n" % doc)
4503
 
            if verbose:
4504
 
                self.outf.write("   %s\n" % path)
4505
 
            self.outf.write("\n")
 
4952
        from bzrlib import plugin
 
4953
        # Don't give writelines a generator as some codecs don't like that
 
4954
        self.outf.writelines(
 
4955
            list(plugin.describe_plugins(show_paths=verbose)))
4506
4956
 
4507
4957
 
4508
4958
class cmd_testament(Command):
4561
5011
    @display_command
4562
5012
    def run(self, filename, all=False, long=False, revision=None,
4563
5013
            show_ids=False, directory=None):
4564
 
        from bzrlib.annotate import annotate_file, annotate_file_tree
 
5014
        from bzrlib.annotate import (
 
5015
            annotate_file_tree,
 
5016
            )
4565
5017
        wt, branch, relpath = \
4566
5018
            _open_directory_or_containing_tree_or_branch(filename, directory)
4567
5019
        if wt is not None:
4570
5022
            self.add_cleanup(branch.lock_read().unlock)
4571
5023
        tree = _get_one_revision_tree('annotate', revision, branch=branch)
4572
5024
        self.add_cleanup(tree.lock_read().unlock)
4573
 
        if wt is not None:
 
5025
        if wt is not None and revision is None:
4574
5026
            file_id = wt.path2id(relpath)
4575
5027
        else:
4576
5028
            file_id = tree.path2id(relpath)
4577
5029
        if file_id is None:
4578
5030
            raise errors.NotVersionedError(filename)
4579
 
        file_version = tree.inventory[file_id].revision
4580
5031
        if wt is not None and revision is None:
4581
5032
            # If there is a tree and we're not annotating historical
4582
5033
            # versions, annotate the working tree's content.
4583
5034
            annotate_file_tree(wt, file_id, self.outf, long, all,
4584
5035
                show_ids=show_ids)
4585
5036
        else:
4586
 
            annotate_file(branch, file_version, file_id, long, all, self.outf,
4587
 
                          show_ids=show_ids)
 
5037
            annotate_file_tree(tree, file_id, self.outf, long, all,
 
5038
                show_ids=show_ids, branch=branch)
4588
5039
 
4589
5040
 
4590
5041
class cmd_re_sign(Command):
4597
5048
 
4598
5049
    def run(self, revision_id_list=None, revision=None, directory=u'.'):
4599
5050
        if revision_id_list is not None and revision is not None:
4600
 
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
 
5051
            raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
4601
5052
        if revision_id_list is None and revision is None:
4602
 
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
 
5053
            raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
4603
5054
        b = WorkingTree.open_containing(directory)[0].branch
4604
5055
        self.add_cleanup(b.lock_write().unlock)
4605
5056
        return self._run(b, revision_id_list, revision)
4606
5057
 
4607
5058
    def _run(self, b, revision_id_list, revision):
4608
5059
        import bzrlib.gpg as gpg
4609
 
        gpg_strategy = gpg.GPGStrategy(b.get_config())
 
5060
        gpg_strategy = gpg.GPGStrategy(b.get_config_stack())
4610
5061
        if revision_id_list is not None:
4611
5062
            b.repository.start_write_group()
4612
5063
            try:
4637
5088
                if to_revid is None:
4638
5089
                    to_revno = b.revno()
4639
5090
                if from_revno is None or to_revno is None:
4640
 
                    raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
 
5091
                    raise errors.BzrCommandError(gettext('Cannot sign a range of non-revision-history revisions'))
4641
5092
                b.repository.start_write_group()
4642
5093
                try:
4643
5094
                    for revno in range(from_revno, to_revno + 1):
4649
5100
                else:
4650
5101
                    b.repository.commit_write_group()
4651
5102
            else:
4652
 
                raise errors.BzrCommandError('Please supply either one revision, or a range.')
 
5103
                raise errors.BzrCommandError(gettext('Please supply either one revision, or a range.'))
4653
5104
 
4654
5105
 
4655
5106
class cmd_bind(Command):
4674
5125
            try:
4675
5126
                location = b.get_old_bound_location()
4676
5127
            except errors.UpgradeRequired:
4677
 
                raise errors.BzrCommandError('No location supplied.  '
4678
 
                    'This format does not remember old locations.')
 
5128
                raise errors.BzrCommandError(gettext('No location supplied.  '
 
5129
                    'This format does not remember old locations.'))
4679
5130
            else:
4680
5131
                if location is None:
4681
5132
                    if b.get_bound_location() is not None:
4682
 
                        raise errors.BzrCommandError('Branch is already bound')
 
5133
                        raise errors.BzrCommandError(gettext('Branch is already bound'))
4683
5134
                    else:
4684
 
                        raise errors.BzrCommandError('No location supplied '
4685
 
                            'and no previous location known')
 
5135
                        raise errors.BzrCommandError(gettext('No location supplied '
 
5136
                            'and no previous location known'))
4686
5137
        b_other = Branch.open(location)
4687
5138
        try:
4688
5139
            b.bind(b_other)
4689
5140
        except errors.DivergedBranches:
4690
 
            raise errors.BzrCommandError('These branches have diverged.'
4691
 
                                         ' Try merging, and then bind again.')
 
5141
            raise errors.BzrCommandError(gettext('These branches have diverged.'
 
5142
                                         ' Try merging, and then bind again.'))
4692
5143
        if b.get_config().has_explicit_nickname():
4693
5144
            b.nick = b_other.nick
4694
5145
 
4707
5158
    def run(self, directory=u'.'):
4708
5159
        b, relpath = Branch.open_containing(directory)
4709
5160
        if not b.unbind():
4710
 
            raise errors.BzrCommandError('Local branch is not bound')
 
5161
            raise errors.BzrCommandError(gettext('Local branch is not bound'))
4711
5162
 
4712
5163
 
4713
5164
class cmd_uncommit(Command):
4734
5185
    takes_options = ['verbose', 'revision',
4735
5186
                    Option('dry-run', help='Don\'t actually make changes.'),
4736
5187
                    Option('force', help='Say yes to all questions.'),
 
5188
                    Option('keep-tags',
 
5189
                           help='Keep tags that point to removed revisions.'),
4737
5190
                    Option('local',
4738
5191
                           help="Only remove the commits from the local branch"
4739
5192
                                " when in a checkout."
4743
5196
    aliases = []
4744
5197
    encoding_type = 'replace'
4745
5198
 
4746
 
    def run(self, location=None,
4747
 
            dry_run=False, verbose=False,
4748
 
            revision=None, force=False, local=False):
 
5199
    def run(self, location=None, dry_run=False, verbose=False,
 
5200
            revision=None, force=False, local=False, keep_tags=False):
4749
5201
        if location is None:
4750
5202
            location = u'.'
4751
 
        control, relpath = bzrdir.BzrDir.open_containing(location)
 
5203
        control, relpath = controldir.ControlDir.open_containing(location)
4752
5204
        try:
4753
5205
            tree = control.open_workingtree()
4754
5206
            b = tree.branch
4760
5212
            self.add_cleanup(tree.lock_write().unlock)
4761
5213
        else:
4762
5214
            self.add_cleanup(b.lock_write().unlock)
4763
 
        return self._run(b, tree, dry_run, verbose, revision, force, local=local)
 
5215
        return self._run(b, tree, dry_run, verbose, revision, force,
 
5216
                         local, keep_tags)
4764
5217
 
4765
 
    def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
 
5218
    def _run(self, b, tree, dry_run, verbose, revision, force, local,
 
5219
             keep_tags):
4766
5220
        from bzrlib.log import log_formatter, show_log
4767
5221
        from bzrlib.uncommit import uncommit
4768
5222
 
4783
5237
                rev_id = b.get_rev_id(revno)
4784
5238
 
4785
5239
        if rev_id is None or _mod_revision.is_null(rev_id):
4786
 
            self.outf.write('No revisions to uncommit.\n')
 
5240
            self.outf.write(gettext('No revisions to uncommit.\n'))
4787
5241
            return 1
4788
5242
 
4789
5243
        lf = log_formatter('short',
4798
5252
                 end_revision=last_revno)
4799
5253
 
4800
5254
        if dry_run:
4801
 
            self.outf.write('Dry-run, pretending to remove'
4802
 
                            ' the above revisions.\n')
 
5255
            self.outf.write(gettext('Dry-run, pretending to remove'
 
5256
                            ' the above revisions.\n'))
4803
5257
        else:
4804
 
            self.outf.write('The above revision(s) will be removed.\n')
 
5258
            self.outf.write(gettext('The above revision(s) will be removed.\n'))
4805
5259
 
4806
5260
        if not force:
4807
5261
            if not ui.ui_factory.confirm_action(
4808
 
                    'Uncommit these revisions',
 
5262
                    gettext(u'Uncommit these revisions'),
4809
5263
                    'bzrlib.builtins.uncommit',
4810
5264
                    {}):
4811
 
                self.outf.write('Canceled\n')
 
5265
                self.outf.write(gettext('Canceled\n'))
4812
5266
                return 0
4813
5267
 
4814
5268
        mutter('Uncommitting from {%s} to {%s}',
4815
5269
               last_rev_id, rev_id)
4816
5270
        uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4817
 
                 revno=revno, local=local)
4818
 
        self.outf.write('You can restore the old tip by running:\n'
4819
 
             '  bzr pull . -r revid:%s\n' % last_rev_id)
 
5271
                 revno=revno, local=local, keep_tags=keep_tags)
 
5272
        self.outf.write(gettext('You can restore the old tip by running:\n'
 
5273
             '  bzr pull . -r revid:%s\n') % last_rev_id)
4820
5274
 
4821
5275
 
4822
5276
class cmd_break_lock(Command):
4841
5295
    takes_options = [
4842
5296
        Option('config',
4843
5297
               help='LOCATION is the directory where the config lock is.'),
 
5298
        Option('force',
 
5299
            help='Do not ask for confirmation before breaking the lock.'),
4844
5300
        ]
4845
5301
 
4846
 
    def run(self, location=None, config=False):
 
5302
    def run(self, location=None, config=False, force=False):
4847
5303
        if location is None:
4848
5304
            location = u'.'
 
5305
        if force:
 
5306
            ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
 
5307
                None,
 
5308
                {'bzrlib.lockdir.break': True})
4849
5309
        if config:
4850
5310
            conf = _mod_config.LockableConfig(file_name=location)
4851
5311
            conf.break_lock()
4852
5312
        else:
4853
 
            control, relpath = bzrdir.BzrDir.open_containing(location)
 
5313
            control, relpath = controldir.ControlDir.open_containing(location)
4854
5314
            try:
4855
5315
                control.break_lock()
4856
5316
            except NotImplementedError:
4900
5360
                    'option leads to global uncontrolled write access to your '
4901
5361
                    'file system.'
4902
5362
                ),
 
5363
        Option('client-timeout', type=float,
 
5364
               help='Override the default idle client timeout (5min).'),
4903
5365
        ]
4904
5366
 
4905
5367
    def get_host_and_port(self, port):
4922
5384
        return host, port
4923
5385
 
4924
5386
    def run(self, port=None, inet=False, directory=None, allow_writes=False,
4925
 
            protocol=None):
 
5387
            protocol=None, client_timeout=None):
4926
5388
        from bzrlib import transport
4927
5389
        if directory is None:
4928
5390
            directory = os.getcwd()
4929
5391
        if protocol is None:
4930
5392
            protocol = transport.transport_server_registry.get()
4931
5393
        host, port = self.get_host_and_port(port)
4932
 
        url = urlutils.local_path_to_url(directory)
 
5394
        url = transport.location_to_url(directory)
4933
5395
        if not allow_writes:
4934
5396
            url = 'readonly+' + url
4935
 
        t = transport.get_transport(url)
4936
 
        protocol(t, host, port, inet)
 
5397
        t = transport.get_transport_from_url(url)
 
5398
        try:
 
5399
            protocol(t, host, port, inet, client_timeout)
 
5400
        except TypeError, e:
 
5401
            # We use symbol_versioning.deprecated_in just so that people
 
5402
            # grepping can find it here.
 
5403
            # symbol_versioning.deprecated_in((2, 5, 0))
 
5404
            symbol_versioning.warn(
 
5405
                'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
 
5406
                'Most likely it needs to be updated to support a'
 
5407
                ' "timeout" parameter (added in bzr 2.5.0)'
 
5408
                % (e, protocol.__module__, protocol),
 
5409
                DeprecationWarning)
 
5410
            protocol(t, host, port, inet)
4937
5411
 
4938
5412
 
4939
5413
class cmd_join(Command):
4962
5436
        containing_tree = WorkingTree.open_containing(parent_dir)[0]
4963
5437
        repo = containing_tree.branch.repository
4964
5438
        if not repo.supports_rich_root():
4965
 
            raise errors.BzrCommandError(
 
5439
            raise errors.BzrCommandError(gettext(
4966
5440
                "Can't join trees because %s doesn't support rich root data.\n"
4967
 
                "You can use bzr upgrade on the repository."
 
5441
                "You can use bzr upgrade on the repository.")
4968
5442
                % (repo,))
4969
5443
        if reference:
4970
5444
            try:
4972
5446
            except errors.BadReferenceTarget, e:
4973
5447
                # XXX: Would be better to just raise a nicely printable
4974
5448
                # exception from the real origin.  Also below.  mbp 20070306
4975
 
                raise errors.BzrCommandError("Cannot join %s.  %s" %
4976
 
                                             (tree, e.reason))
 
5449
                raise errors.BzrCommandError(
 
5450
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
4977
5451
        else:
4978
5452
            try:
4979
5453
                containing_tree.subsume(sub_tree)
4980
5454
            except errors.BadSubsumeSource, e:
4981
 
                raise errors.BzrCommandError("Cannot join %s.  %s" %
4982
 
                                             (tree, e.reason))
 
5455
                raise errors.BzrCommandError(
 
5456
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
4983
5457
 
4984
5458
 
4985
5459
class cmd_split(Command):
5069
5543
        if submit_branch is None:
5070
5544
            submit_branch = branch.get_parent()
5071
5545
        if submit_branch is None:
5072
 
            raise errors.BzrCommandError('No submit branch specified or known')
 
5546
            raise errors.BzrCommandError(gettext('No submit branch specified or known'))
5073
5547
 
5074
5548
        stored_public_branch = branch.get_public_branch()
5075
5549
        if public_branch is None:
5077
5551
        elif stored_public_branch is None:
5078
5552
            branch.set_public_branch(public_branch)
5079
5553
        if not include_bundle and public_branch is None:
5080
 
            raise errors.BzrCommandError('No public branch specified or'
5081
 
                                         ' known')
 
5554
            raise errors.BzrCommandError(gettext('No public branch specified or'
 
5555
                                         ' known'))
5082
5556
        base_revision_id = None
5083
5557
        if revision is not None:
5084
5558
            if len(revision) > 2:
5085
 
                raise errors.BzrCommandError('bzr merge-directive takes '
5086
 
                    'at most two one revision identifiers')
 
5559
                raise errors.BzrCommandError(gettext('bzr merge-directive takes '
 
5560
                    'at most two one revision identifiers'))
5087
5561
            revision_id = revision[-1].as_revision_id(branch)
5088
5562
            if len(revision) == 2:
5089
5563
                base_revision_id = revision[0].as_revision_id(branch)
5091
5565
            revision_id = branch.last_revision()
5092
5566
        revision_id = ensure_null(revision_id)
5093
5567
        if revision_id == NULL_REVISION:
5094
 
            raise errors.BzrCommandError('No revisions to bundle.')
 
5568
            raise errors.BzrCommandError(gettext('No revisions to bundle.'))
5095
5569
        directive = merge_directive.MergeDirective2.from_objects(
5096
5570
            branch.repository, revision_id, time.time(),
5097
5571
            osutils.local_time_offset(), submit_branch,
5141
5615
    source branch defaults to that containing the working directory, but can
5142
5616
    be changed using --from.
5143
5617
 
 
5618
    Both the submit branch and the public branch follow the usual behavior with
 
5619
    respect to --remember: If there is no default location set, the first send
 
5620
    will set it (use --no-remember to avoid setting it). After that, you can
 
5621
    omit the location to use the default.  To change the default, use
 
5622
    --remember. The value will only be saved if the location can be accessed.
 
5623
 
5144
5624
    In order to calculate those changes, bzr must analyse the submit branch.
5145
5625
    Therefore it is most efficient for the submit branch to be a local mirror.
5146
5626
    If a public location is known for the submit_branch, that location is used
5215
5695
        ]
5216
5696
 
5217
5697
    def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5218
 
            no_patch=False, revision=None, remember=False, output=None,
 
5698
            no_patch=False, revision=None, remember=None, output=None,
5219
5699
            format=None, mail_to=None, message=None, body=None,
5220
5700
            strict=None, **kwargs):
5221
5701
        from bzrlib.send import send
5345
5825
        self.add_cleanup(branch.lock_write().unlock)
5346
5826
        if delete:
5347
5827
            if tag_name is None:
5348
 
                raise errors.BzrCommandError("No tag specified to delete.")
 
5828
                raise errors.BzrCommandError(gettext("No tag specified to delete."))
5349
5829
            branch.tags.delete_tag(tag_name)
5350
 
            self.outf.write('Deleted tag %s.\n' % tag_name)
 
5830
            note(gettext('Deleted tag %s.') % tag_name)
5351
5831
        else:
5352
5832
            if revision:
5353
5833
                if len(revision) != 1:
5354
 
                    raise errors.BzrCommandError(
 
5834
                    raise errors.BzrCommandError(gettext(
5355
5835
                        "Tags can only be placed on a single revision, "
5356
 
                        "not on a range")
 
5836
                        "not on a range"))
5357
5837
                revision_id = revision[0].as_revision_id(branch)
5358
5838
            else:
5359
5839
                revision_id = branch.last_revision()
5360
5840
            if tag_name is None:
5361
5841
                tag_name = branch.automatic_tag_name(revision_id)
5362
5842
                if tag_name is None:
5363
 
                    raise errors.BzrCommandError(
5364
 
                        "Please specify a tag name.")
5365
 
            if (not force) and branch.tags.has_tag(tag_name):
 
5843
                    raise errors.BzrCommandError(gettext(
 
5844
                        "Please specify a tag name."))
 
5845
            try:
 
5846
                existing_target = branch.tags.lookup_tag(tag_name)
 
5847
            except errors.NoSuchTag:
 
5848
                existing_target = None
 
5849
            if not force and existing_target not in (None, revision_id):
5366
5850
                raise errors.TagAlreadyExists(tag_name)
5367
 
            branch.tags.set_tag(tag_name, revision_id)
5368
 
            self.outf.write('Created tag %s.\n' % tag_name)
 
5851
            if existing_target == revision_id:
 
5852
                note(gettext('Tag %s already exists for that revision.') % tag_name)
 
5853
            else:
 
5854
                branch.tags.set_tag(tag_name, revision_id)
 
5855
                if existing_target is None:
 
5856
                    note(gettext('Created tag %s.') % tag_name)
 
5857
                else:
 
5858
                    note(gettext('Updated tag %s.') % tag_name)
5369
5859
 
5370
5860
 
5371
5861
class cmd_tags(Command):
5378
5868
    takes_options = [
5379
5869
        custom_help('directory',
5380
5870
            help='Branch whose tags should be displayed.'),
5381
 
        RegistryOption.from_kwargs('sort',
 
5871
        RegistryOption('sort',
5382
5872
            'Sort tags by different criteria.', title='Sorting',
5383
 
            alpha='Sort tags lexicographically (default).',
5384
 
            time='Sort tags chronologically.',
 
5873
            lazy_registry=('bzrlib.tag', 'tag_sort_methods')
5385
5874
            ),
5386
5875
        'show-ids',
5387
5876
        'revision',
5388
5877
    ]
5389
5878
 
5390
5879
    @display_command
5391
 
    def run(self,
5392
 
            directory='.',
5393
 
            sort='alpha',
5394
 
            show_ids=False,
5395
 
            revision=None,
5396
 
            ):
 
5880
    def run(self, directory='.', sort=None, show_ids=False, revision=None):
 
5881
        from bzrlib.tag import tag_sort_methods
5397
5882
        branch, relpath = Branch.open_containing(directory)
5398
5883
 
5399
5884
        tags = branch.tags.get_tag_dict().items()
5402
5887
 
5403
5888
        self.add_cleanup(branch.lock_read().unlock)
5404
5889
        if revision:
5405
 
            graph = branch.repository.get_graph()
5406
 
            rev1, rev2 = _get_revision_range(revision, branch, self.name())
5407
 
            revid1, revid2 = rev1.rev_id, rev2.rev_id
5408
 
            # only show revisions between revid1 and revid2 (inclusive)
5409
 
            tags = [(tag, revid) for tag, revid in tags if
5410
 
                graph.is_between(revid, revid1, revid2)]
5411
 
        if sort == 'alpha':
5412
 
            tags.sort()
5413
 
        elif sort == 'time':
5414
 
            timestamps = {}
5415
 
            for tag, revid in tags:
5416
 
                try:
5417
 
                    revobj = branch.repository.get_revision(revid)
5418
 
                except errors.NoSuchRevision:
5419
 
                    timestamp = sys.maxint # place them at the end
5420
 
                else:
5421
 
                    timestamp = revobj.timestamp
5422
 
                timestamps[revid] = timestamp
5423
 
            tags.sort(key=lambda x: timestamps[x[1]])
 
5890
            # Restrict to the specified range
 
5891
            tags = self._tags_for_range(branch, revision)
 
5892
        if sort is None:
 
5893
            sort = tag_sort_methods.get()
 
5894
        sort(branch, tags)
5424
5895
        if not show_ids:
5425
5896
            # [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5426
5897
            for index, (tag, revid) in enumerate(tags):
5428
5899
                    revno = branch.revision_id_to_dotted_revno(revid)
5429
5900
                    if isinstance(revno, tuple):
5430
5901
                        revno = '.'.join(map(str, revno))
5431
 
                except errors.NoSuchRevision:
 
5902
                except (errors.NoSuchRevision,
 
5903
                        errors.GhostRevisionsHaveNoRevno,
 
5904
                        errors.UnsupportedOperation):
5432
5905
                    # Bad tag data/merges can lead to tagged revisions
5433
5906
                    # which are not in this branch. Fail gracefully ...
5434
5907
                    revno = '?'
5437
5910
        for tag, revspec in tags:
5438
5911
            self.outf.write('%-20s %s\n' % (tag, revspec))
5439
5912
 
 
5913
    def _tags_for_range(self, branch, revision):
 
5914
        range_valid = True
 
5915
        rev1, rev2 = _get_revision_range(revision, branch, self.name())
 
5916
        revid1, revid2 = rev1.rev_id, rev2.rev_id
 
5917
        # _get_revision_range will always set revid2 if it's not specified.
 
5918
        # If revid1 is None, it means we want to start from the branch
 
5919
        # origin which is always a valid ancestor. If revid1 == revid2, the
 
5920
        # ancestry check is useless.
 
5921
        if revid1 and revid1 != revid2:
 
5922
            # FIXME: We really want to use the same graph than
 
5923
            # branch.iter_merge_sorted_revisions below, but this is not
 
5924
            # easily available -- vila 2011-09-23
 
5925
            if branch.repository.get_graph().is_ancestor(revid2, revid1):
 
5926
                # We don't want to output anything in this case...
 
5927
                return []
 
5928
        # only show revisions between revid1 and revid2 (inclusive)
 
5929
        tagged_revids = branch.tags.get_reverse_tag_dict()
 
5930
        found = []
 
5931
        for r in branch.iter_merge_sorted_revisions(
 
5932
            start_revision_id=revid2, stop_revision_id=revid1,
 
5933
            stop_rule='include'):
 
5934
            revid_tags = tagged_revids.get(r[0], None)
 
5935
            if revid_tags:
 
5936
                found.extend([(tag, r[0]) for tag in revid_tags])
 
5937
        return found
 
5938
 
5440
5939
 
5441
5940
class cmd_reconfigure(Command):
5442
5941
    __doc__ = """Reconfigure the type of a bzr directory.
5456
5955
    takes_args = ['location?']
5457
5956
    takes_options = [
5458
5957
        RegistryOption.from_kwargs(
5459
 
            'target_type',
5460
 
            title='Target type',
5461
 
            help='The type to reconfigure the directory to.',
 
5958
            'tree_type',
 
5959
            title='Tree type',
 
5960
            help='The relation between branch and tree.',
5462
5961
            value_switches=True, enum_switch=False,
5463
5962
            branch='Reconfigure to be an unbound branch with no working tree.',
5464
5963
            tree='Reconfigure to be an unbound branch with a working tree.',
5465
5964
            checkout='Reconfigure to be a bound branch with a working tree.',
5466
5965
            lightweight_checkout='Reconfigure to be a lightweight'
5467
5966
                ' checkout (with no local history).',
 
5967
            ),
 
5968
        RegistryOption.from_kwargs(
 
5969
            'repository_type',
 
5970
            title='Repository type',
 
5971
            help='Location fo the repository.',
 
5972
            value_switches=True, enum_switch=False,
5468
5973
            standalone='Reconfigure to be a standalone branch '
5469
5974
                '(i.e. stop using shared repository).',
5470
5975
            use_shared='Reconfigure to use a shared repository.',
 
5976
            ),
 
5977
        RegistryOption.from_kwargs(
 
5978
            'repository_trees',
 
5979
            title='Trees in Repository',
 
5980
            help='Whether new branches in the repository have trees.',
 
5981
            value_switches=True, enum_switch=False,
5471
5982
            with_trees='Reconfigure repository to create '
5472
5983
                'working trees on branches by default.',
5473
5984
            with_no_trees='Reconfigure repository to not create '
5487
5998
            ),
5488
5999
        ]
5489
6000
 
5490
 
    def run(self, location=None, target_type=None, bind_to=None, force=False,
5491
 
            stacked_on=None,
5492
 
            unstacked=None):
5493
 
        directory = bzrdir.BzrDir.open(location)
 
6001
    def run(self, location=None, bind_to=None, force=False,
 
6002
            tree_type=None, repository_type=None, repository_trees=None,
 
6003
            stacked_on=None, unstacked=None):
 
6004
        directory = controldir.ControlDir.open(location)
5494
6005
        if stacked_on and unstacked:
5495
 
            raise BzrCommandError("Can't use both --stacked-on and --unstacked")
 
6006
            raise errors.BzrCommandError(gettext("Can't use both --stacked-on and --unstacked"))
5496
6007
        elif stacked_on is not None:
5497
6008
            reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5498
6009
        elif unstacked:
5500
6011
        # At the moment you can use --stacked-on and a different
5501
6012
        # reconfiguration shape at the same time; there seems no good reason
5502
6013
        # to ban it.
5503
 
        if target_type is None:
 
6014
        if (tree_type is None and
 
6015
            repository_type is None and
 
6016
            repository_trees is None):
5504
6017
            if stacked_on or unstacked:
5505
6018
                return
5506
6019
            else:
5507
 
                raise errors.BzrCommandError('No target configuration '
5508
 
                    'specified')
5509
 
        elif target_type == 'branch':
 
6020
                raise errors.BzrCommandError(gettext('No target configuration '
 
6021
                    'specified'))
 
6022
        reconfiguration = None
 
6023
        if tree_type == 'branch':
5510
6024
            reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5511
 
        elif target_type == 'tree':
 
6025
        elif tree_type == 'tree':
5512
6026
            reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5513
 
        elif target_type == 'checkout':
 
6027
        elif tree_type == 'checkout':
5514
6028
            reconfiguration = reconfigure.Reconfigure.to_checkout(
5515
6029
                directory, bind_to)
5516
 
        elif target_type == 'lightweight-checkout':
 
6030
        elif tree_type == 'lightweight-checkout':
5517
6031
            reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5518
6032
                directory, bind_to)
5519
 
        elif target_type == 'use-shared':
 
6033
        if reconfiguration:
 
6034
            reconfiguration.apply(force)
 
6035
            reconfiguration = None
 
6036
        if repository_type == 'use-shared':
5520
6037
            reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5521
 
        elif target_type == 'standalone':
 
6038
        elif repository_type == 'standalone':
5522
6039
            reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5523
 
        elif target_type == 'with-trees':
 
6040
        if reconfiguration:
 
6041
            reconfiguration.apply(force)
 
6042
            reconfiguration = None
 
6043
        if repository_trees == 'with-trees':
5524
6044
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5525
6045
                directory, True)
5526
 
        elif target_type == 'with-no-trees':
 
6046
        elif repository_trees == 'with-no-trees':
5527
6047
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5528
6048
                directory, False)
5529
 
        reconfiguration.apply(force)
 
6049
        if reconfiguration:
 
6050
            reconfiguration.apply(force)
 
6051
            reconfiguration = None
5530
6052
 
5531
6053
 
5532
6054
class cmd_switch(Command):
5567
6089
        from bzrlib import switch
5568
6090
        tree_location = directory
5569
6091
        revision = _get_one_revision('switch', revision)
5570
 
        control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
 
6092
        control_dir = controldir.ControlDir.open_containing(tree_location)[0]
5571
6093
        if to_location is None:
5572
6094
            if revision is None:
5573
 
                raise errors.BzrCommandError('You must supply either a'
5574
 
                                             ' revision or a location')
 
6095
                raise errors.BzrCommandError(gettext('You must supply either a'
 
6096
                                             ' revision or a location'))
5575
6097
            to_location = tree_location
5576
6098
        try:
5577
6099
            branch = control_dir.open_branch()
5581
6103
            had_explicit_nick = False
5582
6104
        if create_branch:
5583
6105
            if branch is None:
5584
 
                raise errors.BzrCommandError('cannot create branch without'
5585
 
                                             ' source branch')
 
6106
                raise errors.BzrCommandError(gettext('cannot create branch without'
 
6107
                                             ' source branch'))
5586
6108
            to_location = directory_service.directories.dereference(
5587
6109
                              to_location)
5588
6110
            if '/' not in to_location and '\\' not in to_location:
5589
6111
                # This path is meant to be relative to the existing branch
5590
6112
                this_url = self._get_branch_location(control_dir)
5591
 
                to_location = urlutils.join(this_url, '..', to_location)
 
6113
                # Perhaps the target control dir supports colocated branches?
 
6114
                try:
 
6115
                    root = controldir.ControlDir.open(this_url,
 
6116
                        possible_transports=[control_dir.user_transport])
 
6117
                except errors.NotBranchError:
 
6118
                    colocated = False
 
6119
                else:
 
6120
                    colocated = root._format.colocated_branches
 
6121
                if colocated:
 
6122
                    to_location = urlutils.join_segment_parameters(this_url,
 
6123
                        {"branch": urlutils.escape(to_location)})
 
6124
                else:
 
6125
                    to_location = urlutils.join(
 
6126
                        this_url, '..', urlutils.escape(to_location))
5592
6127
            to_branch = branch.bzrdir.sprout(to_location,
5593
6128
                                 possible_transports=[branch.bzrdir.root_transport],
5594
6129
                                 source_branch=branch).open_branch()
5595
6130
        else:
 
6131
            # Perhaps it's a colocated branch?
5596
6132
            try:
5597
 
                to_branch = Branch.open(to_location)
5598
 
            except errors.NotBranchError:
5599
 
                this_url = self._get_branch_location(control_dir)
5600
 
                to_branch = Branch.open(
5601
 
                    urlutils.join(this_url, '..', to_location))
 
6133
                to_branch = control_dir.open_branch(to_location)
 
6134
            except (errors.NotBranchError, errors.NoColocatedBranchSupport):
 
6135
                try:
 
6136
                    to_branch = Branch.open(to_location)
 
6137
                except errors.NotBranchError:
 
6138
                    this_url = self._get_branch_location(control_dir)
 
6139
                    to_branch = Branch.open(
 
6140
                        urlutils.join(
 
6141
                            this_url, '..', urlutils.escape(to_location)))
5602
6142
        if revision is not None:
5603
6143
            revision = revision.as_revision_id(to_branch)
5604
6144
        switch.switch(control_dir, to_branch, force, revision_id=revision)
5605
6145
        if had_explicit_nick:
5606
6146
            branch = control_dir.open_branch() #get the new branch!
5607
6147
            branch.nick = to_branch.nick
5608
 
        note('Switched to branch: %s',
 
6148
        note(gettext('Switched to branch: %s'),
5609
6149
            urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5610
6150
 
5611
6151
    def _get_branch_location(self, control_dir):
5720
6260
            name = current_view
5721
6261
        if delete:
5722
6262
            if file_list:
5723
 
                raise errors.BzrCommandError(
5724
 
                    "Both --delete and a file list specified")
 
6263
                raise errors.BzrCommandError(gettext(
 
6264
                    "Both --delete and a file list specified"))
5725
6265
            elif switch:
5726
 
                raise errors.BzrCommandError(
5727
 
                    "Both --delete and --switch specified")
 
6266
                raise errors.BzrCommandError(gettext(
 
6267
                    "Both --delete and --switch specified"))
5728
6268
            elif all:
5729
6269
                tree.views.set_view_info(None, {})
5730
 
                self.outf.write("Deleted all views.\n")
 
6270
                self.outf.write(gettext("Deleted all views.\n"))
5731
6271
            elif name is None:
5732
 
                raise errors.BzrCommandError("No current view to delete")
 
6272
                raise errors.BzrCommandError(gettext("No current view to delete"))
5733
6273
            else:
5734
6274
                tree.views.delete_view(name)
5735
 
                self.outf.write("Deleted '%s' view.\n" % name)
 
6275
                self.outf.write(gettext("Deleted '%s' view.\n") % name)
5736
6276
        elif switch:
5737
6277
            if file_list:
5738
 
                raise errors.BzrCommandError(
5739
 
                    "Both --switch and a file list specified")
 
6278
                raise errors.BzrCommandError(gettext(
 
6279
                    "Both --switch and a file list specified"))
5740
6280
            elif all:
5741
 
                raise errors.BzrCommandError(
5742
 
                    "Both --switch and --all specified")
 
6281
                raise errors.BzrCommandError(gettext(
 
6282
                    "Both --switch and --all specified"))
5743
6283
            elif switch == 'off':
5744
6284
                if current_view is None:
5745
 
                    raise errors.BzrCommandError("No current view to disable")
 
6285
                    raise errors.BzrCommandError(gettext("No current view to disable"))
5746
6286
                tree.views.set_view_info(None, view_dict)
5747
 
                self.outf.write("Disabled '%s' view.\n" % (current_view))
 
6287
                self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
5748
6288
            else:
5749
6289
                tree.views.set_view_info(switch, view_dict)
5750
6290
                view_str = views.view_display_str(tree.views.lookup_view())
5751
 
                self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
 
6291
                self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
5752
6292
        elif all:
5753
6293
            if view_dict:
5754
 
                self.outf.write('Views defined:\n')
 
6294
                self.outf.write(gettext('Views defined:\n'))
5755
6295
                for view in sorted(view_dict):
5756
6296
                    if view == current_view:
5757
6297
                        active = "=>"
5760
6300
                    view_str = views.view_display_str(view_dict[view])
5761
6301
                    self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5762
6302
            else:
5763
 
                self.outf.write('No views defined.\n')
 
6303
                self.outf.write(gettext('No views defined.\n'))
5764
6304
        elif file_list:
5765
6305
            if name is None:
5766
6306
                # No name given and no current view set
5767
6307
                name = 'my'
5768
6308
            elif name == 'off':
5769
 
                raise errors.BzrCommandError(
5770
 
                    "Cannot change the 'off' pseudo view")
 
6309
                raise errors.BzrCommandError(gettext(
 
6310
                    "Cannot change the 'off' pseudo view"))
5771
6311
            tree.views.set_view(name, sorted(file_list))
5772
6312
            view_str = views.view_display_str(tree.views.lookup_view())
5773
 
            self.outf.write("Using '%s' view: %s\n" % (name, view_str))
 
6313
            self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
5774
6314
        else:
5775
6315
            # list the files
5776
6316
            if name is None:
5777
6317
                # No name given and no current view set
5778
 
                self.outf.write('No current view.\n')
 
6318
                self.outf.write(gettext('No current view.\n'))
5779
6319
            else:
5780
6320
                view_str = views.view_display_str(tree.views.lookup_view(name))
5781
 
                self.outf.write("'%s' view is: %s\n" % (name, view_str))
 
6321
                self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
5782
6322
 
5783
6323
 
5784
6324
class cmd_hooks(Command):
5798
6338
                        self.outf.write("    %s\n" %
5799
6339
                                        (some_hooks.get_hook_name(hook),))
5800
6340
                else:
5801
 
                    self.outf.write("    <no hooks installed>\n")
 
6341
                    self.outf.write(gettext("    <no hooks installed>\n"))
5802
6342
 
5803
6343
 
5804
6344
class cmd_remove_branch(Command):
5824
6364
            location = "."
5825
6365
        branch = Branch.open_containing(location)[0]
5826
6366
        branch.bzrdir.destroy_branch()
5827
 
        
 
6367
 
5828
6368
 
5829
6369
class cmd_shelve(Command):
5830
6370
    __doc__ = """Temporarily set aside some changes from the current tree.
5849
6389
 
5850
6390
    You can put multiple items on the shelf, and by default, 'unshelve' will
5851
6391
    restore the most recently shelved changes.
 
6392
 
 
6393
    For complicated changes, it is possible to edit the changes in a separate
 
6394
    editor program to decide what the file remaining in the working copy
 
6395
    should look like.  To do this, add the configuration option
 
6396
 
 
6397
        change_editor = PROGRAM @new_path @old_path
 
6398
 
 
6399
    where @new_path is replaced with the path of the new version of the 
 
6400
    file and @old_path is replaced with the path of the old version of 
 
6401
    the file.  The PROGRAM should save the new file with the desired 
 
6402
    contents of the file in the working tree.
 
6403
        
5852
6404
    """
5853
6405
 
5854
6406
    takes_args = ['file*']
5866
6418
        Option('destroy',
5867
6419
               help='Destroy removed changes instead of shelving them.'),
5868
6420
    ]
5869
 
    _see_also = ['unshelve']
 
6421
    _see_also = ['unshelve', 'configuration']
5870
6422
 
5871
6423
    def run(self, revision=None, all=False, file_list=None, message=None,
5872
 
            writer=None, list=False, destroy=False, directory=u'.'):
 
6424
            writer=None, list=False, destroy=False, directory=None):
5873
6425
        if list:
5874
 
            return self.run_for_list()
 
6426
            return self.run_for_list(directory=directory)
5875
6427
        from bzrlib.shelf_ui import Shelver
5876
6428
        if writer is None:
5877
6429
            writer = bzrlib.option.diff_writer_registry.get()
5885
6437
        except errors.UserAbort:
5886
6438
            return 0
5887
6439
 
5888
 
    def run_for_list(self):
5889
 
        tree = WorkingTree.open_containing('.')[0]
 
6440
    def run_for_list(self, directory=None):
 
6441
        if directory is None:
 
6442
            directory = u'.'
 
6443
        tree = WorkingTree.open_containing(directory)[0]
5890
6444
        self.add_cleanup(tree.lock_read().unlock)
5891
6445
        manager = tree.get_shelf_manager()
5892
6446
        shelves = manager.active_shelves()
5893
6447
        if len(shelves) == 0:
5894
 
            note('No shelved changes.')
 
6448
            note(gettext('No shelved changes.'))
5895
6449
            return 0
5896
6450
        for shelf_id in reversed(shelves):
5897
6451
            message = manager.get_metadata(shelf_id).get('message')
5951
6505
    """
5952
6506
    takes_options = ['directory',
5953
6507
                     Option('ignored', help='Delete all ignored files.'),
5954
 
                     Option('detritus', help='Delete conflict files, merge'
 
6508
                     Option('detritus', help='Delete conflict files, merge and revert'
5955
6509
                            ' backups, and failed selftest dirs.'),
5956
6510
                     Option('unknown',
5957
6511
                            help='Delete files unknown to bzr (default).'),
5986
6540
        if path is not None:
5987
6541
            branchdir = path
5988
6542
        tree, branch, relpath =(
5989
 
            bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
 
6543
            controldir.ControlDir.open_containing_tree_or_branch(branchdir))
5990
6544
        if path is not None:
5991
6545
            path = relpath
5992
6546
        if tree is None:
6016
6570
            self.outf.write('%s %s\n' % (path, location))
6017
6571
 
6018
6572
 
 
6573
class cmd_export_pot(Command):
 
6574
    __doc__ = """Export command helps and error messages in po format."""
 
6575
 
 
6576
    hidden = True
 
6577
    takes_options = [Option('plugin', 
 
6578
                            help='Export help text from named command '\
 
6579
                                 '(defaults to all built in commands).',
 
6580
                            type=str),
 
6581
                     Option('include-duplicates',
 
6582
                            help='Output multiple copies of the same msgid '
 
6583
                                 'string if it appears more than once.'),
 
6584
                            ]
 
6585
 
 
6586
    def run(self, plugin=None, include_duplicates=False):
 
6587
        from bzrlib.export_pot import export_pot
 
6588
        export_pot(self.outf, plugin, include_duplicates)
 
6589
 
 
6590
 
6019
6591
def _register_lazy_builtins():
6020
6592
    # register lazy builtins from other modules; called at startup and should
6021
6593
    # be only called once.
6022
6594
    for (name, aliases, module_name) in [
6023
6595
        ('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
 
6596
        ('cmd_config', [], 'bzrlib.config'),
6024
6597
        ('cmd_dpush', [], 'bzrlib.foreign'),
6025
6598
        ('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6026
6599
        ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6027
6600
        ('cmd_conflicts', [], 'bzrlib.conflicts'),
6028
 
        ('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
 
6601
        ('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
 
6602
        ('cmd_verify_signatures', [],
 
6603
                                        'bzrlib.commit_signature_commands'),
 
6604
        ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6029
6605
        ]:
6030
6606
        builtin_command_registry.register_lazy(name, aliases, module_name)