~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Jelmer Vernooij
  • Date: 2011-12-16 19:18:39 UTC
  • mto: This revision was merged to the branch mainline in revision 6391.
  • Revision ID: jelmer@samba.org-20111216191839-eg681lxqibi1qxu1
Fix remaining tests.

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
24
 
import itertools
25
 
import re
 
26
import errno
26
27
import sys
27
28
import time
28
29
 
31
32
    bugtracker,
32
33
    bundle,
33
34
    btree_index,
34
 
    bzrdir,
 
35
    controldir,
35
36
    directory_service,
36
37
    delta,
37
38
    config as _mod_config,
46
47
    rename_map,
47
48
    revision as _mod_revision,
48
49
    static_tuple,
49
 
    symbol_versioning,
50
50
    timestamp,
51
51
    transport,
52
52
    ui,
53
53
    urlutils,
54
54
    views,
 
55
    gpg,
55
56
    )
56
57
from bzrlib.branch import Branch
57
58
from bzrlib.conflicts import ConflictList
59
60
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
60
61
from bzrlib.smtp_connection import SMTPConnection
61
62
from bzrlib.workingtree import WorkingTree
 
63
from bzrlib.i18n import gettext, ngettext
62
64
""")
63
65
 
64
66
from bzrlib.commands import (
74
76
    _parse_revision_str,
75
77
    )
76
78
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
 
79
from bzrlib import (
 
80
    symbol_versioning,
 
81
    )
77
82
 
78
83
 
79
84
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
111
116
            if view_files:
112
117
                file_list = view_files
113
118
                view_str = views.view_display_str(view_files)
114
 
                note("Ignoring files outside view. View is %s" % view_str)
 
119
                note(gettext("Ignoring files outside view. View is %s") % view_str)
115
120
    return tree, file_list
116
121
 
117
122
 
119
124
    if revisions is None:
120
125
        return None
121
126
    if len(revisions) != 1:
122
 
        raise errors.BzrCommandError(
123
 
            'bzr %s --revision takes exactly one revision identifier' % (
 
127
        raise errors.BzrCommandError(gettext(
 
128
            'bzr %s --revision takes exactly one revision identifier') % (
124
129
                command_name,))
125
130
    return revisions[0]
126
131
 
195
200
    the --directory option is used to specify a different branch."""
196
201
    if directory is not None:
197
202
        return (None, Branch.open(directory), filename)
198
 
    return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
 
203
    return controldir.ControlDir.open_containing_tree_or_branch(filename)
199
204
 
200
205
 
201
206
# TODO: Make sure no commands unconditionally use the working directory as a
231
236
    unknown
232
237
        Not versioned and not matching an ignore pattern.
233
238
 
234
 
    Additionally for directories, symlinks and files with an executable
235
 
    bit, Bazaar indicates their type using a trailing character: '/', '@'
236
 
    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.
237
243
 
238
244
    To see ignored files use 'bzr ignored'.  For details on the
239
245
    changes to file texts, use 'bzr diff'.
270
276
                            short_name='V'),
271
277
                     Option('no-pending', help='Don\'t show pending merges.',
272
278
                           ),
 
279
                     Option('no-classify',
 
280
                            help='Do not mark object type using indicator.',
 
281
                           ),
273
282
                     ]
274
283
    aliases = ['st', 'stat']
275
284
 
278
287
 
279
288
    @display_command
280
289
    def run(self, show_ids=False, file_list=None, revision=None, short=False,
281
 
            versioned=False, no_pending=False, verbose=False):
 
290
            versioned=False, no_pending=False, verbose=False,
 
291
            no_classify=False):
282
292
        from bzrlib.status import show_tree_status
283
293
 
284
294
        if revision and len(revision) > 2:
285
 
            raise errors.BzrCommandError('bzr status --revision takes exactly'
286
 
                                         ' one or two revision specifiers')
 
295
            raise errors.BzrCommandError(gettext('bzr status --revision takes exactly'
 
296
                                         ' one or two revision specifiers'))
287
297
 
288
298
        tree, relfile_list = WorkingTree.open_containing_paths(file_list)
289
299
        # Avoid asking for specific files when that is not needed.
298
308
        show_tree_status(tree, show_ids=show_ids,
299
309
                         specific_files=relfile_list, revision=revision,
300
310
                         to_file=self.outf, short=short, versioned=versioned,
301
 
                         show_pending=(not no_pending), verbose=verbose)
 
311
                         show_pending=(not no_pending), verbose=verbose,
 
312
                         classify=not no_classify)
302
313
 
303
314
 
304
315
class cmd_cat_revision(Command):
325
336
    @display_command
326
337
    def run(self, revision_id=None, revision=None, directory=u'.'):
327
338
        if revision_id is not None and revision is not None:
328
 
            raise errors.BzrCommandError('You can only supply one of'
329
 
                                         ' revision_id or --revision')
 
339
            raise errors.BzrCommandError(gettext('You can only supply one of'
 
340
                                         ' revision_id or --revision'))
330
341
        if revision_id is None and revision is None:
331
 
            raise errors.BzrCommandError('You must supply either'
332
 
                                         ' --revision or a revision_id')
333
 
        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]
334
346
 
335
347
        revisions = b.repository.revisions
336
348
        if revisions is None:
337
 
            raise errors.BzrCommandError('Repository %r does not support '
338
 
                'access to raw revision texts')
 
349
            raise errors.BzrCommandError(gettext('Repository %r does not support '
 
350
                'access to raw revision texts'))
339
351
 
340
352
        b.repository.lock_read()
341
353
        try:
345
357
                try:
346
358
                    self.print_revision(revisions, revision_id)
347
359
                except errors.NoSuchRevision:
348
 
                    msg = "The repository %s contains no revision %s." % (
 
360
                    msg = gettext("The repository {0} contains no revision {1}.").format(
349
361
                        b.repository.base, revision_id)
350
362
                    raise errors.BzrCommandError(msg)
351
363
            elif revision is not None:
352
364
                for rev in revision:
353
365
                    if rev is None:
354
366
                        raise errors.BzrCommandError(
355
 
                            'You cannot specify a NULL revision.')
 
367
                            gettext('You cannot specify a NULL revision.'))
356
368
                    rev_id = rev.as_revision_id(b)
357
369
                    self.print_revision(revisions, rev_id)
358
370
        finally:
414
426
                self.outf.write(page_bytes[:header_end])
415
427
                page_bytes = data
416
428
            self.outf.write('\nPage %d\n' % (page_idx,))
417
 
            decomp_bytes = zlib.decompress(page_bytes)
418
 
            self.outf.write(decomp_bytes)
419
 
            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')
420
435
 
421
436
    def _dump_entries(self, trans, basename):
422
437
        try:
461
476
            location_list=['.']
462
477
 
463
478
        for location in location_list:
464
 
            d = bzrdir.BzrDir.open(location)
465
 
            
 
479
            d = controldir.ControlDir.open(location)
 
480
 
466
481
            try:
467
482
                working = d.open_workingtree()
468
483
            except errors.NoWorkingTree:
469
 
                raise errors.BzrCommandError("No working tree to remove")
 
484
                raise errors.BzrCommandError(gettext("No working tree to remove"))
470
485
            except errors.NotLocalUrl:
471
 
                raise errors.BzrCommandError("You cannot remove the working tree"
472
 
                                             " of a remote path")
 
486
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
487
                                             " of a remote path"))
473
488
            if not force:
474
489
                if (working.has_changes()):
475
490
                    raise errors.UncommittedChanges(working)
477
492
                    raise errors.ShelvedChanges(working)
478
493
 
479
494
            if working.user_url != working.branch.user_url:
480
 
                raise errors.BzrCommandError("You cannot remove the working tree"
481
 
                                             " from a lightweight checkout")
 
495
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
496
                                             " from a lightweight checkout"))
482
497
 
483
498
            d.destroy_workingtree()
484
499
 
485
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
 
486
553
class cmd_revno(Command):
487
554
    __doc__ = """Show current revision number.
488
555
 
492
559
    _see_also = ['info']
493
560
    takes_args = ['location?']
494
561
    takes_options = [
495
 
        Option('tree', help='Show revno of working tree'),
 
562
        Option('tree', help='Show revno of working tree.'),
 
563
        'revision',
496
564
        ]
497
565
 
498
566
    @display_command
499
 
    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
 
500
572
        if tree:
501
573
            try:
502
574
                wt = WorkingTree.open_containing(location)[0]
503
575
                self.add_cleanup(wt.lock_read().unlock)
504
576
            except (errors.NoWorkingTree, errors.NotLocalUrl):
505
577
                raise errors.NoWorkingTree(location)
 
578
            b = wt.branch
506
579
            revid = wt.last_revision()
507
 
            try:
508
 
                revno_t = wt.branch.revision_id_to_dotted_revno(revid)
509
 
            except errors.NoSuchRevision:
510
 
                revno_t = ('???',)
511
 
            revno = ".".join(str(n) for n in revno_t)
512
580
        else:
513
581
            b = Branch.open_containing(location)[0]
514
582
            self.add_cleanup(b.lock_read().unlock)
515
 
            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)
516
596
        self.cleanup_now()
517
 
        self.outf.write(str(revno) + '\n')
 
597
        self.outf.write(revno + '\n')
518
598
 
519
599
 
520
600
class cmd_revision_info(Command):
527
607
        custom_help('directory',
528
608
            help='Branch to examine, '
529
609
                 'rather than the one containing the working directory.'),
530
 
        Option('tree', help='Show revno of working tree'),
 
610
        Option('tree', help='Show revno of working tree.'),
531
611
        ]
532
612
 
533
613
    @display_command
589
669
    are added.  This search proceeds recursively into versioned
590
670
    directories.  If no names are given '.' is assumed.
591
671
 
 
672
    A warning will be printed when nested trees are encountered,
 
673
    unless they are explicitly ignored.
 
674
 
592
675
    Therefore simply saying 'bzr add' will version all files that
593
676
    are currently unknown.
594
677
 
610
693
    
611
694
    Any files matching patterns in the ignore list will not be added
612
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.
613
700
    """
614
701
    takes_args = ['file*']
615
702
    takes_options = [
642
729
            action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
643
730
                          to_file=self.outf, should_print=(not is_quiet()))
644
731
        else:
645
 
            action = bzrlib.add.AddAction(to_file=self.outf,
 
732
            action = bzrlib.add.AddWithSkipLargeAction(to_file=self.outf,
646
733
                should_print=(not is_quiet()))
647
734
 
648
735
        if base_tree:
655
742
            if verbose:
656
743
                for glob in sorted(ignored.keys()):
657
744
                    for path in ignored[glob]:
658
 
                        self.outf.write("ignored %s matching \"%s\"\n"
659
 
                                        % (path, glob))
 
745
                        self.outf.write(
 
746
                         gettext("ignored {0} matching \"{1}\"\n").format(
 
747
                         path, glob))
660
748
 
661
749
 
662
750
class cmd_mkdir(Command):
666
754
    """
667
755
 
668
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
        ]
669
764
    encoding_type = 'replace'
670
765
 
671
 
    def run(self, dir_list):
672
 
        for d in dir_list:
673
 
            wt, dd = WorkingTree.open_containing(d)
674
 
            base = os.path.dirname(dd)
675
 
            id = wt.path2id(base)
676
 
            if id != None:
677
 
                os.mkdir(d)
678
 
                wt.add([dd])
679
 
                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
680
790
            else:
681
 
                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)
682
795
 
683
796
 
684
797
class cmd_relpath(Command):
720
833
    @display_command
721
834
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
722
835
        if kind and kind not in ['file', 'directory', 'symlink']:
723
 
            raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
 
836
            raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
724
837
 
725
838
        revision = _get_one_revision('inventory', revision)
726
839
        work_tree, file_list = WorkingTree.open_containing_paths(file_list)
739
852
                                      require_versioned=True)
740
853
            # find_ids_across_trees may include some paths that don't
741
854
            # exist in 'tree'.
742
 
            entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
743
 
                             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))
744
858
        else:
745
859
            entries = tree.inventory.entries()
746
860
 
789
903
        if auto:
790
904
            return self.run_auto(names_list, after, dry_run)
791
905
        elif dry_run:
792
 
            raise errors.BzrCommandError('--dry-run requires --auto.')
 
906
            raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
793
907
        if names_list is None:
794
908
            names_list = []
795
909
        if len(names_list) < 2:
796
 
            raise errors.BzrCommandError("missing file argument")
 
910
            raise errors.BzrCommandError(gettext("missing file argument"))
797
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"))
798
915
        self.add_cleanup(tree.lock_tree_write().unlock)
799
916
        self._run(tree, names_list, rel_names, after)
800
917
 
801
918
    def run_auto(self, names_list, after, dry_run):
802
919
        if names_list is not None and len(names_list) > 1:
803
 
            raise errors.BzrCommandError('Only one path may be specified to'
804
 
                                         ' --auto.')
 
920
            raise errors.BzrCommandError(gettext('Only one path may be specified to'
 
921
                                         ' --auto.'))
805
922
        if after:
806
 
            raise errors.BzrCommandError('--after cannot be specified with'
807
 
                                         ' --auto.')
 
923
            raise errors.BzrCommandError(gettext('--after cannot be specified with'
 
924
                                         ' --auto.'))
808
925
        work_tree, file_list = WorkingTree.open_containing_paths(
809
926
            names_list, default_directory='.')
810
927
        self.add_cleanup(work_tree.lock_tree_write().unlock)
840
957
                    self.outf.write("%s => %s\n" % (src, dest))
841
958
        else:
842
959
            if len(names_list) != 2:
843
 
                raise errors.BzrCommandError('to mv multiple files the'
 
960
                raise errors.BzrCommandError(gettext('to mv multiple files the'
844
961
                                             ' destination must be a versioned'
845
 
                                             ' directory')
 
962
                                             ' directory'))
846
963
 
847
964
            # for cicp file-systems: the src references an existing inventory
848
965
            # item:
907
1024
    match the remote one, use pull --overwrite. This will work even if the two
908
1025
    branches have diverged.
909
1026
 
910
 
    If there is no default location set, the first pull will set it.  After
911
 
    that, you can omit the location to use the default.  To change the
912
 
    default, use --remember. The value will only be saved if the remote
913
 
    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>.
914
1035
 
915
1036
    Note: The location can be specified either in the form of a branch,
916
1037
    or in the form of a path to a file containing a merge directive generated
935
1056
    takes_args = ['location?']
936
1057
    encoding_type = 'replace'
937
1058
 
938
 
    def run(self, location=None, remember=False, overwrite=False,
 
1059
    def run(self, location=None, remember=None, overwrite=False,
939
1060
            revision=None, verbose=False,
940
1061
            directory=None, local=False,
941
1062
            show_base=False):
954
1075
            self.add_cleanup(branch_to.lock_write().unlock)
955
1076
 
956
1077
        if tree_to is None and show_base:
957
 
            raise errors.BzrCommandError("Need working tree for --show-base.")
 
1078
            raise errors.BzrCommandError(gettext("Need working tree for --show-base."))
958
1079
 
959
1080
        if local and not branch_to.get_bound_location():
960
1081
            raise errors.LocalRequiresBoundBranch()
970
1091
        stored_loc = branch_to.get_parent()
971
1092
        if location is None:
972
1093
            if stored_loc is None:
973
 
                raise errors.BzrCommandError("No pull location known or"
974
 
                                             " specified.")
 
1094
                raise errors.BzrCommandError(gettext("No pull location known or"
 
1095
                                             " specified."))
975
1096
            else:
976
1097
                display_url = urlutils.unescape_for_display(stored_loc,
977
1098
                        self.outf.encoding)
978
1099
                if not is_quiet():
979
 
                    self.outf.write("Using saved parent location: %s\n" % display_url)
 
1100
                    self.outf.write(gettext("Using saved parent location: %s\n") % display_url)
980
1101
                location = stored_loc
981
1102
 
982
1103
        revision = _get_one_revision('pull', revision)
983
1104
        if mergeable is not None:
984
1105
            if revision is not None:
985
 
                raise errors.BzrCommandError(
986
 
                    'Cannot use -r with merge directives or bundles')
 
1106
                raise errors.BzrCommandError(gettext(
 
1107
                    'Cannot use -r with merge directives or bundles'))
987
1108
            mergeable.install_revisions(branch_to.repository)
988
1109
            base_revision_id, revision_id, verified = \
989
1110
                mergeable.get_merge_request(branch_to.repository)
992
1113
            branch_from = Branch.open(location,
993
1114
                possible_transports=possible_transports)
994
1115
            self.add_cleanup(branch_from.lock_read().unlock)
995
 
 
996
 
            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)):
997
1119
                branch_to.set_parent(branch_from.base)
998
1120
 
999
1121
        if revision is not None:
1006
1128
                view_info=view_info)
1007
1129
            result = tree_to.pull(
1008
1130
                branch_from, overwrite, revision_id, change_reporter,
1009
 
                possible_transports=possible_transports, local=local,
1010
 
                show_base=show_base)
 
1131
                local=local, show_base=show_base)
1011
1132
        else:
1012
1133
            result = branch_to.pull(
1013
1134
                branch_from, overwrite, revision_id, local=local)
1017
1138
            log.show_branch_change(
1018
1139
                branch_to, self.outf, result.old_revno,
1019
1140
                result.old_revid)
 
1141
        if getattr(result, 'tag_conflicts', None):
 
1142
            return 1
 
1143
        else:
 
1144
            return 0
1020
1145
 
1021
1146
 
1022
1147
class cmd_push(Command):
1039
1164
    do a merge (see bzr help merge) from the other branch, and commit that.
1040
1165
    After that you will be able to do a push without '--overwrite'.
1041
1166
 
1042
 
    If there is no default push location set, the first push will set it.
1043
 
    After that, you can omit the location to use the default.  To change the
1044
 
    default, use --remember. The value will only be saved if the remote
1045
 
    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>.
1046
1175
    """
1047
1176
 
1048
1177
    _see_also = ['pull', 'update', 'working-trees']
1076
1205
    takes_args = ['location?']
1077
1206
    encoding_type = 'replace'
1078
1207
 
1079
 
    def run(self, location=None, remember=False, overwrite=False,
 
1208
    def run(self, location=None, remember=None, overwrite=False,
1080
1209
        create_prefix=False, verbose=False, revision=None,
1081
1210
        use_existing_dir=False, directory=None, stacked_on=None,
1082
1211
        stacked=False, strict=None, no_tree=False):
1086
1215
            directory = '.'
1087
1216
        # Get the source branch
1088
1217
        (tree, br_from,
1089
 
         _unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
 
1218
         _unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
1090
1219
        # Get the tip's revision_id
1091
1220
        revision = _get_one_revision('push', revision)
1092
1221
        if revision is not None:
1113
1242
                    # error by the feedback given to them. RBC 20080227.
1114
1243
                    stacked_on = parent_url
1115
1244
            if not stacked_on:
1116
 
                raise errors.BzrCommandError(
1117
 
                    "Could not determine branch to refer to.")
 
1245
                raise errors.BzrCommandError(gettext(
 
1246
                    "Could not determine branch to refer to."))
1118
1247
 
1119
1248
        # Get the destination location
1120
1249
        if location is None:
1121
1250
            stored_loc = br_from.get_push_location()
1122
1251
            if stored_loc is None:
1123
 
                raise errors.BzrCommandError(
1124
 
                    "No push location known or specified.")
 
1252
                raise errors.BzrCommandError(gettext(
 
1253
                    "No push location known or specified."))
1125
1254
            else:
1126
1255
                display_url = urlutils.unescape_for_display(stored_loc,
1127
1256
                        self.outf.encoding)
1128
 
                self.outf.write("Using saved push location: %s\n" % display_url)
 
1257
                note(gettext("Using saved push location: %s") % display_url)
1129
1258
                location = stored_loc
1130
1259
 
1131
1260
        _show_push_branch(br_from, revision_id, location, self.outf,
1146
1275
 
1147
1276
    To retrieve the branch as of a particular revision, supply the --revision
1148
1277
    parameter, as in "branch foo/bar -r 5".
 
1278
 
 
1279
    The synonyms 'clone' and 'get' for this command are deprecated.
1149
1280
    """
1150
1281
 
1151
1282
    _see_also = ['checkout']
1181
1312
            files_from=None):
1182
1313
        from bzrlib import switch as _mod_switch
1183
1314
        from bzrlib.tag import _merge_tags_if_possible
1184
 
        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(
1185
1322
            from_location)
1186
1323
        if not (hardlink or files_from):
1187
1324
            # accelerator_tree is usually slower because you have to read N
1200
1337
            # RBC 20060209
1201
1338
            revision_id = br_from.last_revision()
1202
1339
        if to_location is None:
1203
 
            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)
1204
1343
        to_transport = transport.get_transport(to_location)
1205
1344
        try:
1206
1345
            to_transport.mkdir('.')
1207
1346
        except errors.FileExists:
1208
 
            if not use_existing_dir:
1209
 
                raise errors.BzrCommandError('Target directory "%s" '
1210
 
                    '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
1211
1356
            else:
1212
1357
                try:
1213
 
                    bzrdir.BzrDir.open_from_transport(to_transport)
 
1358
                    to_dir.open_branch()
1214
1359
                except errors.NotBranchError:
1215
1360
                    pass
1216
1361
                else:
1217
1362
                    raise errors.AlreadyBranchError(to_location)
1218
1363
        except errors.NoSuchFile:
1219
 
            raise errors.BzrCommandError('Parent of "%s" does not exist.'
 
1364
            raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1220
1365
                                         % to_location)
1221
 
        try:
1222
 
            # preserve whatever source format we have.
1223
 
            dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1224
 
                                        possible_transports=[to_transport],
1225
 
                                        accelerator_tree=accelerator_tree,
1226
 
                                        hardlink=hardlink, stacked=stacked,
1227
 
                                        force_new_repo=standalone,
1228
 
                                        create_tree_if_local=not no_tree,
1229
 
                                        source_branch=br_from)
1230
 
            branch = dir.open_branch()
1231
 
        except errors.NoSuchRevision:
1232
 
            to_transport.delete_tree('.')
1233
 
            msg = "The branch %s has no revision %s." % (from_location,
1234
 
                revision)
1235
 
            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)
1236
1388
        _merge_tags_if_possible(br_from, branch)
1237
1389
        # If the source branch is stacked, the new branch may
1238
1390
        # be stacked whether we asked for that explicitly or not.
1239
1391
        # We therefore need a try/except here and not just 'if stacked:'
1240
1392
        try:
1241
 
            note('Created new stacked branch referring to %s.' %
 
1393
            note(gettext('Created new stacked branch referring to %s.') %
1242
1394
                branch.get_stacked_on_url())
1243
1395
        except (errors.NotStacked, errors.UnstackableBranchFormat,
1244
1396
            errors.UnstackableRepositoryFormat), e:
1245
 
            note('Branched %d revision(s).' % branch.revno())
 
1397
            note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1246
1398
        if bind:
1247
1399
            # Bind to the parent
1248
1400
            parent_branch = Branch.open(from_location)
1249
1401
            branch.bind(parent_branch)
1250
 
            note('New branch bound to %s' % from_location)
 
1402
            note(gettext('New branch bound to %s') % from_location)
1251
1403
        if switch:
1252
1404
            # Switch to the new branch
1253
1405
            wt, _ = WorkingTree.open_containing('.')
1254
1406
            _mod_switch.switch(wt.bzrdir, branch)
1255
 
            note('Switched to branch: %s',
 
1407
            note(gettext('Switched to branch: %s'),
1256
1408
                urlutils.unescape_for_display(branch.base, 'utf-8'))
1257
1409
 
1258
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
 
1259
1444
class cmd_checkout(Command):
1260
1445
    __doc__ = """Create a new checkout of an existing branch.
1261
1446
 
1300
1485
        if branch_location is None:
1301
1486
            branch_location = osutils.getcwd()
1302
1487
            to_location = branch_location
1303
 
        accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
 
1488
        accelerator_tree, source = controldir.ControlDir.open_tree_or_branch(
1304
1489
            branch_location)
1305
1490
        if not (hardlink or files_from):
1306
1491
            # accelerator_tree is usually slower because you have to read N
1361
1546
 
1362
1547
 
1363
1548
class cmd_update(Command):
1364
 
    __doc__ = """Update a tree to have the latest code committed to its branch.
1365
 
 
1366
 
    This will perform a merge into the working tree, and may generate
1367
 
    conflicts. If you have any local changes, you will still
1368
 
    need to commit them after the update for the update to be complete.
1369
 
 
1370
 
    If you want to discard your local changes, you can just do a
1371
 
    'bzr revert' instead of 'bzr commit' after the update.
1372
 
 
1373
 
    If you want to restore a file that has been removed locally, use
1374
 
    'bzr revert' instead of 'bzr update'.
1375
 
 
1376
 
    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
1377
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.
1378
1576
    """
1379
1577
 
1380
1578
    _see_also = ['pull', 'working-trees', 'status-flags']
1385
1583
                     ]
1386
1584
    aliases = ['up']
1387
1585
 
1388
 
    def run(self, dir='.', revision=None, show_base=None):
 
1586
    def run(self, dir=None, revision=None, show_base=None):
1389
1587
        if revision is not None and len(revision) != 1:
1390
 
            raise errors.BzrCommandError(
1391
 
                        "bzr update --revision takes exactly one revision")
1392
 
        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"))
1393
1599
        branch = tree.branch
1394
1600
        possible_transports = []
1395
1601
        master = branch.get_master_branch(
1419
1625
            revision_id = branch.last_revision()
1420
1626
        if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1421
1627
            revno = branch.revision_id_to_dotted_revno(revision_id)
1422
 
            note("Tree is up to date at revision %s of branch %s" %
1423
 
                ('.'.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))
1424
1630
            return 0
1425
1631
        view_info = _get_view_info_for_change_reporter(tree)
1426
1632
        change_reporter = delta._ChangeReporter(
1434
1640
                old_tip=old_tip,
1435
1641
                show_base=show_base)
1436
1642
        except errors.NoSuchRevision, e:
1437
 
            raise errors.BzrCommandError(
 
1643
            raise errors.BzrCommandError(gettext(
1438
1644
                                  "branch has no revision %s\n"
1439
1645
                                  "bzr update --revision only works"
1440
 
                                  " for a revision in the branch history"
 
1646
                                  " for a revision in the branch history")
1441
1647
                                  % (e.revision))
1442
1648
        revno = tree.branch.revision_id_to_dotted_revno(
1443
1649
            _mod_revision.ensure_null(tree.last_revision()))
1444
 
        note('Updated to revision %s of branch %s' %
1445
 
             ('.'.join(map(str, revno)), branch_location))
 
1650
        note(gettext('Updated to revision {0} of branch {1}').format(
 
1651
             '.'.join(map(str, revno)), branch_location))
1446
1652
        parent_ids = tree.get_parent_ids()
1447
1653
        if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1448
 
            note('Your local commits will now show as pending merges with '
1449
 
                 "'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'."))
1450
1656
        if conflicts != 0:
1451
1657
            return 1
1452
1658
        else:
1493
1699
        else:
1494
1700
            noise_level = 0
1495
1701
        from bzrlib.info import show_bzrdir_info
1496
 
        show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
 
1702
        show_bzrdir_info(controldir.ControlDir.open_containing(location)[0],
1497
1703
                         verbose=noise_level, outfile=self.outf)
1498
1704
 
1499
1705
 
1524
1730
    def run(self, file_list, verbose=False, new=False,
1525
1731
        file_deletion_strategy='safe'):
1526
1732
        if file_deletion_strategy == 'force':
1527
 
            note("(The --force option is deprecated, rather use --no-backup "
1528
 
                "in future.)")
 
1733
            note(gettext("(The --force option is deprecated, rather use --no-backup "
 
1734
                "in future.)"))
1529
1735
            file_deletion_strategy = 'no-backup'
1530
1736
 
1531
1737
        tree, file_list = WorkingTree.open_containing_paths(file_list)
1541
1747
                specific_files=file_list).added
1542
1748
            file_list = sorted([f[0] for f in added], reverse=True)
1543
1749
            if len(file_list) == 0:
1544
 
                raise errors.BzrCommandError('No matching files.')
 
1750
                raise errors.BzrCommandError(gettext('No matching files.'))
1545
1751
        elif file_list is None:
1546
1752
            # missing files show up in iter_changes(basis) as
1547
1753
            # versioned-with-no-kind.
1631
1837
 
1632
1838
    def run(self, branch=".", canonicalize_chks=False):
1633
1839
        from bzrlib.reconcile import reconcile
1634
 
        dir = bzrdir.BzrDir.open(branch)
 
1840
        dir = controldir.ControlDir.open(branch)
1635
1841
        reconcile(dir, canonicalize_chks=canonicalize_chks)
1636
1842
 
1637
1843
 
1646
1852
    @display_command
1647
1853
    def run(self, location="."):
1648
1854
        branch = Branch.open_containing(location)[0]
1649
 
        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):
1650
1860
            self.outf.write(revid)
1651
1861
            self.outf.write('\n')
1652
1862
 
1670
1880
            b = wt.branch
1671
1881
            last_revision = wt.last_revision()
1672
1882
 
1673
 
        revision_ids = b.repository.get_ancestry(last_revision)
1674
 
        revision_ids.pop(0)
1675
 
        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
1676
1890
            self.outf.write(revision_id + '\n')
1677
1891
 
1678
1892
 
1709
1923
                help='Specify a format for this branch. '
1710
1924
                'See "help formats".',
1711
1925
                lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1712
 
                converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
1926
                converter=lambda name: controldir.format_registry.make_bzrdir(name),
1713
1927
                value_switches=True,
1714
1928
                title="Branch format",
1715
1929
                ),
1722
1936
    def run(self, location=None, format=None, append_revisions_only=False,
1723
1937
            create_prefix=False, no_tree=False):
1724
1938
        if format is None:
1725
 
            format = bzrdir.format_registry.make_bzrdir('default')
 
1939
            format = controldir.format_registry.make_bzrdir('default')
1726
1940
        if location is None:
1727
1941
            location = u'.'
1728
1942
 
1737
1951
            to_transport.ensure_base()
1738
1952
        except errors.NoSuchFile:
1739
1953
            if not create_prefix:
1740
 
                raise errors.BzrCommandError("Parent directory of %s"
 
1954
                raise errors.BzrCommandError(gettext("Parent directory of %s"
1741
1955
                    " does not exist."
1742
1956
                    "\nYou may supply --create-prefix to create all"
1743
 
                    " leading parent directories."
 
1957
                    " leading parent directories.")
1744
1958
                    % location)
1745
1959
            to_transport.create_prefix()
1746
1960
 
1747
1961
        try:
1748
 
            a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
 
1962
            a_bzrdir = controldir.ControlDir.open_from_transport(to_transport)
1749
1963
        except errors.NotBranchError:
1750
1964
            # really a NotBzrDir error...
1751
 
            create_branch = bzrdir.BzrDir.create_branch_convenience
 
1965
            create_branch = controldir.ControlDir.create_branch_convenience
1752
1966
            if no_tree:
1753
1967
                force_new_tree = False
1754
1968
            else:
1765
1979
                        raise errors.BranchExistsWithoutWorkingTree(location)
1766
1980
                raise errors.AlreadyBranchError(location)
1767
1981
            branch = a_bzrdir.create_branch()
1768
 
            if not no_tree:
 
1982
            if not no_tree and not a_bzrdir.has_workingtree():
1769
1983
                a_bzrdir.create_workingtree()
1770
1984
        if append_revisions_only:
1771
1985
            try:
1772
1986
                branch.set_append_revisions_only(True)
1773
1987
            except errors.UpgradeRequired:
1774
 
                raise errors.BzrCommandError('This branch format cannot be set'
1775
 
                    ' to append-revisions-only.  Try --default.')
 
1988
                raise errors.BzrCommandError(gettext('This branch format cannot be set'
 
1989
                    ' to append-revisions-only.  Try --default.'))
1776
1990
        if not is_quiet():
1777
1991
            from bzrlib.info import describe_layout, describe_format
1778
1992
            try:
1782
1996
            repository = branch.repository
1783
1997
            layout = describe_layout(repository, branch, tree).lower()
1784
1998
            format = describe_format(a_bzrdir, repository, branch, tree)
1785
 
            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))
1786
2001
            if repository.is_shared():
1787
2002
                #XXX: maybe this can be refactored into transport.path_or_url()
1788
2003
                url = repository.bzrdir.root_transport.external_url()
1790
2005
                    url = urlutils.local_path_from_url(url)
1791
2006
                except errors.InvalidURL:
1792
2007
                    pass
1793
 
                self.outf.write("Using shared repository: %s\n" % url)
 
2008
                self.outf.write(gettext("Using shared repository: %s\n") % url)
1794
2009
 
1795
2010
 
1796
2011
class cmd_init_repository(Command):
1826
2041
    takes_options = [RegistryOption('format',
1827
2042
                            help='Specify a format for this repository. See'
1828
2043
                                 ' "bzr help formats" for details.',
1829
 
                            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
1830
 
                            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),
1831
2046
                            value_switches=True, title='Repository format'),
1832
2047
                     Option('no-trees',
1833
2048
                             help='Branches in the repository will default to'
1837
2052
 
1838
2053
    def run(self, location, format=None, no_trees=False):
1839
2054
        if format is None:
1840
 
            format = bzrdir.format_registry.make_bzrdir('default')
 
2055
            format = controldir.format_registry.make_bzrdir('default')
1841
2056
 
1842
2057
        if location is None:
1843
2058
            location = '.'
1963
2178
            type=unicode,
1964
2179
            ),
1965
2180
        RegistryOption('format',
 
2181
            short_name='F',
1966
2182
            help='Diff format to use.',
1967
2183
            lazy_registry=('bzrlib.diff', 'format_registry'),
1968
 
            value_switches=False, title='Diff format'),
 
2184
            title='Diff format'),
1969
2185
        ]
1970
2186
    aliases = ['di', 'dif']
1971
2187
    encoding_type = 'exact'
1986
2202
        elif ':' in prefix:
1987
2203
            old_label, new_label = prefix.split(":")
1988
2204
        else:
1989
 
            raise errors.BzrCommandError(
 
2205
            raise errors.BzrCommandError(gettext(
1990
2206
                '--prefix expects two values separated by a colon'
1991
 
                ' (eg "old/:new/")')
 
2207
                ' (eg "old/:new/")'))
1992
2208
 
1993
2209
        if revision and len(revision) > 2:
1994
 
            raise errors.BzrCommandError('bzr diff --revision takes exactly'
1995
 
                                         ' one or two revision specifiers')
 
2210
            raise errors.BzrCommandError(gettext('bzr diff --revision takes exactly'
 
2211
                                         ' one or two revision specifiers'))
1996
2212
 
1997
2213
        if using is not None and format is not None:
1998
 
            raise errors.BzrCommandError('--using and --format are mutually '
1999
 
                'exclusive.')
 
2214
            raise errors.BzrCommandError(gettext(
 
2215
                '{0} and {1} are mutually exclusive').format(
 
2216
                '--using', '--format'))
2000
2217
 
2001
2218
        (old_tree, new_tree,
2002
2219
         old_branch, new_branch,
2052
2269
    @display_command
2053
2270
    def run(self, null=False, directory=u'.'):
2054
2271
        tree = WorkingTree.open_containing(directory)[0]
 
2272
        self.add_cleanup(tree.lock_read().unlock)
2055
2273
        td = tree.changes_from(tree.basis_tree())
 
2274
        self.cleanup_now()
2056
2275
        for path, id, kind, text_modified, meta_modified in td.modified:
2057
2276
            if null:
2058
2277
                self.outf.write(path + '\0')
2077
2296
        basis_inv = basis.inventory
2078
2297
        inv = wt.inventory
2079
2298
        for file_id in inv:
2080
 
            if file_id in basis_inv:
 
2299
            if basis_inv.has_id(file_id):
2081
2300
                continue
2082
2301
            if inv.is_root(file_id) and len(basis_inv) == 0:
2083
2302
                continue
2108
2327
    try:
2109
2328
        return int(limitstring)
2110
2329
    except ValueError:
2111
 
        msg = "The limit argument must be an integer."
 
2330
        msg = gettext("The limit argument must be an integer.")
2112
2331
        raise errors.BzrCommandError(msg)
2113
2332
 
2114
2333
 
2116
2335
    try:
2117
2336
        return int(s)
2118
2337
    except ValueError:
2119
 
        msg = "The levels argument must be an integer."
 
2338
        msg = gettext("The levels argument must be an integer.")
2120
2339
        raise errors.BzrCommandError(msg)
2121
2340
 
2122
2341
 
2232
2451
 
2233
2452
    :Other filtering:
2234
2453
 
2235
 
      The --message option can be used for finding revisions that match a
2236
 
      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.
2237
2459
 
2238
2460
    :Tips & tricks:
2239
2461
 
2299
2521
                   argname='N',
2300
2522
                   type=_parse_levels),
2301
2523
            Option('message',
2302
 
                   short_name='m',
2303
2524
                   help='Show revisions whose message matches this '
2304
2525
                        'regular expression.',
2305
 
                   type=str),
 
2526
                   type=str,
 
2527
                   hidden=True),
2306
2528
            Option('limit',
2307
2529
                   short_name='l',
2308
2530
                   help='Limit the output to the first N revisions.',
2311
2533
            Option('show-diff',
2312
2534
                   short_name='p',
2313
2535
                   help='Show changes made in each revision as a patch.'),
2314
 
            Option('include-merges',
 
2536
            Option('include-merged',
2315
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.'),
2316
2542
            Option('exclude-common-ancestry',
2317
2543
                   help='Display only the revisions that are not part'
2318
 
                   ' of both ancestries (require -rX..Y)'
2319
 
                   )
 
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)
2320
2569
            ]
2321
2570
    encoding_type = 'replace'
2322
2571
 
2332
2581
            message=None,
2333
2582
            limit=None,
2334
2583
            show_diff=False,
2335
 
            include_merges=False,
 
2584
            include_merged=None,
2336
2585
            authors=None,
2337
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,
2338
2595
            ):
2339
2596
        from bzrlib.log import (
2340
2597
            Logger,
2342
2599
            _get_info_for_log_files,
2343
2600
            )
2344
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
2345
2617
        if (exclude_common_ancestry
2346
2618
            and (revision is None or len(revision) != 2)):
2347
 
            raise errors.BzrCommandError(
2348
 
                '--exclude-common-ancestry requires -r with two revisions')
2349
 
        if include_merges:
 
2619
            raise errors.BzrCommandError(gettext(
 
2620
                '--exclude-common-ancestry requires -r with two revisions'))
 
2621
        if include_merged:
2350
2622
            if levels is None:
2351
2623
                levels = 0
2352
2624
            else:
2353
 
                raise errors.BzrCommandError(
2354
 
                    '--levels and --include-merges are mutually exclusive')
 
2625
                raise errors.BzrCommandError(gettext(
 
2626
                    '{0} and {1} are mutually exclusive').format(
 
2627
                    '--levels', '--include-merged'))
2355
2628
 
2356
2629
        if change is not None:
2357
2630
            if len(change) > 1:
2358
2631
                raise errors.RangeInChangeOption()
2359
2632
            if revision is not None:
2360
 
                raise errors.BzrCommandError(
2361
 
                    '--revision and --change are mutually exclusive')
 
2633
                raise errors.BzrCommandError(gettext(
 
2634
                    '{0} and {1} are mutually exclusive').format(
 
2635
                    '--revision', '--change'))
2362
2636
            else:
2363
2637
                revision = change
2364
2638
 
2370
2644
                revision, file_list, self.add_cleanup)
2371
2645
            for relpath, file_id, kind in file_info_list:
2372
2646
                if file_id is None:
2373
 
                    raise errors.BzrCommandError(
2374
 
                        "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") %
2375
2649
                        relpath)
2376
2650
                # If the relpath is the top of the tree, we log everything
2377
2651
                if relpath == '':
2389
2663
                location = revision[0].get_branch()
2390
2664
            else:
2391
2665
                location = '.'
2392
 
            dir, relpath = bzrdir.BzrDir.open_containing(location)
 
2666
            dir, relpath = controldir.ControlDir.open_containing(location)
2393
2667
            b = dir.open_branch()
2394
2668
            self.add_cleanup(b.lock_read().unlock)
2395
2669
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2396
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
 
2397
2678
        # Decide on the type of delta & diff filtering to use
2398
2679
        # TODO: add an --all-files option to make this configurable & consistent
2399
2680
        if not verbose:
2436
2717
        match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2437
2718
            or delta_type or partial_history)
2438
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
 
2439
2732
        # Build the LogRequest and execute it
2440
2733
        if len(file_ids) == 0:
2441
2734
            file_ids = None
2444
2737
            start_revision=rev1, end_revision=rev2, limit=limit,
2445
2738
            message_search=message, delta_type=delta_type,
2446
2739
            diff_type=diff_type, _match_using_deltas=match_using_deltas,
2447
 
            exclude_common_ancestry=exclude_common_ancestry,
 
2740
            exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
 
2741
            signature=signatures, omit_merges=omit_merges,
2448
2742
            )
2449
2743
        Logger(b, rqst).show(lf)
2450
2744
 
2467
2761
            # b is taken from revision[0].get_branch(), and
2468
2762
            # show_log will use its revision_history. Having
2469
2763
            # different branches will lead to weird behaviors.
2470
 
            raise errors.BzrCommandError(
 
2764
            raise errors.BzrCommandError(gettext(
2471
2765
                "bzr %s doesn't accept two revisions in different"
2472
 
                " branches." % command_name)
 
2766
                " branches.") % command_name)
2473
2767
        if start_spec.spec is None:
2474
2768
            # Avoid loading all the history.
2475
2769
            rev1 = RevisionInfo(branch, None, None)
2483
2777
        else:
2484
2778
            rev2 = end_spec.in_history(branch)
2485
2779
    else:
2486
 
        raise errors.BzrCommandError(
2487
 
            '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)
2488
2782
    return rev1, rev2
2489
2783
 
2490
2784
 
2561
2855
            null=False, kind=None, show_ids=False, path=None, directory=None):
2562
2856
 
2563
2857
        if kind and kind not in ('file', 'directory', 'symlink'):
2564
 
            raise errors.BzrCommandError('invalid kind specified')
 
2858
            raise errors.BzrCommandError(gettext('invalid kind specified'))
2565
2859
 
2566
2860
        if verbose and null:
2567
 
            raise errors.BzrCommandError('Cannot set both --verbose and --null')
 
2861
            raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
2568
2862
        all = not (unknown or versioned or ignored)
2569
2863
 
2570
2864
        selection = {'I':ignored, '?':unknown, 'V':versioned}
2573
2867
            fs_path = '.'
2574
2868
        else:
2575
2869
            if from_root:
2576
 
                raise errors.BzrCommandError('cannot specify both --from-root'
2577
 
                                             ' and PATH')
 
2870
                raise errors.BzrCommandError(gettext('cannot specify both --from-root'
 
2871
                                             ' and PATH'))
2578
2872
            fs_path = path
2579
2873
        tree, branch, relpath = \
2580
2874
            _open_directory_or_containing_tree_or_branch(fs_path, directory)
2596
2890
            if view_files:
2597
2891
                apply_view = True
2598
2892
                view_str = views.view_display_str(view_files)
2599
 
                note("Ignoring files outside view. View is %s" % view_str)
 
2893
                note(gettext("Ignoring files outside view. View is %s") % view_str)
2600
2894
 
2601
2895
        self.add_cleanup(tree.lock_read().unlock)
2602
2896
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2726
3020
            bzr ignore "RE:(?!debian/).*"
2727
3021
        
2728
3022
        Ignore everything except the "local" toplevel directory,
2729
 
        but always ignore "*~" autosave files, even under local/::
 
3023
        but always ignore autosave files ending in ~, even under local/::
2730
3024
        
2731
3025
            bzr ignore "*"
2732
3026
            bzr ignore "!./local"
2749
3043
                self.outf.write("%s\n" % pattern)
2750
3044
            return
2751
3045
        if not name_pattern_list:
2752
 
            raise errors.BzrCommandError("ignore requires at least one "
2753
 
                "NAME_PATTERN or --default-rules.")
 
3046
            raise errors.BzrCommandError(gettext("ignore requires at least one "
 
3047
                "NAME_PATTERN or --default-rules."))
2754
3048
        name_pattern_list = [globbing.normalize_pattern(p)
2755
3049
                             for p in name_pattern_list]
2756
3050
        bad_patterns = ''
 
3051
        bad_patterns_count = 0
2757
3052
        for p in name_pattern_list:
2758
3053
            if not globbing.Globster.is_pattern_valid(p):
 
3054
                bad_patterns_count += 1
2759
3055
                bad_patterns += ('\n  %s' % p)
2760
3056
        if bad_patterns:
2761
 
            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)
2762
3060
            ui.ui_factory.show_error(msg)
2763
3061
            raise errors.InvalidPattern('')
2764
3062
        for name_pattern in name_pattern_list:
2765
3063
            if (name_pattern[0] == '/' or
2766
3064
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
2767
 
                raise errors.BzrCommandError(
2768
 
                    "NAME_PATTERN should not be an absolute path")
 
3065
                raise errors.BzrCommandError(gettext(
 
3066
                    "NAME_PATTERN should not be an absolute path"))
2769
3067
        tree, relpath = WorkingTree.open_containing(directory)
2770
3068
        ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2771
3069
        ignored = globbing.Globster(name_pattern_list)
2778
3076
                if ignored.match(filename):
2779
3077
                    matches.append(filename)
2780
3078
        if len(matches) > 0:
2781
 
            self.outf.write("Warning: the following files are version controlled and"
2782
 
                  " 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"
2783
3081
                  "\nThese files will continue to be version controlled"
2784
 
                  " unless you 'bzr remove' them.\n" % ("\n".join(matches),))
 
3082
                  " unless you 'bzr remove' them.\n") % ("\n".join(matches),))
2785
3083
 
2786
3084
 
2787
3085
class cmd_ignored(Command):
2826
3124
        try:
2827
3125
            revno = int(revno)
2828
3126
        except ValueError:
2829
 
            raise errors.BzrCommandError("not a valid revision-number: %r"
 
3127
            raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
2830
3128
                                         % revno)
2831
3129
        revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2832
3130
        self.outf.write("%s\n" % revid)
2860
3158
         zip                          .zip
2861
3159
      =================       =========================
2862
3160
    """
 
3161
    encoding = 'exact'
2863
3162
    takes_args = ['dest', 'branch_or_subdir?']
2864
3163
    takes_options = ['directory',
2865
3164
        Option('format',
2874
3173
        Option('per-file-timestamps',
2875
3174
               help='Set modification time of files to that of the last '
2876
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.'),
2877
3179
        ]
2878
3180
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2879
 
        root=None, filters=False, per_file_timestamps=False, directory=u'.'):
 
3181
        root=None, filters=False, per_file_timestamps=False, uncommitted=False,
 
3182
        directory=u'.'):
2880
3183
        from bzrlib.export import export
2881
3184
 
2882
3185
        if branch_or_subdir is None:
2883
 
            tree = WorkingTree.open_containing(directory)[0]
2884
 
            b = tree.branch
2885
 
            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
2886
3198
        else:
2887
 
            b, subdir = Branch.open_containing(branch_or_subdir)
2888
 
            tree = None
2889
 
 
2890
 
        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)
2891
3200
        try:
2892
 
            export(rev_tree, dest, format, root, subdir, filtered=filters,
 
3201
            export(export_tree, dest, format, root, subdir, filtered=filters,
2893
3202
                   per_file_timestamps=per_file_timestamps)
2894
3203
        except errors.NoSuchExportFormat, e:
2895
 
            raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
 
3204
            raise errors.BzrCommandError(
 
3205
                gettext('Unsupported export format: %s') % e.format)
2896
3206
 
2897
3207
 
2898
3208
class cmd_cat(Command):
2918
3228
    def run(self, filename, revision=None, name_from_revision=False,
2919
3229
            filters=False, directory=None):
2920
3230
        if revision is not None and len(revision) != 1:
2921
 
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
2922
 
                                         " one revision specifier")
 
3231
            raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
 
3232
                                         " one revision specifier"))
2923
3233
        tree, branch, relpath = \
2924
3234
            _open_directory_or_containing_tree_or_branch(filename, directory)
2925
3235
        self.add_cleanup(branch.lock_read().unlock)
2935
3245
 
2936
3246
        old_file_id = rev_tree.path2id(relpath)
2937
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.
2938
3252
        if name_from_revision:
2939
3253
            # Try in revision if requested
2940
3254
            if old_file_id is None:
2941
 
                raise errors.BzrCommandError(
2942
 
                    "%r is not present in revision %s" % (
 
3255
                raise errors.BzrCommandError(gettext(
 
3256
                    "{0!r} is not present in revision {1}").format(
2943
3257
                        filename, rev_tree.get_revision_id()))
2944
3258
            else:
2945
 
                content = rev_tree.get_file_text(old_file_id)
 
3259
                actual_file_id = old_file_id
2946
3260
        else:
2947
3261
            cur_file_id = tree.path2id(relpath)
2948
 
            found = False
2949
 
            if cur_file_id is not None:
2950
 
                # Then try with the actual file id
2951
 
                try:
2952
 
                    content = rev_tree.get_file_text(cur_file_id)
2953
 
                    found = True
2954
 
                except errors.NoSuchId:
2955
 
                    # The actual file id didn't exist at that time
2956
 
                    pass
2957
 
            if not found and old_file_id is not None:
2958
 
                # Finally try with the old file id
2959
 
                content = rev_tree.get_file_text(old_file_id)
2960
 
                found = True
2961
 
            if not found:
2962
 
                # Can't be found anywhere
2963
 
                raise errors.BzrCommandError(
2964
 
                    "%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(
2965
3269
                        filename, rev_tree.get_revision_id()))
2966
3270
        if filtered:
2967
 
            from bzrlib.filters import (
2968
 
                ContentFilterContext,
2969
 
                filtered_output_bytes,
2970
 
                )
2971
 
            filters = rev_tree._content_filter_stack(relpath)
2972
 
            chunks = content.splitlines(True)
2973
 
            content = filtered_output_bytes(chunks, filters,
2974
 
                ContentFilterContext(relpath, rev_tree))
2975
 
            self.cleanup_now()
2976
 
            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)
2977
3275
        else:
2978
 
            self.cleanup_now()
2979
 
            self.outf.write(content)
 
3276
            content = rev_tree.get_file_text(actual_file_id)
 
3277
        self.cleanup_now()
 
3278
        self.outf.write(content)
2980
3279
 
2981
3280
 
2982
3281
class cmd_local_time_offset(Command):
3043
3342
      to trigger updates to external systems like bug trackers. The --fixes
3044
3343
      option can be used to record the association between a revision and
3045
3344
      one or more bugs. See ``bzr help bugs`` for details.
3046
 
 
3047
 
      A selective commit may fail in some cases where the committed
3048
 
      tree would be invalid. Consider::
3049
 
  
3050
 
        bzr init foo
3051
 
        mkdir foo/bar
3052
 
        bzr add foo/bar
3053
 
        bzr commit foo -m "committing foo"
3054
 
        bzr mv foo/bar foo/baz
3055
 
        mkdir foo/bar
3056
 
        bzr add foo/bar
3057
 
        bzr commit foo/bar -m "committing bar but not baz"
3058
 
  
3059
 
      In the example above, the last commit will fail by design. This gives
3060
 
      the user the opportunity to decide whether they want to commit the
3061
 
      rename at the same time, separately first, or not at all. (As a general
3062
 
      rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
3063
3345
    """
3064
 
    # TODO: Run hooks on tree to-be-committed, and after commit.
3065
 
 
3066
 
    # TODO: Strict commit that fails if there are deleted files.
3067
 
    #       (what does "deleted files" mean ??)
3068
 
 
3069
 
    # TODO: Give better message for -s, --summary, used by tla people
3070
 
 
3071
 
    # XXX: verbose currently does nothing
3072
3346
 
3073
3347
    _see_also = ['add', 'bugs', 'hooks', 'uncommit']
3074
3348
    takes_args = ['selected*']
3106
3380
             Option('show-diff', short_name='p',
3107
3381
                    help='When no message is supplied, show the diff along'
3108
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.'),
3109
3387
             ]
3110
3388
    aliases = ['ci', 'checkin']
3111
3389
 
3112
3390
    def _iter_bug_fix_urls(self, fixes, branch):
 
3391
        default_bugtracker  = None
3113
3392
        # Configure the properties for bug fixing attributes.
3114
3393
        for fixed_bug in fixes:
3115
3394
            tokens = fixed_bug.split(':')
3116
 
            if len(tokens) != 2:
3117
 
                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(
3118
3411
                    "Invalid bug %s. Must be in the form of 'tracker:id'. "
3119
3412
                    "See \"bzr help bugs\" for more information on this "
3120
 
                    "feature.\nCommit refused." % fixed_bug)
3121
 
            tag, bug_id = tokens
 
3413
                    "feature.\nCommit refused.") % fixed_bug)
 
3414
            else:
 
3415
                tag, bug_id = tokens
3122
3416
            try:
3123
3417
                yield bugtracker.get_bug_url(tag, branch, bug_id)
3124
3418
            except errors.UnknownBugTrackerAbbreviation:
3125
 
                raise errors.BzrCommandError(
3126
 
                    'Unrecognized bug %s. Commit refused.' % fixed_bug)
 
3419
                raise errors.BzrCommandError(gettext(
 
3420
                    'Unrecognized bug %s. Commit refused.') % fixed_bug)
3127
3421
            except errors.MalformedBugIdentifier, e:
3128
 
                raise errors.BzrCommandError(
3129
 
                    "%s\nCommit refused." % (str(e),))
 
3422
                raise errors.BzrCommandError(gettext(
 
3423
                    "%s\nCommit refused.") % (str(e),))
3130
3424
 
3131
3425
    def run(self, message=None, file=None, verbose=False, selected_list=None,
3132
3426
            unchanged=False, strict=False, local=False, fixes=None,
3133
 
            author=None, show_diff=False, exclude=None, commit_time=None):
 
3427
            author=None, show_diff=False, exclude=None, commit_time=None,
 
3428
            lossy=False):
3134
3429
        from bzrlib.errors import (
3135
3430
            PointlessCommit,
3136
3431
            ConflictsInTree,
3139
3434
        from bzrlib.msgeditor import (
3140
3435
            edit_commit_message_encoded,
3141
3436
            generate_commit_message_template,
3142
 
            make_commit_message_template_encoded
 
3437
            make_commit_message_template_encoded,
 
3438
            set_commit_message,
3143
3439
        )
3144
3440
 
3145
3441
        commit_stamp = offset = None
3147
3443
            try:
3148
3444
                commit_stamp, offset = timestamp.parse_patch_date(commit_time)
3149
3445
            except ValueError, e:
3150
 
                raise errors.BzrCommandError(
3151
 
                    "Could not parse --commit-time: " + str(e))
3152
 
 
3153
 
        # TODO: Need a blackbox test for invoking the external editor; may be
3154
 
        # slightly problematic to run this cross-platform.
3155
 
 
3156
 
        # TODO: do more checks that the commit will succeed before
3157
 
        # spending the user's valuable time typing a commit message.
 
3446
                raise errors.BzrCommandError(gettext(
 
3447
                    "Could not parse --commit-time: " + str(e)))
3158
3448
 
3159
3449
        properties = {}
3160
3450
 
3193
3483
                message = message.replace('\r\n', '\n')
3194
3484
                message = message.replace('\r', '\n')
3195
3485
            if file:
3196
 
                raise errors.BzrCommandError(
3197
 
                    "please specify either --message or --file")
 
3486
                raise errors.BzrCommandError(gettext(
 
3487
                    "please specify either --message or --file"))
3198
3488
 
3199
3489
        def get_message(commit_obj):
3200
3490
            """Callback to get commit message"""
3217
3507
                # make_commit_message_template_encoded returns user encoding.
3218
3508
                # We probably want to be using edit_commit_message instead to
3219
3509
                # avoid this.
3220
 
                start_message = generate_commit_message_template(commit_obj)
3221
 
                my_message = edit_commit_message_encoded(text,
3222
 
                    start_message=start_message)
3223
 
                if my_message is None:
3224
 
                    raise errors.BzrCommandError("please specify a commit"
3225
 
                        " message with either --message or --file")
3226
 
            if my_message == "":
3227
 
                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 \"\"."))
3228
3523
            return my_message
3229
3524
 
3230
3525
        # The API permits a commit with a filter of [] to mean 'select nothing'
3238
3533
                        reporter=None, verbose=verbose, revprops=properties,
3239
3534
                        authors=author, timestamp=commit_stamp,
3240
3535
                        timezone=offset,
3241
 
                        exclude=tree.safe_relpath_files(exclude))
 
3536
                        exclude=tree.safe_relpath_files(exclude),
 
3537
                        lossy=lossy)
3242
3538
        except PointlessCommit:
3243
 
            raise errors.BzrCommandError("No changes to commit."
3244
 
                              " 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."))
3245
3542
        except ConflictsInTree:
3246
 
            raise errors.BzrCommandError('Conflicts detected in working '
 
3543
            raise errors.BzrCommandError(gettext('Conflicts detected in working '
3247
3544
                'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
3248
 
                ' resolve.')
 
3545
                ' resolve.'))
3249
3546
        except StrictCommitFailed:
3250
 
            raise errors.BzrCommandError("Commit refused because there are"
3251
 
                              " unknown files in the working tree.")
 
3547
            raise errors.BzrCommandError(gettext("Commit refused because there are"
 
3548
                              " unknown files in the working tree."))
3252
3549
        except errors.BoundBranchOutOfDate, e:
3253
 
            e.extra_help = ("\n"
 
3550
            e.extra_help = (gettext("\n"
3254
3551
                'To commit to master branch, run update and then commit.\n'
3255
3552
                'You can also pass --local to commit to continue working '
3256
 
                'disconnected.')
 
3553
                'disconnected.'))
3257
3554
            raise
3258
3555
 
3259
3556
 
3328
3625
 
3329
3626
 
3330
3627
class cmd_upgrade(Command):
3331
 
    __doc__ = """Upgrade branch storage to current format.
3332
 
 
3333
 
    The check command or bzr developers may sometimes advise you to run
3334
 
    this command. When the default format has changed you may also be warned
3335
 
    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/.
3336
3658
    """
3337
3659
 
3338
 
    _see_also = ['check']
 
3660
    _see_also = ['check', 'reconcile', 'formats']
3339
3661
    takes_args = ['url?']
3340
3662
    takes_options = [
3341
 
                    RegistryOption('format',
3342
 
                        help='Upgrade to a specific format.  See "bzr help'
3343
 
                             ' formats" for details.',
3344
 
                        lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3345
 
                        converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3346
 
                        value_switches=True, title='Branch format'),
3347
 
                    ]
 
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
    ]
3348
3674
 
3349
 
    def run(self, url='.', format=None):
 
3675
    def run(self, url='.', format=None, clean=False, dry_run=False):
3350
3676
        from bzrlib.upgrade import upgrade
3351
 
        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
3352
3684
 
3353
3685
 
3354
3686
class cmd_whoami(Command):
3379
3711
            if directory is None:
3380
3712
                # use branch if we're inside one; otherwise global config
3381
3713
                try:
3382
 
                    c = Branch.open_containing(u'.')[0].get_config()
 
3714
                    c = Branch.open_containing(u'.')[0].get_config_stack()
3383
3715
                except errors.NotBranchError:
3384
 
                    c = _mod_config.GlobalConfig()
 
3716
                    c = _mod_config.GlobalStack()
3385
3717
            else:
3386
 
                c = Branch.open(directory).get_config()
 
3718
                c = Branch.open(directory).get_config_stack()
 
3719
            identity = c.get('email')
3387
3720
            if email:
3388
 
                self.outf.write(c.user_email() + '\n')
 
3721
                self.outf.write(_mod_config.extract_email_address(identity)
 
3722
                                + '\n')
3389
3723
            else:
3390
 
                self.outf.write(c.username() + '\n')
 
3724
                self.outf.write(identity + '\n')
3391
3725
            return
3392
3726
 
 
3727
        if email:
 
3728
            raise errors.BzrCommandError(gettext("--email can only be used to display existing "
 
3729
                                         "identity"))
 
3730
 
3393
3731
        # display a warning if an email address isn't included in the given name.
3394
3732
        try:
3395
3733
            _mod_config.extract_email_address(name)
3400
3738
        # use global config unless --branch given
3401
3739
        if branch:
3402
3740
            if directory is None:
3403
 
                c = Branch.open_containing(u'.')[0].get_config()
 
3741
                c = Branch.open_containing(u'.')[0].get_config_stack()
3404
3742
            else:
3405
 
                c = Branch.open(directory).get_config()
 
3743
                c = Branch.open(directory).get_config_stack()
3406
3744
        else:
3407
 
            c = _mod_config.GlobalConfig()
3408
 
        c.set_user_option('email', name)
 
3745
            c = _mod_config.GlobalStack()
 
3746
        c.set('email', name)
3409
3747
 
3410
3748
 
3411
3749
class cmd_nick(Command):
3473
3811
 
3474
3812
    def remove_alias(self, alias_name):
3475
3813
        if alias_name is None:
3476
 
            raise errors.BzrCommandError(
3477
 
                'bzr alias --remove expects an alias to remove.')
 
3814
            raise errors.BzrCommandError(gettext(
 
3815
                'bzr alias --remove expects an alias to remove.'))
3478
3816
        # If alias is not found, print something like:
3479
3817
        # unalias: foo: not found
3480
3818
        c = _mod_config.GlobalConfig()
3559
3897
        if typestring == "sftp":
3560
3898
            from bzrlib.tests import stub_sftp
3561
3899
            return stub_sftp.SFTPAbsoluteServer
3562
 
        if typestring == "memory":
 
3900
        elif typestring == "memory":
3563
3901
            from bzrlib.tests import test_server
3564
3902
            return memory.MemoryServer
3565
 
        if typestring == "fakenfs":
 
3903
        elif typestring == "fakenfs":
3566
3904
            from bzrlib.tests import test_server
3567
3905
            return test_server.FakeNFSServer
3568
3906
        msg = "No known transport type %s. Supported types are: sftp\n" %\
3602
3940
                     Option('randomize', type=str, argname="SEED",
3603
3941
                            help='Randomize the order of tests using the given'
3604
3942
                                 ' seed or "now" for the current time.'),
3605
 
                     Option('exclude', type=str, argname="PATTERN",
3606
 
                            short_name='x',
3607
 
                            help='Exclude tests that match this regular'
3608
 
                                 ' expression.'),
 
3943
                     ListOption('exclude', type=str, argname="PATTERN",
 
3944
                                short_name='x',
 
3945
                                help='Exclude tests that match this regular'
 
3946
                                ' expression.'),
3609
3947
                     Option('subunit',
3610
3948
                        help='Output test progress via subunit.'),
3611
3949
                     Option('strict', help='Fail on missing dependencies or '
3618
3956
                                param_name='starting_with', short_name='s',
3619
3957
                                help=
3620
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.")
3621
3962
                     ]
3622
3963
    encoding_type = 'replace'
3623
3964
 
3631
3972
            first=False, list_only=False,
3632
3973
            randomize=None, exclude=None, strict=False,
3633
3974
            load_list=None, debugflag=None, starting_with=None, subunit=False,
3634
 
            parallel=None, lsprof_tests=False):
 
3975
            parallel=None, lsprof_tests=False,
 
3976
            sync=False):
3635
3977
        from bzrlib import tests
3636
3978
 
3637
3979
        if testspecs_list is not None:
3642
3984
            try:
3643
3985
                from bzrlib.tests import SubUnitBzrRunner
3644
3986
            except ImportError:
3645
 
                raise errors.BzrCommandError("subunit not available. subunit "
3646
 
                    "needs to be installed to use --subunit.")
 
3987
                raise errors.BzrCommandError(gettext("subunit not available. subunit "
 
3988
                    "needs to be installed to use --subunit."))
3647
3989
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3648
3990
            # On Windows, disable automatic conversion of '\n' to '\r\n' in
3649
3991
            # stdout, which would corrupt the subunit stream. 
3658
4000
            self.additional_selftest_args.setdefault(
3659
4001
                'suite_decorators', []).append(parallel)
3660
4002
        if benchmark:
3661
 
            raise errors.BzrCommandError(
 
4003
            raise errors.BzrCommandError(gettext(
3662
4004
                "--benchmark is no longer supported from bzr 2.2; "
3663
 
                "use bzr-usertest instead")
 
4005
                "use bzr-usertest instead"))
3664
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()
3665
4013
        selftest_kwargs = {"verbose": verbose,
3666
4014
                          "pattern": pattern,
3667
4015
                          "stop_on_failure": one,
3672
4020
                          "matching_tests_first": first,
3673
4021
                          "list_only": list_only,
3674
4022
                          "random_seed": randomize,
3675
 
                          "exclude_pattern": exclude,
 
4023
                          "exclude_pattern": exclude_pattern,
3676
4024
                          "strict": strict,
3677
4025
                          "load_list": load_list,
3678
4026
                          "debug_flags": debugflag,
3689
4037
            cleanup()
3690
4038
        return int(not result)
3691
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
 
3692
4049
 
3693
4050
class cmd_version(Command):
3694
4051
    __doc__ = """Show version of bzr."""
3714
4071
 
3715
4072
    @display_command
3716
4073
    def run(self):
3717
 
        self.outf.write("It sure does!\n")
 
4074
        self.outf.write(gettext("It sure does!\n"))
3718
4075
 
3719
4076
 
3720
4077
class cmd_find_merge_base(Command):
3738
4095
        graph = branch1.repository.get_graph(branch2.repository)
3739
4096
        base_rev_id = graph.find_unique_lca(last1, last2)
3740
4097
 
3741
 
        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)
3742
4099
 
3743
4100
 
3744
4101
class cmd_merge(Command):
3747
4104
    The source of the merge can be specified either in the form of a branch,
3748
4105
    or in the form of a path to a file containing a merge directive generated
3749
4106
    with bzr send. If neither is specified, the default is the upstream branch
3750
 
    or the branch most recently merged using --remember.
3751
 
 
3752
 
    When merging a branch, by default the tip will be merged. To pick a different
3753
 
    revision, pass --revision. If you specify two values, the first will be used as
3754
 
    BASE and the second one as OTHER. Merging individual revisions, or a subset of
3755
 
    available revisions, like this is commonly referred to as "cherrypicking".
3756
 
 
3757
 
    Revision numbers are always relative to the branch being merged.
3758
 
 
3759
 
    By default, bzr will try to merge in all new work from the other
3760
 
    branch, automatically determining an appropriate base.  If this
3761
 
    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.
3762
4128
 
3763
4129
    Merge will do its best to combine the changes in two branches, but there
3764
4130
    are some kinds of problems only a human can fix.  When it encounters those,
3767
4133
 
3768
4134
    Use bzr resolve when you have fixed a problem.  See also bzr conflicts.
3769
4135
 
3770
 
    If there is no default branch set, the first merge will set it. After
3771
 
    that, you can omit the branch to use the default.  To change the
3772
 
    default, use --remember. The value will only be saved if the remote
3773
 
    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.
3774
4140
 
3775
4141
    The results of the merge are placed into the destination working
3776
4142
    directory, where they can be reviewed (with bzr diff), tested, and then
3777
4143
    committed to record the result of the merge.
3778
4144
 
3779
4145
    merge refuses to run if there are any uncommitted changes, unless
3780
 
    --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
3781
4149
    merge revision which has more than two parents.
3782
4150
 
3783
4151
    If one would like to merge changes from the working tree of the other
3788
4156
    you to apply each diff hunk and file change, similar to "shelve".
3789
4157
 
3790
4158
    :Examples:
3791
 
        To merge the latest revision from bzr.dev::
 
4159
        To merge all new revisions from bzr.dev::
3792
4160
 
3793
4161
            bzr merge ../bzr.dev
3794
4162
 
3841
4209
    ]
3842
4210
 
3843
4211
    def run(self, location=None, revision=None, force=False,
3844
 
            merge_type=None, show_base=False, reprocess=None, remember=False,
 
4212
            merge_type=None, show_base=False, reprocess=None, remember=None,
3845
4213
            uncommitted=False, pull=False,
3846
4214
            directory=None,
3847
4215
            preview=False,
3855
4223
        merger = None
3856
4224
        allow_pending = True
3857
4225
        verified = 'inapplicable'
 
4226
 
3858
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'))
3859
4231
 
3860
4232
        try:
3861
4233
            basis_tree = tree.revision_tree(tree.last_revision())
3881
4253
                mergeable = None
3882
4254
            else:
3883
4255
                if uncommitted:
3884
 
                    raise errors.BzrCommandError('Cannot use --uncommitted'
3885
 
                        ' with bundles or merge directives.')
 
4256
                    raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
 
4257
                        ' with bundles or merge directives.'))
3886
4258
 
3887
4259
                if revision is not None:
3888
 
                    raise errors.BzrCommandError(
3889
 
                        'Cannot use -r with merge directives or bundles')
 
4260
                    raise errors.BzrCommandError(gettext(
 
4261
                        'Cannot use -r with merge directives or bundles'))
3890
4262
                merger, verified = _mod_merge.Merger.from_mergeable(tree,
3891
4263
                   mergeable, None)
3892
4264
 
3893
4265
        if merger is None and uncommitted:
3894
4266
            if revision is not None and len(revision) > 0:
3895
 
                raise errors.BzrCommandError('Cannot use --uncommitted and'
3896
 
                    ' --revision at the same time.')
 
4267
                raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
 
4268
                    ' --revision at the same time.'))
3897
4269
            merger = self.get_merger_from_uncommitted(tree, location, None)
3898
4270
            allow_pending = False
3899
4271
 
3907
4279
        self.sanity_check_merger(merger)
3908
4280
        if (merger.base_rev_id == merger.other_rev_id and
3909
4281
            merger.other_rev_id is not None):
3910
 
            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.'))
3911
4290
            return 0
3912
 
        if pull:
 
4291
        if pull and not preview:
3913
4292
            if merger.interesting_files is not None:
3914
 
                raise errors.BzrCommandError('Cannot pull individual files')
 
4293
                raise errors.BzrCommandError(gettext('Cannot pull individual files'))
3915
4294
            if (merger.base_rev_id == tree.last_revision()):
3916
4295
                result = tree.pull(merger.other_branch, False,
3917
4296
                                   merger.other_rev_id)
3918
4297
                result.report(self.outf)
3919
4298
                return 0
3920
4299
        if merger.this_basis is None:
3921
 
            raise errors.BzrCommandError(
 
4300
            raise errors.BzrCommandError(gettext(
3922
4301
                "This branch has no commits."
3923
 
                " (perhaps you would prefer 'bzr pull')")
 
4302
                " (perhaps you would prefer 'bzr pull')"))
3924
4303
        if preview:
3925
4304
            return self._do_preview(merger)
3926
4305
        elif interactive:
3977
4356
    def sanity_check_merger(self, merger):
3978
4357
        if (merger.show_base and
3979
4358
            not merger.merge_type is _mod_merge.Merge3Merger):
3980
 
            raise errors.BzrCommandError("Show-base is not supported for this"
3981
 
                                         " 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)
3982
4361
        if merger.reprocess is None:
3983
4362
            if merger.show_base:
3984
4363
                merger.reprocess = False
3986
4365
                # Use reprocess if the merger supports it
3987
4366
                merger.reprocess = merger.merge_type.supports_reprocess
3988
4367
        if merger.reprocess and not merger.merge_type.supports_reprocess:
3989
 
            raise errors.BzrCommandError("Conflict reduction is not supported"
3990
 
                                         " for merge type %s." %
 
4368
            raise errors.BzrCommandError(gettext("Conflict reduction is not supported"
 
4369
                                         " for merge type %s.") %
3991
4370
                                         merger.merge_type)
3992
4371
        if merger.reprocess and merger.show_base:
3993
 
            raise errors.BzrCommandError("Cannot do conflict reduction and"
3994
 
                                         " show base.")
 
4372
            raise errors.BzrCommandError(gettext("Cannot do conflict reduction and"
 
4373
                                         " show base."))
3995
4374
 
3996
4375
    def _get_merger_from_branch(self, tree, location, revision, remember,
3997
4376
                                possible_transports, pb):
4024
4403
        if other_revision_id is None:
4025
4404
            other_revision_id = _mod_revision.ensure_null(
4026
4405
                other_branch.last_revision())
4027
 
        # Remember where we merge from
4028
 
        if ((remember or tree.branch.get_submit_branch() is None) and
4029
 
             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)))):
4030
4415
            tree.branch.set_submit_branch(other_branch.base)
4031
 
        _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)
4032
4419
        merger = _mod_merge.Merger.from_revision_ids(pb, tree,
4033
4420
            other_revision_id, base_revision_id, other_branch, base_branch)
4034
4421
        if other_path != '':
4093
4480
            stored_location_type = "parent"
4094
4481
        mutter("%s", stored_location)
4095
4482
        if stored_location is None:
4096
 
            raise errors.BzrCommandError("No location specified or remembered")
 
4483
            raise errors.BzrCommandError(gettext("No location specified or remembered"))
4097
4484
        display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4098
 
        note(u"%s remembered %s location %s", verb_string,
4099
 
                stored_location_type, display_url)
 
4485
        note(gettext("{0} remembered {1} location {2}").format(verb_string,
 
4486
                stored_location_type, display_url))
4100
4487
        return stored_location
4101
4488
 
4102
4489
 
4139
4526
        self.add_cleanup(tree.lock_write().unlock)
4140
4527
        parents = tree.get_parent_ids()
4141
4528
        if len(parents) != 2:
4142
 
            raise errors.BzrCommandError("Sorry, remerge only works after normal"
 
4529
            raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4143
4530
                                         " merges.  Not cherrypicking or"
4144
 
                                         " multi-merges.")
 
4531
                                         " multi-merges."))
4145
4532
        repository = tree.branch.repository
4146
4533
        interesting_ids = None
4147
4534
        new_conflicts = []
4202
4589
    last committed revision is used.
4203
4590
 
4204
4591
    To remove only some changes, without reverting to a prior version, use
4205
 
    merge instead.  For example, "merge . --revision -2..-3" will remove the
4206
 
    changes introduced by -2, without affecting the changes introduced by -1.
4207
 
    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.
4208
4596
 
4209
4597
    By default, any files that have been manually changed will be backed up
4210
4598
    first.  (Files changed only by merge are not backed up.)  Backup files have
4240
4628
    target branches.
4241
4629
    """
4242
4630
 
4243
 
    _see_also = ['cat', 'export']
 
4631
    _see_also = ['cat', 'export', 'merge', 'shelve']
4244
4632
    takes_options = [
4245
4633
        'revision',
4246
4634
        Option('no-backup', "Do not save backups of reverted files."),
4365
4753
            type=_parse_revision_str,
4366
4754
            help='Filter on local branch revisions (inclusive). '
4367
4755
                'See "help revisionspec" for details.'),
4368
 
        Option('include-merges',
 
4756
        Option('include-merged',
4369
4757
               'Show all revisions in addition to the mainline ones.'),
 
4758
        Option('include-merges', hidden=True,
 
4759
               help='Historical alias for --include-merged.'),
4370
4760
        ]
4371
4761
    encoding_type = 'replace'
4372
4762
 
4375
4765
            theirs_only=False,
4376
4766
            log_format=None, long=False, short=False, line=False,
4377
4767
            show_ids=False, verbose=False, this=False, other=False,
4378
 
            include_merges=False, revision=None, my_revision=None,
4379
 
            directory=u'.'):
 
4768
            include_merged=None, revision=None, my_revision=None,
 
4769
            directory=u'.',
 
4770
            include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4380
4771
        from bzrlib.missing import find_unmerged, iter_log_revisions
4381
4772
        def message(s):
4382
4773
            if not is_quiet():
4383
4774
                self.outf.write(s)
4384
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
4385
4791
        if this:
4386
4792
            mine_only = this
4387
4793
        if other:
4402
4808
        if other_branch is None:
4403
4809
            other_branch = parent
4404
4810
            if other_branch is None:
4405
 
                raise errors.BzrCommandError("No peer location known"
4406
 
                                             " or specified.")
 
4811
                raise errors.BzrCommandError(gettext("No peer location known"
 
4812
                                             " or specified."))
4407
4813
            display_url = urlutils.unescape_for_display(parent,
4408
4814
                                                        self.outf.encoding)
4409
 
            message("Using saved parent location: "
4410
 
                    + display_url + "\n")
 
4815
            message(gettext("Using saved parent location: {0}\n").format(
 
4816
                    display_url))
4411
4817
 
4412
4818
        remote_branch = Branch.open(other_branch)
4413
4819
        if remote_branch.base == local_branch.base:
4426
4832
        local_extra, remote_extra = find_unmerged(
4427
4833
            local_branch, remote_branch, restrict,
4428
4834
            backward=not reverse,
4429
 
            include_merges=include_merges,
 
4835
            include_merged=include_merged,
4430
4836
            local_revid_range=local_revid_range,
4431
4837
            remote_revid_range=remote_revid_range)
4432
4838
 
4439
4845
 
4440
4846
        status_code = 0
4441
4847
        if local_extra and not theirs_only:
4442
 
            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)) %
4443
4851
                len(local_extra))
4444
4852
            for revision in iter_log_revisions(local_extra,
4445
4853
                                local_branch.repository,
4453
4861
        if remote_extra and not mine_only:
4454
4862
            if printed_local is True:
4455
4863
                message("\n\n\n")
4456
 
            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)) %
4457
4867
                len(remote_extra))
4458
4868
            for revision in iter_log_revisions(remote_extra,
4459
4869
                                remote_branch.repository,
4463
4873
 
4464
4874
        if mine_only and not local_extra:
4465
4875
            # We checked local, and found nothing extra
4466
 
            message('This branch is up to date.\n')
 
4876
            message(gettext('This branch has no new revisions.\n'))
4467
4877
        elif theirs_only and not remote_extra:
4468
4878
            # We checked remote, and found nothing extra
4469
 
            message('Other branch is up to date.\n')
 
4879
            message(gettext('Other branch has no new revisions.\n'))
4470
4880
        elif not (mine_only or theirs_only or local_extra or
4471
4881
                  remote_extra):
4472
4882
            # We checked both branches, and neither one had extra
4473
4883
            # revisions
4474
 
            message("Branches are up to date.\n")
 
4884
            message(gettext("Branches are up to date.\n"))
4475
4885
        self.cleanup_now()
4476
4886
        if not status_code and parent is None and other_branch is not None:
4477
4887
            self.add_cleanup(local_branch.lock_write().unlock)
4507
4917
        ]
4508
4918
 
4509
4919
    def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4510
 
        dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
 
4920
        dir = controldir.ControlDir.open_containing(branch_or_repo)[0]
4511
4921
        try:
4512
4922
            branch = dir.open_branch()
4513
4923
            repository = branch.repository
4539
4949
 
4540
4950
    @display_command
4541
4951
    def run(self, verbose=False):
4542
 
        import bzrlib.plugin
4543
 
        from inspect import getdoc
4544
 
        result = []
4545
 
        for name, plugin in bzrlib.plugin.plugins().items():
4546
 
            version = plugin.__version__
4547
 
            if version == 'unknown':
4548
 
                version = ''
4549
 
            name_ver = '%s %s' % (name, version)
4550
 
            d = getdoc(plugin.module)
4551
 
            if d:
4552
 
                doc = d.split('\n')[0]
4553
 
            else:
4554
 
                doc = '(no description)'
4555
 
            result.append((name_ver, doc, plugin.path()))
4556
 
        for name_ver, doc, path in sorted(result):
4557
 
            self.outf.write("%s\n" % name_ver)
4558
 
            self.outf.write("   %s\n" % doc)
4559
 
            if verbose:
4560
 
                self.outf.write("   %s\n" % path)
4561
 
            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)))
4562
4956
 
4563
4957
 
4564
4958
class cmd_testament(Command):
4617
5011
    @display_command
4618
5012
    def run(self, filename, all=False, long=False, revision=None,
4619
5013
            show_ids=False, directory=None):
4620
 
        from bzrlib.annotate import annotate_file, annotate_file_tree
 
5014
        from bzrlib.annotate import (
 
5015
            annotate_file_tree,
 
5016
            )
4621
5017
        wt, branch, relpath = \
4622
5018
            _open_directory_or_containing_tree_or_branch(filename, directory)
4623
5019
        if wt is not None:
4626
5022
            self.add_cleanup(branch.lock_read().unlock)
4627
5023
        tree = _get_one_revision_tree('annotate', revision, branch=branch)
4628
5024
        self.add_cleanup(tree.lock_read().unlock)
4629
 
        if wt is not None:
 
5025
        if wt is not None and revision is None:
4630
5026
            file_id = wt.path2id(relpath)
4631
5027
        else:
4632
5028
            file_id = tree.path2id(relpath)
4633
5029
        if file_id is None:
4634
5030
            raise errors.NotVersionedError(filename)
4635
 
        file_version = tree.inventory[file_id].revision
4636
5031
        if wt is not None and revision is None:
4637
5032
            # If there is a tree and we're not annotating historical
4638
5033
            # versions, annotate the working tree's content.
4639
5034
            annotate_file_tree(wt, file_id, self.outf, long, all,
4640
5035
                show_ids=show_ids)
4641
5036
        else:
4642
 
            annotate_file(branch, file_version, file_id, long, all, self.outf,
4643
 
                          show_ids=show_ids)
 
5037
            annotate_file_tree(tree, file_id, self.outf, long, all,
 
5038
                show_ids=show_ids, branch=branch)
4644
5039
 
4645
5040
 
4646
5041
class cmd_re_sign(Command):
4653
5048
 
4654
5049
    def run(self, revision_id_list=None, revision=None, directory=u'.'):
4655
5050
        if revision_id_list is not None and revision is not None:
4656
 
            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'))
4657
5052
        if revision_id_list is None and revision is None:
4658
 
            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'))
4659
5054
        b = WorkingTree.open_containing(directory)[0].branch
4660
5055
        self.add_cleanup(b.lock_write().unlock)
4661
5056
        return self._run(b, revision_id_list, revision)
4662
5057
 
4663
5058
    def _run(self, b, revision_id_list, revision):
4664
5059
        import bzrlib.gpg as gpg
4665
 
        gpg_strategy = gpg.GPGStrategy(b.get_config())
 
5060
        gpg_strategy = gpg.GPGStrategy(b.get_config_stack())
4666
5061
        if revision_id_list is not None:
4667
5062
            b.repository.start_write_group()
4668
5063
            try:
4693
5088
                if to_revid is None:
4694
5089
                    to_revno = b.revno()
4695
5090
                if from_revno is None or to_revno is None:
4696
 
                    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'))
4697
5092
                b.repository.start_write_group()
4698
5093
                try:
4699
5094
                    for revno in range(from_revno, to_revno + 1):
4705
5100
                else:
4706
5101
                    b.repository.commit_write_group()
4707
5102
            else:
4708
 
                raise errors.BzrCommandError('Please supply either one revision, or a range.')
 
5103
                raise errors.BzrCommandError(gettext('Please supply either one revision, or a range.'))
4709
5104
 
4710
5105
 
4711
5106
class cmd_bind(Command):
4730
5125
            try:
4731
5126
                location = b.get_old_bound_location()
4732
5127
            except errors.UpgradeRequired:
4733
 
                raise errors.BzrCommandError('No location supplied.  '
4734
 
                    'This format does not remember old locations.')
 
5128
                raise errors.BzrCommandError(gettext('No location supplied.  '
 
5129
                    'This format does not remember old locations.'))
4735
5130
            else:
4736
5131
                if location is None:
4737
5132
                    if b.get_bound_location() is not None:
4738
 
                        raise errors.BzrCommandError('Branch is already bound')
 
5133
                        raise errors.BzrCommandError(gettext('Branch is already bound'))
4739
5134
                    else:
4740
 
                        raise errors.BzrCommandError('No location supplied '
4741
 
                            'and no previous location known')
 
5135
                        raise errors.BzrCommandError(gettext('No location supplied '
 
5136
                            'and no previous location known'))
4742
5137
        b_other = Branch.open(location)
4743
5138
        try:
4744
5139
            b.bind(b_other)
4745
5140
        except errors.DivergedBranches:
4746
 
            raise errors.BzrCommandError('These branches have diverged.'
4747
 
                                         ' Try merging, and then bind again.')
 
5141
            raise errors.BzrCommandError(gettext('These branches have diverged.'
 
5142
                                         ' Try merging, and then bind again.'))
4748
5143
        if b.get_config().has_explicit_nickname():
4749
5144
            b.nick = b_other.nick
4750
5145
 
4763
5158
    def run(self, directory=u'.'):
4764
5159
        b, relpath = Branch.open_containing(directory)
4765
5160
        if not b.unbind():
4766
 
            raise errors.BzrCommandError('Local branch is not bound')
 
5161
            raise errors.BzrCommandError(gettext('Local branch is not bound'))
4767
5162
 
4768
5163
 
4769
5164
class cmd_uncommit(Command):
4790
5185
    takes_options = ['verbose', 'revision',
4791
5186
                    Option('dry-run', help='Don\'t actually make changes.'),
4792
5187
                    Option('force', help='Say yes to all questions.'),
 
5188
                    Option('keep-tags',
 
5189
                           help='Keep tags that point to removed revisions.'),
4793
5190
                    Option('local',
4794
5191
                           help="Only remove the commits from the local branch"
4795
5192
                                " when in a checkout."
4799
5196
    aliases = []
4800
5197
    encoding_type = 'replace'
4801
5198
 
4802
 
    def run(self, location=None,
4803
 
            dry_run=False, verbose=False,
4804
 
            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):
4805
5201
        if location is None:
4806
5202
            location = u'.'
4807
 
        control, relpath = bzrdir.BzrDir.open_containing(location)
 
5203
        control, relpath = controldir.ControlDir.open_containing(location)
4808
5204
        try:
4809
5205
            tree = control.open_workingtree()
4810
5206
            b = tree.branch
4816
5212
            self.add_cleanup(tree.lock_write().unlock)
4817
5213
        else:
4818
5214
            self.add_cleanup(b.lock_write().unlock)
4819
 
        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)
4820
5217
 
4821
 
    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):
4822
5220
        from bzrlib.log import log_formatter, show_log
4823
5221
        from bzrlib.uncommit import uncommit
4824
5222
 
4839
5237
                rev_id = b.get_rev_id(revno)
4840
5238
 
4841
5239
        if rev_id is None or _mod_revision.is_null(rev_id):
4842
 
            self.outf.write('No revisions to uncommit.\n')
 
5240
            self.outf.write(gettext('No revisions to uncommit.\n'))
4843
5241
            return 1
4844
5242
 
4845
5243
        lf = log_formatter('short',
4854
5252
                 end_revision=last_revno)
4855
5253
 
4856
5254
        if dry_run:
4857
 
            self.outf.write('Dry-run, pretending to remove'
4858
 
                            ' the above revisions.\n')
 
5255
            self.outf.write(gettext('Dry-run, pretending to remove'
 
5256
                            ' the above revisions.\n'))
4859
5257
        else:
4860
 
            self.outf.write('The above revision(s) will be removed.\n')
 
5258
            self.outf.write(gettext('The above revision(s) will be removed.\n'))
4861
5259
 
4862
5260
        if not force:
4863
5261
            if not ui.ui_factory.confirm_action(
4864
 
                    'Uncommit these revisions',
 
5262
                    gettext(u'Uncommit these revisions'),
4865
5263
                    'bzrlib.builtins.uncommit',
4866
5264
                    {}):
4867
 
                self.outf.write('Canceled\n')
 
5265
                self.outf.write(gettext('Canceled\n'))
4868
5266
                return 0
4869
5267
 
4870
5268
        mutter('Uncommitting from {%s} to {%s}',
4871
5269
               last_rev_id, rev_id)
4872
5270
        uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4873
 
                 revno=revno, local=local)
4874
 
        self.outf.write('You can restore the old tip by running:\n'
4875
 
             '  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)
4876
5274
 
4877
5275
 
4878
5276
class cmd_break_lock(Command):
4912
5310
            conf = _mod_config.LockableConfig(file_name=location)
4913
5311
            conf.break_lock()
4914
5312
        else:
4915
 
            control, relpath = bzrdir.BzrDir.open_containing(location)
 
5313
            control, relpath = controldir.ControlDir.open_containing(location)
4916
5314
            try:
4917
5315
                control.break_lock()
4918
5316
            except NotImplementedError:
4962
5360
                    'option leads to global uncontrolled write access to your '
4963
5361
                    'file system.'
4964
5362
                ),
 
5363
        Option('client-timeout', type=float,
 
5364
               help='Override the default idle client timeout (5min).'),
4965
5365
        ]
4966
5366
 
4967
5367
    def get_host_and_port(self, port):
4984
5384
        return host, port
4985
5385
 
4986
5386
    def run(self, port=None, inet=False, directory=None, allow_writes=False,
4987
 
            protocol=None):
 
5387
            protocol=None, client_timeout=None):
4988
5388
        from bzrlib import transport
4989
5389
        if directory is None:
4990
5390
            directory = os.getcwd()
4991
5391
        if protocol is None:
4992
5392
            protocol = transport.transport_server_registry.get()
4993
5393
        host, port = self.get_host_and_port(port)
4994
 
        url = urlutils.local_path_to_url(directory)
 
5394
        url = transport.location_to_url(directory)
4995
5395
        if not allow_writes:
4996
5396
            url = 'readonly+' + url
4997
 
        t = transport.get_transport(url)
4998
 
        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)
4999
5411
 
5000
5412
 
5001
5413
class cmd_join(Command):
5024
5436
        containing_tree = WorkingTree.open_containing(parent_dir)[0]
5025
5437
        repo = containing_tree.branch.repository
5026
5438
        if not repo.supports_rich_root():
5027
 
            raise errors.BzrCommandError(
 
5439
            raise errors.BzrCommandError(gettext(
5028
5440
                "Can't join trees because %s doesn't support rich root data.\n"
5029
 
                "You can use bzr upgrade on the repository."
 
5441
                "You can use bzr upgrade on the repository.")
5030
5442
                % (repo,))
5031
5443
        if reference:
5032
5444
            try:
5034
5446
            except errors.BadReferenceTarget, e:
5035
5447
                # XXX: Would be better to just raise a nicely printable
5036
5448
                # exception from the real origin.  Also below.  mbp 20070306
5037
 
                raise errors.BzrCommandError("Cannot join %s.  %s" %
5038
 
                                             (tree, e.reason))
 
5449
                raise errors.BzrCommandError(
 
5450
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5039
5451
        else:
5040
5452
            try:
5041
5453
                containing_tree.subsume(sub_tree)
5042
5454
            except errors.BadSubsumeSource, e:
5043
 
                raise errors.BzrCommandError("Cannot join %s.  %s" %
5044
 
                                             (tree, e.reason))
 
5455
                raise errors.BzrCommandError(
 
5456
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5045
5457
 
5046
5458
 
5047
5459
class cmd_split(Command):
5131
5543
        if submit_branch is None:
5132
5544
            submit_branch = branch.get_parent()
5133
5545
        if submit_branch is None:
5134
 
            raise errors.BzrCommandError('No submit branch specified or known')
 
5546
            raise errors.BzrCommandError(gettext('No submit branch specified or known'))
5135
5547
 
5136
5548
        stored_public_branch = branch.get_public_branch()
5137
5549
        if public_branch is None:
5139
5551
        elif stored_public_branch is None:
5140
5552
            branch.set_public_branch(public_branch)
5141
5553
        if not include_bundle and public_branch is None:
5142
 
            raise errors.BzrCommandError('No public branch specified or'
5143
 
                                         ' known')
 
5554
            raise errors.BzrCommandError(gettext('No public branch specified or'
 
5555
                                         ' known'))
5144
5556
        base_revision_id = None
5145
5557
        if revision is not None:
5146
5558
            if len(revision) > 2:
5147
 
                raise errors.BzrCommandError('bzr merge-directive takes '
5148
 
                    'at most two one revision identifiers')
 
5559
                raise errors.BzrCommandError(gettext('bzr merge-directive takes '
 
5560
                    'at most two one revision identifiers'))
5149
5561
            revision_id = revision[-1].as_revision_id(branch)
5150
5562
            if len(revision) == 2:
5151
5563
                base_revision_id = revision[0].as_revision_id(branch)
5153
5565
            revision_id = branch.last_revision()
5154
5566
        revision_id = ensure_null(revision_id)
5155
5567
        if revision_id == NULL_REVISION:
5156
 
            raise errors.BzrCommandError('No revisions to bundle.')
 
5568
            raise errors.BzrCommandError(gettext('No revisions to bundle.'))
5157
5569
        directive = merge_directive.MergeDirective2.from_objects(
5158
5570
            branch.repository, revision_id, time.time(),
5159
5571
            osutils.local_time_offset(), submit_branch,
5167
5579
                self.outf.writelines(directive.to_lines())
5168
5580
        else:
5169
5581
            message = directive.to_email(mail_to, branch, sign)
5170
 
            s = SMTPConnection(branch.get_config())
 
5582
            s = SMTPConnection(branch.get_config_stack())
5171
5583
            s.send_email(message)
5172
5584
 
5173
5585
 
5203
5615
    source branch defaults to that containing the working directory, but can
5204
5616
    be changed using --from.
5205
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
 
5206
5624
    In order to calculate those changes, bzr must analyse the submit branch.
5207
5625
    Therefore it is most efficient for the submit branch to be a local mirror.
5208
5626
    If a public location is known for the submit_branch, that location is used
5277
5695
        ]
5278
5696
 
5279
5697
    def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5280
 
            no_patch=False, revision=None, remember=False, output=None,
 
5698
            no_patch=False, revision=None, remember=None, output=None,
5281
5699
            format=None, mail_to=None, message=None, body=None,
5282
5700
            strict=None, **kwargs):
5283
5701
        from bzrlib.send import send
5407
5825
        self.add_cleanup(branch.lock_write().unlock)
5408
5826
        if delete:
5409
5827
            if tag_name is None:
5410
 
                raise errors.BzrCommandError("No tag specified to delete.")
 
5828
                raise errors.BzrCommandError(gettext("No tag specified to delete."))
5411
5829
            branch.tags.delete_tag(tag_name)
5412
 
            note('Deleted tag %s.' % tag_name)
 
5830
            note(gettext('Deleted tag %s.') % tag_name)
5413
5831
        else:
5414
5832
            if revision:
5415
5833
                if len(revision) != 1:
5416
 
                    raise errors.BzrCommandError(
 
5834
                    raise errors.BzrCommandError(gettext(
5417
5835
                        "Tags can only be placed on a single revision, "
5418
 
                        "not on a range")
 
5836
                        "not on a range"))
5419
5837
                revision_id = revision[0].as_revision_id(branch)
5420
5838
            else:
5421
5839
                revision_id = branch.last_revision()
5422
5840
            if tag_name is None:
5423
5841
                tag_name = branch.automatic_tag_name(revision_id)
5424
5842
                if tag_name is None:
5425
 
                    raise errors.BzrCommandError(
5426
 
                        "Please specify a tag name.")
5427
 
            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):
5428
5850
                raise errors.TagAlreadyExists(tag_name)
5429
 
            branch.tags.set_tag(tag_name, revision_id)
5430
 
            note('Created tag %s.' % tag_name)
 
5851
            if existing_target == revision_id:
 
5852
                note(gettext('Tag %s already exists for that revision.') % tag_name)
 
5853
            else:
 
5854
                branch.tags.set_tag(tag_name, revision_id)
 
5855
                if existing_target is None:
 
5856
                    note(gettext('Created tag %s.') % tag_name)
 
5857
                else:
 
5858
                    note(gettext('Updated tag %s.') % tag_name)
5431
5859
 
5432
5860
 
5433
5861
class cmd_tags(Command):
5440
5868
    takes_options = [
5441
5869
        custom_help('directory',
5442
5870
            help='Branch whose tags should be displayed.'),
5443
 
        RegistryOption.from_kwargs('sort',
 
5871
        RegistryOption('sort',
5444
5872
            'Sort tags by different criteria.', title='Sorting',
5445
 
            natural='Sort numeric substrings as numbers:'
5446
 
                    ' suitable for version numbers. (default)',
5447
 
            alpha='Sort tags lexicographically.',
5448
 
            time='Sort tags chronologically.',
 
5873
            lazy_registry=('bzrlib.tag', 'tag_sort_methods')
5449
5874
            ),
5450
5875
        'show-ids',
5451
5876
        'revision',
5452
5877
    ]
5453
5878
 
5454
5879
    @display_command
5455
 
    def run(self,
5456
 
            directory='.',
5457
 
            sort='natural',
5458
 
            show_ids=False,
5459
 
            revision=None,
5460
 
            ):
 
5880
    def run(self, directory='.', sort=None, show_ids=False, revision=None):
 
5881
        from bzrlib.tag import tag_sort_methods
5461
5882
        branch, relpath = Branch.open_containing(directory)
5462
5883
 
5463
5884
        tags = branch.tags.get_tag_dict().items()
5466
5887
 
5467
5888
        self.add_cleanup(branch.lock_read().unlock)
5468
5889
        if revision:
5469
 
            graph = branch.repository.get_graph()
5470
 
            rev1, rev2 = _get_revision_range(revision, branch, self.name())
5471
 
            revid1, revid2 = rev1.rev_id, rev2.rev_id
5472
 
            # only show revisions between revid1 and revid2 (inclusive)
5473
 
            tags = [(tag, revid) for tag, revid in tags if
5474
 
                graph.is_between(revid, revid1, revid2)]
5475
 
        if sort == 'natural':
5476
 
            def natural_sort_key(tag):
5477
 
                return [f(s) for f,s in 
5478
 
                        zip(itertools.cycle((unicode.lower,int)),
5479
 
                                            re.split('([0-9]+)', tag[0]))]
5480
 
            tags.sort(key=natural_sort_key)
5481
 
        elif sort == 'alpha':
5482
 
            tags.sort()
5483
 
        elif sort == 'time':
5484
 
            timestamps = {}
5485
 
            for tag, revid in tags:
5486
 
                try:
5487
 
                    revobj = branch.repository.get_revision(revid)
5488
 
                except errors.NoSuchRevision:
5489
 
                    timestamp = sys.maxint # place them at the end
5490
 
                else:
5491
 
                    timestamp = revobj.timestamp
5492
 
                timestamps[revid] = timestamp
5493
 
            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)
5494
5895
        if not show_ids:
5495
5896
            # [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5496
5897
            for index, (tag, revid) in enumerate(tags):
5498
5899
                    revno = branch.revision_id_to_dotted_revno(revid)
5499
5900
                    if isinstance(revno, tuple):
5500
5901
                        revno = '.'.join(map(str, revno))
5501
 
                except errors.NoSuchRevision:
 
5902
                except (errors.NoSuchRevision,
 
5903
                        errors.GhostRevisionsHaveNoRevno,
 
5904
                        errors.UnsupportedOperation):
5502
5905
                    # Bad tag data/merges can lead to tagged revisions
5503
5906
                    # which are not in this branch. Fail gracefully ...
5504
5907
                    revno = '?'
5507
5910
        for tag, revspec in tags:
5508
5911
            self.outf.write('%-20s %s\n' % (tag, revspec))
5509
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
 
5510
5939
 
5511
5940
class cmd_reconfigure(Command):
5512
5941
    __doc__ = """Reconfigure the type of a bzr directory.
5526
5955
    takes_args = ['location?']
5527
5956
    takes_options = [
5528
5957
        RegistryOption.from_kwargs(
5529
 
            'target_type',
5530
 
            title='Target type',
5531
 
            help='The type to reconfigure the directory to.',
 
5958
            'tree_type',
 
5959
            title='Tree type',
 
5960
            help='The relation between branch and tree.',
5532
5961
            value_switches=True, enum_switch=False,
5533
5962
            branch='Reconfigure to be an unbound branch with no working tree.',
5534
5963
            tree='Reconfigure to be an unbound branch with a working tree.',
5535
5964
            checkout='Reconfigure to be a bound branch with a working tree.',
5536
5965
            lightweight_checkout='Reconfigure to be a lightweight'
5537
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,
5538
5973
            standalone='Reconfigure to be a standalone branch '
5539
5974
                '(i.e. stop using shared repository).',
5540
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,
5541
5982
            with_trees='Reconfigure repository to create '
5542
5983
                'working trees on branches by default.',
5543
5984
            with_no_trees='Reconfigure repository to not create '
5557
5998
            ),
5558
5999
        ]
5559
6000
 
5560
 
    def run(self, location=None, target_type=None, bind_to=None, force=False,
5561
 
            stacked_on=None,
5562
 
            unstacked=None):
5563
 
        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)
5564
6005
        if stacked_on and unstacked:
5565
 
            raise BzrCommandError("Can't use both --stacked-on and --unstacked")
 
6006
            raise errors.BzrCommandError(gettext("Can't use both --stacked-on and --unstacked"))
5566
6007
        elif stacked_on is not None:
5567
6008
            reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5568
6009
        elif unstacked:
5570
6011
        # At the moment you can use --stacked-on and a different
5571
6012
        # reconfiguration shape at the same time; there seems no good reason
5572
6013
        # to ban it.
5573
 
        if target_type is None:
 
6014
        if (tree_type is None and
 
6015
            repository_type is None and
 
6016
            repository_trees is None):
5574
6017
            if stacked_on or unstacked:
5575
6018
                return
5576
6019
            else:
5577
 
                raise errors.BzrCommandError('No target configuration '
5578
 
                    'specified')
5579
 
        elif target_type == 'branch':
 
6020
                raise errors.BzrCommandError(gettext('No target configuration '
 
6021
                    'specified'))
 
6022
        reconfiguration = None
 
6023
        if tree_type == 'branch':
5580
6024
            reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5581
 
        elif target_type == 'tree':
 
6025
        elif tree_type == 'tree':
5582
6026
            reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5583
 
        elif target_type == 'checkout':
 
6027
        elif tree_type == 'checkout':
5584
6028
            reconfiguration = reconfigure.Reconfigure.to_checkout(
5585
6029
                directory, bind_to)
5586
 
        elif target_type == 'lightweight-checkout':
 
6030
        elif tree_type == 'lightweight-checkout':
5587
6031
            reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5588
6032
                directory, bind_to)
5589
 
        elif target_type == 'use-shared':
 
6033
        if reconfiguration:
 
6034
            reconfiguration.apply(force)
 
6035
            reconfiguration = None
 
6036
        if repository_type == 'use-shared':
5590
6037
            reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5591
 
        elif target_type == 'standalone':
 
6038
        elif repository_type == 'standalone':
5592
6039
            reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5593
 
        elif target_type == 'with-trees':
 
6040
        if reconfiguration:
 
6041
            reconfiguration.apply(force)
 
6042
            reconfiguration = None
 
6043
        if repository_trees == 'with-trees':
5594
6044
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5595
6045
                directory, True)
5596
 
        elif target_type == 'with-no-trees':
 
6046
        elif repository_trees == 'with-no-trees':
5597
6047
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5598
6048
                directory, False)
5599
 
        reconfiguration.apply(force)
 
6049
        if reconfiguration:
 
6050
            reconfiguration.apply(force)
 
6051
            reconfiguration = None
5600
6052
 
5601
6053
 
5602
6054
class cmd_switch(Command):
5637
6089
        from bzrlib import switch
5638
6090
        tree_location = directory
5639
6091
        revision = _get_one_revision('switch', revision)
5640
 
        control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
 
6092
        control_dir = controldir.ControlDir.open_containing(tree_location)[0]
5641
6093
        if to_location is None:
5642
6094
            if revision is None:
5643
 
                raise errors.BzrCommandError('You must supply either a'
5644
 
                                             ' revision or a location')
 
6095
                raise errors.BzrCommandError(gettext('You must supply either a'
 
6096
                                             ' revision or a location'))
5645
6097
            to_location = tree_location
5646
6098
        try:
5647
6099
            branch = control_dir.open_branch()
5651
6103
            had_explicit_nick = False
5652
6104
        if create_branch:
5653
6105
            if branch is None:
5654
 
                raise errors.BzrCommandError('cannot create branch without'
5655
 
                                             ' source branch')
 
6106
                raise errors.BzrCommandError(gettext('cannot create branch without'
 
6107
                                             ' source branch'))
5656
6108
            to_location = directory_service.directories.dereference(
5657
6109
                              to_location)
5658
6110
            if '/' not in to_location and '\\' not in to_location:
5659
6111
                # This path is meant to be relative to the existing branch
5660
6112
                this_url = self._get_branch_location(control_dir)
5661
 
                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))
5662
6127
            to_branch = branch.bzrdir.sprout(to_location,
5663
6128
                                 possible_transports=[branch.bzrdir.root_transport],
5664
6129
                                 source_branch=branch).open_branch()
5665
6130
        else:
 
6131
            # Perhaps it's a colocated branch?
5666
6132
            try:
5667
 
                to_branch = Branch.open(to_location)
5668
 
            except errors.NotBranchError:
5669
 
                this_url = self._get_branch_location(control_dir)
5670
 
                to_branch = Branch.open(
5671
 
                    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)))
5672
6142
        if revision is not None:
5673
6143
            revision = revision.as_revision_id(to_branch)
5674
6144
        switch.switch(control_dir, to_branch, force, revision_id=revision)
5675
6145
        if had_explicit_nick:
5676
6146
            branch = control_dir.open_branch() #get the new branch!
5677
6147
            branch.nick = to_branch.nick
5678
 
        note('Switched to branch: %s',
 
6148
        note(gettext('Switched to branch: %s'),
5679
6149
            urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5680
6150
 
5681
6151
    def _get_branch_location(self, control_dir):
5790
6260
            name = current_view
5791
6261
        if delete:
5792
6262
            if file_list:
5793
 
                raise errors.BzrCommandError(
5794
 
                    "Both --delete and a file list specified")
 
6263
                raise errors.BzrCommandError(gettext(
 
6264
                    "Both --delete and a file list specified"))
5795
6265
            elif switch:
5796
 
                raise errors.BzrCommandError(
5797
 
                    "Both --delete and --switch specified")
 
6266
                raise errors.BzrCommandError(gettext(
 
6267
                    "Both --delete and --switch specified"))
5798
6268
            elif all:
5799
6269
                tree.views.set_view_info(None, {})
5800
 
                self.outf.write("Deleted all views.\n")
 
6270
                self.outf.write(gettext("Deleted all views.\n"))
5801
6271
            elif name is None:
5802
 
                raise errors.BzrCommandError("No current view to delete")
 
6272
                raise errors.BzrCommandError(gettext("No current view to delete"))
5803
6273
            else:
5804
6274
                tree.views.delete_view(name)
5805
 
                self.outf.write("Deleted '%s' view.\n" % name)
 
6275
                self.outf.write(gettext("Deleted '%s' view.\n") % name)
5806
6276
        elif switch:
5807
6277
            if file_list:
5808
 
                raise errors.BzrCommandError(
5809
 
                    "Both --switch and a file list specified")
 
6278
                raise errors.BzrCommandError(gettext(
 
6279
                    "Both --switch and a file list specified"))
5810
6280
            elif all:
5811
 
                raise errors.BzrCommandError(
5812
 
                    "Both --switch and --all specified")
 
6281
                raise errors.BzrCommandError(gettext(
 
6282
                    "Both --switch and --all specified"))
5813
6283
            elif switch == 'off':
5814
6284
                if current_view is None:
5815
 
                    raise errors.BzrCommandError("No current view to disable")
 
6285
                    raise errors.BzrCommandError(gettext("No current view to disable"))
5816
6286
                tree.views.set_view_info(None, view_dict)
5817
 
                self.outf.write("Disabled '%s' view.\n" % (current_view))
 
6287
                self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
5818
6288
            else:
5819
6289
                tree.views.set_view_info(switch, view_dict)
5820
6290
                view_str = views.view_display_str(tree.views.lookup_view())
5821
 
                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))
5822
6292
        elif all:
5823
6293
            if view_dict:
5824
 
                self.outf.write('Views defined:\n')
 
6294
                self.outf.write(gettext('Views defined:\n'))
5825
6295
                for view in sorted(view_dict):
5826
6296
                    if view == current_view:
5827
6297
                        active = "=>"
5830
6300
                    view_str = views.view_display_str(view_dict[view])
5831
6301
                    self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5832
6302
            else:
5833
 
                self.outf.write('No views defined.\n')
 
6303
                self.outf.write(gettext('No views defined.\n'))
5834
6304
        elif file_list:
5835
6305
            if name is None:
5836
6306
                # No name given and no current view set
5837
6307
                name = 'my'
5838
6308
            elif name == 'off':
5839
 
                raise errors.BzrCommandError(
5840
 
                    "Cannot change the 'off' pseudo view")
 
6309
                raise errors.BzrCommandError(gettext(
 
6310
                    "Cannot change the 'off' pseudo view"))
5841
6311
            tree.views.set_view(name, sorted(file_list))
5842
6312
            view_str = views.view_display_str(tree.views.lookup_view())
5843
 
            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))
5844
6314
        else:
5845
6315
            # list the files
5846
6316
            if name is None:
5847
6317
                # No name given and no current view set
5848
 
                self.outf.write('No current view.\n')
 
6318
                self.outf.write(gettext('No current view.\n'))
5849
6319
            else:
5850
6320
                view_str = views.view_display_str(tree.views.lookup_view(name))
5851
 
                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))
5852
6322
 
5853
6323
 
5854
6324
class cmd_hooks(Command):
5868
6338
                        self.outf.write("    %s\n" %
5869
6339
                                        (some_hooks.get_hook_name(hook),))
5870
6340
                else:
5871
 
                    self.outf.write("    <no hooks installed>\n")
 
6341
                    self.outf.write(gettext("    <no hooks installed>\n"))
5872
6342
 
5873
6343
 
5874
6344
class cmd_remove_branch(Command):
5894
6364
            location = "."
5895
6365
        branch = Branch.open_containing(location)[0]
5896
6366
        branch.bzrdir.destroy_branch()
5897
 
        
 
6367
 
5898
6368
 
5899
6369
class cmd_shelve(Command):
5900
6370
    __doc__ = """Temporarily set aside some changes from the current tree.
5951
6421
    _see_also = ['unshelve', 'configuration']
5952
6422
 
5953
6423
    def run(self, revision=None, all=False, file_list=None, message=None,
5954
 
            writer=None, list=False, destroy=False, directory=u'.'):
 
6424
            writer=None, list=False, destroy=False, directory=None):
5955
6425
        if list:
5956
 
            return self.run_for_list()
 
6426
            return self.run_for_list(directory=directory)
5957
6427
        from bzrlib.shelf_ui import Shelver
5958
6428
        if writer is None:
5959
6429
            writer = bzrlib.option.diff_writer_registry.get()
5967
6437
        except errors.UserAbort:
5968
6438
            return 0
5969
6439
 
5970
 
    def run_for_list(self):
5971
 
        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]
5972
6444
        self.add_cleanup(tree.lock_read().unlock)
5973
6445
        manager = tree.get_shelf_manager()
5974
6446
        shelves = manager.active_shelves()
5975
6447
        if len(shelves) == 0:
5976
 
            note('No shelved changes.')
 
6448
            note(gettext('No shelved changes.'))
5977
6449
            return 0
5978
6450
        for shelf_id in reversed(shelves):
5979
6451
            message = manager.get_metadata(shelf_id).get('message')
6033
6505
    """
6034
6506
    takes_options = ['directory',
6035
6507
                     Option('ignored', help='Delete all ignored files.'),
6036
 
                     Option('detritus', help='Delete conflict files, merge'
 
6508
                     Option('detritus', help='Delete conflict files, merge and revert'
6037
6509
                            ' backups, and failed selftest dirs.'),
6038
6510
                     Option('unknown',
6039
6511
                            help='Delete files unknown to bzr (default).'),
6068
6540
        if path is not None:
6069
6541
            branchdir = path
6070
6542
        tree, branch, relpath =(
6071
 
            bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
 
6543
            controldir.ControlDir.open_containing_tree_or_branch(branchdir))
6072
6544
        if path is not None:
6073
6545
            path = relpath
6074
6546
        if tree is None:
6098
6570
            self.outf.write('%s %s\n' % (path, location))
6099
6571
 
6100
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
 
6101
6591
def _register_lazy_builtins():
6102
6592
    # register lazy builtins from other modules; called at startup and should
6103
6593
    # be only called once.
6108
6598
        ('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6109
6599
        ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6110
6600
        ('cmd_conflicts', [], 'bzrlib.conflicts'),
6111
 
        ('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'),
6112
6604
        ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6113
6605
        ]:
6114
6606
        builtin_command_registry.register_lazy(name, aliases, module_name)