~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: John Arbash Meinel
  • Date: 2011-04-20 15:06:17 UTC
  • mto: This revision was merged to the branch mainline in revision 5836.
  • Revision ID: john@arbash-meinel.com-20110420150617-i41caxgemg32tq1r
Start adding tests that _worth_saving_limit works as expected.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012 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
16
16
 
17
17
"""builtin bzr commands"""
18
18
 
19
 
from __future__ import absolute_import
20
 
 
21
19
import os
22
20
 
23
 
import bzrlib.bzrdir
24
 
 
25
 
from bzrlib import lazy_import
26
 
lazy_import.lazy_import(globals(), """
 
21
from bzrlib.lazy_import import lazy_import
 
22
lazy_import(globals(), """
27
23
import cStringIO
28
 
import errno
29
24
import sys
30
25
import time
31
26
 
34
29
    bugtracker,
35
30
    bundle,
36
31
    btree_index,
37
 
    controldir,
 
32
    bzrdir,
38
33
    directory_service,
39
34
    delta,
40
35
    config as _mod_config,
49
44
    rename_map,
50
45
    revision as _mod_revision,
51
46
    static_tuple,
 
47
    symbol_versioning,
52
48
    timestamp,
53
49
    transport,
54
50
    ui,
55
51
    urlutils,
56
52
    views,
57
 
    gpg,
58
53
    )
59
54
from bzrlib.branch import Branch
60
55
from bzrlib.conflicts import ConflictList
62
57
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
63
58
from bzrlib.smtp_connection import SMTPConnection
64
59
from bzrlib.workingtree import WorkingTree
65
 
from bzrlib.i18n import gettext, ngettext
66
60
""")
67
61
 
68
62
from bzrlib.commands import (
78
72
    _parse_revision_str,
79
73
    )
80
74
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
81
 
from bzrlib import (
82
 
    symbol_versioning,
83
 
    )
84
 
 
85
 
 
86
 
def _get_branch_location(control_dir, possible_transports=None):
87
 
    """Return location of branch for this control dir."""
88
 
    try:
89
 
        target = control_dir.get_branch_reference()
90
 
    except errors.NotBranchError:
91
 
        return control_dir.root_transport.base
92
 
    if target is not None:
93
 
        return target
94
 
    this_branch = control_dir.open_branch(
95
 
        possible_transports=possible_transports)
96
 
    # This may be a heavy checkout, where we want the master branch
97
 
    master_location = this_branch.get_bound_location()
98
 
    if master_location is not None:
99
 
        return master_location
100
 
    # If not, use a local sibling
101
 
    return this_branch.base
102
 
 
103
 
 
104
 
def _is_colocated(control_dir, possible_transports=None):
105
 
    """Check if the branch in control_dir is colocated.
106
 
 
107
 
    :param control_dir: Control directory
108
 
    :return: Tuple with boolean indicating whether the branch is colocated
109
 
        and the full URL to the actual branch
110
 
    """
111
 
    # This path is meant to be relative to the existing branch
112
 
    this_url = _get_branch_location(control_dir,
113
 
        possible_transports=possible_transports)
114
 
    # Perhaps the target control dir supports colocated branches?
115
 
    try:
116
 
        root = controldir.ControlDir.open(this_url,
117
 
            possible_transports=possible_transports)
118
 
    except errors.NotBranchError:
119
 
        return (False, this_url)
120
 
    else:
121
 
        try:
122
 
            wt = control_dir.open_workingtree()
123
 
        except (errors.NoWorkingTree, errors.NotLocalUrl):
124
 
            return (False, this_url)
125
 
        else:
126
 
            return (
127
 
                root._format.colocated_branches and
128
 
                control_dir.control_url == root.control_url,
129
 
                this_url)
130
 
 
131
 
 
132
 
def lookup_new_sibling_branch(control_dir, location, possible_transports=None):
133
 
    """Lookup the location for a new sibling branch.
134
 
 
135
 
    :param control_dir: Control directory to find sibling branches from
136
 
    :param location: Name of the new branch
137
 
    :return: Full location to the new branch
138
 
    """
139
 
    location = directory_service.directories.dereference(location)
140
 
    if '/' not in location and '\\' not in location:
141
 
        (colocated, this_url) = _is_colocated(control_dir, possible_transports)
142
 
 
143
 
        if colocated:
144
 
            return urlutils.join_segment_parameters(this_url,
145
 
                {"branch": urlutils.escape(location)})
146
 
        else:
147
 
            return urlutils.join(this_url, '..', urlutils.escape(location))
148
 
    return location
149
 
 
150
 
 
151
 
def open_sibling_branch(control_dir, location, possible_transports=None):
152
 
    """Open a branch, possibly a sibling of another.
153
 
 
154
 
    :param control_dir: Control directory relative to which to lookup the
155
 
        location.
156
 
    :param location: Location to look up
157
 
    :return: branch to open
158
 
    """
159
 
    try:
160
 
        # Perhaps it's a colocated branch?
161
 
        return control_dir.open_branch(location, 
162
 
            possible_transports=possible_transports)
163
 
    except (errors.NotBranchError, errors.NoColocatedBranchSupport):
164
 
        this_url = _get_branch_location(control_dir)
165
 
        return Branch.open(
166
 
            urlutils.join(
167
 
                this_url, '..', urlutils.escape(location)))
168
 
 
169
 
 
170
 
def open_nearby_branch(near=None, location=None, possible_transports=None):
171
 
    """Open a nearby branch.
172
 
 
173
 
    :param near: Optional location of container from which to open branch
174
 
    :param location: Location of the branch
175
 
    :return: Branch instance
176
 
    """
177
 
    if near is None:
178
 
        if location is None:
179
 
            location = "."
180
 
        try:
181
 
            return Branch.open(location,
182
 
                possible_transports=possible_transports)
183
 
        except errors.NotBranchError:
184
 
            near = "."
185
 
    cdir = controldir.ControlDir.open(near,
186
 
        possible_transports=possible_transports)
187
 
    return open_sibling_branch(cdir, location,
188
 
        possible_transports=possible_transports)
189
 
 
190
 
 
191
 
def iter_sibling_branches(control_dir, possible_transports=None):
192
 
    """Iterate over the siblings of a branch.
193
 
 
194
 
    :param control_dir: Control directory for which to look up the siblings
195
 
    :return: Iterator over tuples with branch name and branch object
196
 
    """
197
 
    seen_urls = set()
198
 
    try:
199
 
        reference = control_dir.get_branch_reference()
200
 
    except errors.NotBranchError:
201
 
        # There is no active branch, just return the colocated branches.
202
 
        for name, branch in control_dir.get_branches().iteritems():
203
 
            yield name, branch
204
 
        return
205
 
    if reference is not None:
206
 
        ref_branch = Branch.open(reference,
207
 
            possible_transports=possible_transports)
208
 
    else:
209
 
        ref_branch = None
210
 
    if ref_branch is None or ref_branch.name:
211
 
        if ref_branch is not None:
212
 
            control_dir = ref_branch.bzrdir
213
 
        for name, branch in control_dir.get_branches().iteritems():
214
 
            yield name, branch
215
 
    else:
216
 
        repo = ref_branch.bzrdir.find_repository()
217
 
        for branch in repo.find_branches(using=True):
218
 
            name = urlutils.relative_url(repo.user_url,
219
 
                branch.user_url).rstrip("/")
220
 
            yield name, branch
 
75
 
 
76
 
 
77
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
 
78
def tree_files(file_list, default_branch=u'.', canonicalize=True,
 
79
    apply_view=True):
 
80
    return internal_tree_files(file_list, default_branch, canonicalize,
 
81
        apply_view)
221
82
 
222
83
 
223
84
def tree_files_for_add(file_list):
248
109
            if view_files:
249
110
                file_list = view_files
250
111
                view_str = views.view_display_str(view_files)
251
 
                note(gettext("Ignoring files outside view. View is %s") % view_str)
 
112
                note("Ignoring files outside view. View is %s" % view_str)
252
113
    return tree, file_list
253
114
 
254
115
 
256
117
    if revisions is None:
257
118
        return None
258
119
    if len(revisions) != 1:
259
 
        raise errors.BzrCommandError(gettext(
260
 
            'bzr %s --revision takes exactly one revision identifier') % (
 
120
        raise errors.BzrCommandError(
 
121
            'bzr %s --revision takes exactly one revision identifier' % (
261
122
                command_name,))
262
123
    return revisions[0]
263
124
 
285
146
    return rev_tree
286
147
 
287
148
 
 
149
# XXX: Bad function name; should possibly also be a class method of
 
150
# WorkingTree rather than a function.
 
151
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
 
152
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
 
153
    apply_view=True):
 
154
    """Convert command-line paths to a WorkingTree and relative paths.
 
155
 
 
156
    Deprecated: use WorkingTree.open_containing_paths instead.
 
157
 
 
158
    This is typically used for command-line processors that take one or
 
159
    more filenames, and infer the workingtree that contains them.
 
160
 
 
161
    The filenames given are not required to exist.
 
162
 
 
163
    :param file_list: Filenames to convert.
 
164
 
 
165
    :param default_branch: Fallback tree path to use if file_list is empty or
 
166
        None.
 
167
 
 
168
    :param apply_view: if True and a view is set, apply it or check that
 
169
        specified files are within it
 
170
 
 
171
    :return: workingtree, [relative_paths]
 
172
    """
 
173
    return WorkingTree.open_containing_paths(
 
174
        file_list, default_directory='.',
 
175
        canonicalize=True,
 
176
        apply_view=True)
 
177
 
 
178
 
288
179
def _get_view_info_for_change_reporter(tree):
289
180
    """Get the view information from a tree for change reporting."""
290
181
    view_info = None
302
193
    the --directory option is used to specify a different branch."""
303
194
    if directory is not None:
304
195
        return (None, Branch.open(directory), filename)
305
 
    return controldir.ControlDir.open_containing_tree_or_branch(filename)
 
196
    return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
306
197
 
307
198
 
308
199
# TODO: Make sure no commands unconditionally use the working directory as a
338
229
    unknown
339
230
        Not versioned and not matching an ignore pattern.
340
231
 
341
 
    Additionally for directories, symlinks and files with a changed
342
 
    executable bit, Bazaar indicates their type using a trailing
343
 
    character: '/', '@' or '*' respectively. These decorations can be
344
 
    disabled using the '--no-classify' option.
 
232
    Additionally for directories, symlinks and files with an executable
 
233
    bit, Bazaar indicates their type using a trailing character: '/', '@'
 
234
    or '*' respectively.
345
235
 
346
236
    To see ignored files use 'bzr ignored'.  For details on the
347
237
    changes to file texts, use 'bzr diff'.
368
258
    This will produce the same results as calling 'bzr diff --summarize'.
369
259
    """
370
260
 
371
 
    # TODO: --no-recurse/-N, --recurse options
 
261
    # TODO: --no-recurse, --recurse options
372
262
 
373
263
    takes_args = ['file*']
374
264
    takes_options = ['show-ids', 'revision', 'change', 'verbose',
378
268
                            short_name='V'),
379
269
                     Option('no-pending', help='Don\'t show pending merges.',
380
270
                           ),
381
 
                     Option('no-classify',
382
 
                            help='Do not mark object type using indicator.',
383
 
                           ),
384
271
                     ]
385
272
    aliases = ['st', 'stat']
386
273
 
389
276
 
390
277
    @display_command
391
278
    def run(self, show_ids=False, file_list=None, revision=None, short=False,
392
 
            versioned=False, no_pending=False, verbose=False,
393
 
            no_classify=False):
 
279
            versioned=False, no_pending=False, verbose=False):
394
280
        from bzrlib.status import show_tree_status
395
281
 
396
282
        if revision and len(revision) > 2:
397
 
            raise errors.BzrCommandError(gettext('bzr status --revision takes exactly'
398
 
                                         ' one or two revision specifiers'))
 
283
            raise errors.BzrCommandError('bzr status --revision takes exactly'
 
284
                                         ' one or two revision specifiers')
399
285
 
400
286
        tree, relfile_list = WorkingTree.open_containing_paths(file_list)
401
287
        # Avoid asking for specific files when that is not needed.
410
296
        show_tree_status(tree, show_ids=show_ids,
411
297
                         specific_files=relfile_list, revision=revision,
412
298
                         to_file=self.outf, short=short, versioned=versioned,
413
 
                         show_pending=(not no_pending), verbose=verbose,
414
 
                         classify=not no_classify)
 
299
                         show_pending=(not no_pending), verbose=verbose)
415
300
 
416
301
 
417
302
class cmd_cat_revision(Command):
438
323
    @display_command
439
324
    def run(self, revision_id=None, revision=None, directory=u'.'):
440
325
        if revision_id is not None and revision is not None:
441
 
            raise errors.BzrCommandError(gettext('You can only supply one of'
442
 
                                         ' revision_id or --revision'))
 
326
            raise errors.BzrCommandError('You can only supply one of'
 
327
                                         ' revision_id or --revision')
443
328
        if revision_id is None and revision is None:
444
 
            raise errors.BzrCommandError(gettext('You must supply either'
445
 
                                         ' --revision or a revision_id'))
 
329
            raise errors.BzrCommandError('You must supply either'
 
330
                                         ' --revision or a revision_id')
446
331
 
447
 
        b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
 
332
        b = bzrdir.BzrDir.open_containing_tree_or_branch(directory)[1]
448
333
 
449
334
        revisions = b.repository.revisions
450
335
        if revisions is None:
451
 
            raise errors.BzrCommandError(gettext('Repository %r does not support '
452
 
                'access to raw revision texts'))
 
336
            raise errors.BzrCommandError('Repository %r does not support '
 
337
                'access to raw revision texts')
453
338
 
454
339
        b.repository.lock_read()
455
340
        try:
459
344
                try:
460
345
                    self.print_revision(revisions, revision_id)
461
346
                except errors.NoSuchRevision:
462
 
                    msg = gettext("The repository {0} contains no revision {1}.").format(
 
347
                    msg = "The repository %s contains no revision %s." % (
463
348
                        b.repository.base, revision_id)
464
349
                    raise errors.BzrCommandError(msg)
465
350
            elif revision is not None:
466
351
                for rev in revision:
467
352
                    if rev is None:
468
353
                        raise errors.BzrCommandError(
469
 
                            gettext('You cannot specify a NULL revision.'))
 
354
                            'You cannot specify a NULL revision.')
470
355
                    rev_id = rev.as_revision_id(b)
471
356
                    self.print_revision(revisions, rev_id)
472
357
        finally:
578
463
            location_list=['.']
579
464
 
580
465
        for location in location_list:
581
 
            d = controldir.ControlDir.open(location)
582
 
 
 
466
            d = bzrdir.BzrDir.open(location)
 
467
            
583
468
            try:
584
469
                working = d.open_workingtree()
585
470
            except errors.NoWorkingTree:
586
 
                raise errors.BzrCommandError(gettext("No working tree to remove"))
 
471
                raise errors.BzrCommandError("No working tree to remove")
587
472
            except errors.NotLocalUrl:
588
 
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
589
 
                                             " of a remote path"))
 
473
                raise errors.BzrCommandError("You cannot remove the working tree"
 
474
                                             " of a remote path")
590
475
            if not force:
591
476
                if (working.has_changes()):
592
477
                    raise errors.UncommittedChanges(working)
594
479
                    raise errors.ShelvedChanges(working)
595
480
 
596
481
            if working.user_url != working.branch.user_url:
597
 
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
598
 
                                             " from a lightweight checkout"))
 
482
                raise errors.BzrCommandError("You cannot remove the working tree"
 
483
                                             " from a lightweight checkout")
599
484
 
600
485
            d.destroy_workingtree()
601
486
 
633
518
                pass # There seems to be a real error here, so we'll reset
634
519
            else:
635
520
                # Refuse
636
 
                raise errors.BzrCommandError(gettext(
 
521
                raise errors.BzrCommandError(
637
522
                    'The tree does not appear to be corrupt. You probably'
638
523
                    ' want "bzr revert" instead. Use "--force" if you are'
639
 
                    ' sure you want to reset the working tree.'))
 
524
                    ' sure you want to reset the working tree.')
640
525
        if revision is None:
641
526
            revision_ids = None
642
527
        else:
645
530
            tree.reset_state(revision_ids)
646
531
        except errors.BzrError, e:
647
532
            if revision_ids is None:
648
 
                extra = (gettext(', the header appears corrupt, try passing -r -1'
649
 
                         ' to set the state to the last commit'))
 
533
                extra = (', the header appears corrupt, try passing -r -1'
 
534
                         ' to set the state to the last commit')
650
535
            else:
651
536
                extra = ''
652
 
            raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
 
537
            raise errors.BzrCommandError('failed to reset the tree state'
 
538
                                         + extra)
653
539
 
654
540
 
655
541
class cmd_revno(Command):
661
547
    _see_also = ['info']
662
548
    takes_args = ['location?']
663
549
    takes_options = [
664
 
        Option('tree', help='Show revno of working tree.'),
665
 
        'revision',
 
550
        Option('tree', help='Show revno of working tree'),
666
551
        ]
667
552
 
668
553
    @display_command
669
 
    def run(self, tree=False, location=u'.', revision=None):
670
 
        if revision is not None and tree:
671
 
            raise errors.BzrCommandError(gettext("--tree and --revision can "
672
 
                "not be used together"))
673
 
 
 
554
    def run(self, tree=False, location=u'.'):
674
555
        if tree:
675
556
            try:
676
557
                wt = WorkingTree.open_containing(location)[0]
677
558
                self.add_cleanup(wt.lock_read().unlock)
678
559
            except (errors.NoWorkingTree, errors.NotLocalUrl):
679
560
                raise errors.NoWorkingTree(location)
680
 
            b = wt.branch
681
561
            revid = wt.last_revision()
 
562
            try:
 
563
                revno_t = wt.branch.revision_id_to_dotted_revno(revid)
 
564
            except errors.NoSuchRevision:
 
565
                revno_t = ('???',)
 
566
            revno = ".".join(str(n) for n in revno_t)
682
567
        else:
683
568
            b = Branch.open_containing(location)[0]
684
569
            self.add_cleanup(b.lock_read().unlock)
685
 
            if revision:
686
 
                if len(revision) != 1:
687
 
                    raise errors.BzrCommandError(gettext(
688
 
                        "Revision numbers only make sense for single "
689
 
                        "revisions, not ranges"))
690
 
                revid = revision[0].as_revision_id(b)
691
 
            else:
692
 
                revid = b.last_revision()
693
 
        try:
694
 
            revno_t = b.revision_id_to_dotted_revno(revid)
695
 
        except errors.NoSuchRevision:
696
 
            revno_t = ('???',)
697
 
        revno = ".".join(str(n) for n in revno_t)
 
570
            revno = b.revno()
698
571
        self.cleanup_now()
699
 
        self.outf.write(revno + '\n')
 
572
        self.outf.write(str(revno) + '\n')
700
573
 
701
574
 
702
575
class cmd_revision_info(Command):
709
582
        custom_help('directory',
710
583
            help='Branch to examine, '
711
584
                 'rather than the one containing the working directory.'),
712
 
        Option('tree', help='Show revno of working tree.'),
 
585
        Option('tree', help='Show revno of working tree'),
713
586
        ]
714
587
 
715
588
    @display_command
771
644
    are added.  This search proceeds recursively into versioned
772
645
    directories.  If no names are given '.' is assumed.
773
646
 
774
 
    A warning will be printed when nested trees are encountered,
775
 
    unless they are explicitly ignored.
776
 
 
777
647
    Therefore simply saying 'bzr add' will version all files that
778
648
    are currently unknown.
779
649
 
795
665
    
796
666
    Any files matching patterns in the ignore list will not be added
797
667
    unless they are explicitly mentioned.
798
 
    
799
 
    In recursive mode, files larger than the configuration option 
800
 
    add.maximum_file_size will be skipped. Named items are never skipped due
801
 
    to file size.
802
668
    """
803
669
    takes_args = ['file*']
804
670
    takes_options = [
805
671
        Option('no-recurse',
806
 
               help="Don't recursively add the contents of directories.",
807
 
               short_name='N'),
 
672
               help="Don't recursively add the contents of directories."),
808
673
        Option('dry-run',
809
674
               help="Show what would be done, but don't actually do anything."),
810
675
        'verbose',
832
697
            action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
833
698
                          to_file=self.outf, should_print=(not is_quiet()))
834
699
        else:
835
 
            action = bzrlib.add.AddWithSkipLargeAction(to_file=self.outf,
 
700
            action = bzrlib.add.AddAction(to_file=self.outf,
836
701
                should_print=(not is_quiet()))
837
702
 
838
703
        if base_tree:
845
710
            if verbose:
846
711
                for glob in sorted(ignored.keys()):
847
712
                    for path in ignored[glob]:
848
 
                        self.outf.write(
849
 
                         gettext("ignored {0} matching \"{1}\"\n").format(
850
 
                         path, glob))
 
713
                        self.outf.write("ignored %s matching \"%s\"\n"
 
714
                                        % (path, glob))
851
715
 
852
716
 
853
717
class cmd_mkdir(Command):
857
721
    """
858
722
 
859
723
    takes_args = ['dir+']
860
 
    takes_options = [
861
 
        Option(
862
 
            'parents',
863
 
            help='No error if existing, make parent directories as needed.',
864
 
            short_name='p'
865
 
            )
866
 
        ]
867
724
    encoding_type = 'replace'
868
725
 
869
 
    @classmethod
870
 
    def add_file_with_parents(cls, wt, relpath):
871
 
        if wt.path2id(relpath) is not None:
872
 
            return
873
 
        cls.add_file_with_parents(wt, osutils.dirname(relpath))
874
 
        wt.add([relpath])
875
 
 
876
 
    @classmethod
877
 
    def add_file_single(cls, wt, relpath):
878
 
        wt.add([relpath])
879
 
 
880
 
    def run(self, dir_list, parents=False):
881
 
        if parents:
882
 
            add_file = self.add_file_with_parents
883
 
        else:
884
 
            add_file = self.add_file_single
885
 
        for dir in dir_list:
886
 
            wt, relpath = WorkingTree.open_containing(dir)
887
 
            if parents:
888
 
                try:
889
 
                    os.makedirs(dir)
890
 
                except OSError, e:
891
 
                    if e.errno != errno.EEXIST:
892
 
                        raise
 
726
    def run(self, dir_list):
 
727
        for d in dir_list:
 
728
            wt, dd = WorkingTree.open_containing(d)
 
729
            base = os.path.dirname(dd)
 
730
            id = wt.path2id(base)
 
731
            if id != None:
 
732
                os.mkdir(d)
 
733
                wt.add([dd])
 
734
                self.outf.write('added %s\n' % d)
893
735
            else:
894
 
                os.mkdir(dir)
895
 
            add_file(wt, relpath)
896
 
            if not is_quiet():
897
 
                self.outf.write(gettext('added %s\n') % dir)
 
736
                raise errors.NotVersionedError(path=base)
898
737
 
899
738
 
900
739
class cmd_relpath(Command):
936
775
    @display_command
937
776
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
938
777
        if kind and kind not in ['file', 'directory', 'symlink']:
939
 
            raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
 
778
            raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
940
779
 
941
780
        revision = _get_one_revision('inventory', revision)
942
781
        work_tree, file_list = WorkingTree.open_containing_paths(file_list)
950
789
            tree = work_tree
951
790
            extra_trees = []
952
791
 
953
 
        self.add_cleanup(tree.lock_read().unlock)
954
792
        if file_list is not None:
955
793
            file_ids = tree.paths2ids(file_list, trees=extra_trees,
956
794
                                      require_versioned=True)
957
795
            # find_ids_across_trees may include some paths that don't
958
796
            # exist in 'tree'.
959
 
            entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
 
797
            entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
 
798
                             for file_id in file_ids if file_id in tree)
960
799
        else:
961
 
            entries = tree.iter_entries_by_dir()
 
800
            entries = tree.inventory.entries()
962
801
 
963
 
        for path, entry in sorted(entries):
 
802
        self.cleanup_now()
 
803
        for path, entry in entries:
964
804
            if kind and kind != entry.kind:
965
805
                continue
966
 
            if path == "":
967
 
                continue
968
806
            if show_ids:
969
807
                self.outf.write('%-50s %s\n' % (path, entry.file_id))
970
808
            else:
1006
844
        if auto:
1007
845
            return self.run_auto(names_list, after, dry_run)
1008
846
        elif dry_run:
1009
 
            raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
 
847
            raise errors.BzrCommandError('--dry-run requires --auto.')
1010
848
        if names_list is None:
1011
849
            names_list = []
1012
850
        if len(names_list) < 2:
1013
 
            raise errors.BzrCommandError(gettext("missing file argument"))
 
851
            raise errors.BzrCommandError("missing file argument")
1014
852
        tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
1015
 
        for file_name in rel_names[0:-1]:
1016
 
            if file_name == '':
1017
 
                raise errors.BzrCommandError(gettext("can not move root of branch"))
1018
853
        self.add_cleanup(tree.lock_tree_write().unlock)
1019
854
        self._run(tree, names_list, rel_names, after)
1020
855
 
1021
856
    def run_auto(self, names_list, after, dry_run):
1022
857
        if names_list is not None and len(names_list) > 1:
1023
 
            raise errors.BzrCommandError(gettext('Only one path may be specified to'
1024
 
                                         ' --auto.'))
 
858
            raise errors.BzrCommandError('Only one path may be specified to'
 
859
                                         ' --auto.')
1025
860
        if after:
1026
 
            raise errors.BzrCommandError(gettext('--after cannot be specified with'
1027
 
                                         ' --auto.'))
 
861
            raise errors.BzrCommandError('--after cannot be specified with'
 
862
                                         ' --auto.')
1028
863
        work_tree, file_list = WorkingTree.open_containing_paths(
1029
864
            names_list, default_directory='.')
1030
865
        self.add_cleanup(work_tree.lock_tree_write().unlock)
1042
877
                and rel_names[0].lower() == rel_names[1].lower()):
1043
878
                into_existing = False
1044
879
            else:
 
880
                inv = tree.inventory
1045
881
                # 'fix' the case of a potential 'from'
1046
882
                from_id = tree.path2id(
1047
883
                            tree.get_canonical_inventory_path(rel_names[0]))
1048
884
                if (not osutils.lexists(names_list[0]) and
1049
 
                    from_id and tree.stored_kind(from_id) == "directory"):
 
885
                    from_id and inv.get_file_kind(from_id) == "directory"):
1050
886
                    into_existing = False
1051
887
        # move/rename
1052
888
        if into_existing:
1059
895
                    self.outf.write("%s => %s\n" % (src, dest))
1060
896
        else:
1061
897
            if len(names_list) != 2:
1062
 
                raise errors.BzrCommandError(gettext('to mv multiple files the'
 
898
                raise errors.BzrCommandError('to mv multiple files the'
1063
899
                                             ' destination must be a versioned'
1064
 
                                             ' directory'))
 
900
                                             ' directory')
1065
901
 
1066
902
            # for cicp file-systems: the src references an existing inventory
1067
903
            # item:
1126
962
    match the remote one, use pull --overwrite. This will work even if the two
1127
963
    branches have diverged.
1128
964
 
1129
 
    If there is no default location set, the first pull will set it (use
1130
 
    --no-remember to avoid setting it). After that, you can omit the
1131
 
    location to use the default.  To change the default, use --remember. The
1132
 
    value will only be saved if the remote location can be accessed.
1133
 
 
1134
 
    The --verbose option will display the revisions pulled using the log_format
1135
 
    configuration option. You can use a different format by overriding it with
1136
 
    -Olog_format=<other_format>.
 
965
    If there is no default location set, the first pull will set it.  After
 
966
    that, you can omit the location to use the default.  To change the
 
967
    default, use --remember. The value will only be saved if the remote
 
968
    location can be accessed.
1137
969
 
1138
970
    Note: The location can be specified either in the form of a branch,
1139
971
    or in the form of a path to a file containing a merge directive generated
1153
985
                 "the master branch."
1154
986
            ),
1155
987
        Option('show-base',
1156
 
            help="Show base revision text in conflicts."),
1157
 
        Option('overwrite-tags',
1158
 
            help="Overwrite tags only."),
 
988
            help="Show base revision text in conflicts.")
1159
989
        ]
1160
990
    takes_args = ['location?']
1161
991
    encoding_type = 'replace'
1162
992
 
1163
 
    def run(self, location=None, remember=None, overwrite=False,
 
993
    def run(self, location=None, remember=False, overwrite=False,
1164
994
            revision=None, verbose=False,
1165
995
            directory=None, local=False,
1166
 
            show_base=False, overwrite_tags=False):
1167
 
 
1168
 
        if overwrite:
1169
 
            overwrite = ["history", "tags"]
1170
 
        elif overwrite_tags:
1171
 
            overwrite = ["tags"]
1172
 
        else:
1173
 
            overwrite = []
 
996
            show_base=False):
1174
997
        # FIXME: too much stuff is in the command class
1175
998
        revision_id = None
1176
999
        mergeable = None
1184
1007
            tree_to = None
1185
1008
            branch_to = Branch.open_containing(directory)[0]
1186
1009
            self.add_cleanup(branch_to.lock_write().unlock)
1187
 
            if show_base:
1188
 
                warning(gettext("No working tree, ignoring --show-base"))
 
1010
 
 
1011
        if tree_to is None and show_base:
 
1012
            raise errors.BzrCommandError("Need working tree for --show-base.")
1189
1013
 
1190
1014
        if local and not branch_to.get_bound_location():
1191
1015
            raise errors.LocalRequiresBoundBranch()
1201
1025
        stored_loc = branch_to.get_parent()
1202
1026
        if location is None:
1203
1027
            if stored_loc is None:
1204
 
                raise errors.BzrCommandError(gettext("No pull location known or"
1205
 
                                             " specified."))
 
1028
                raise errors.BzrCommandError("No pull location known or"
 
1029
                                             " specified.")
1206
1030
            else:
1207
1031
                display_url = urlutils.unescape_for_display(stored_loc,
1208
1032
                        self.outf.encoding)
1209
1033
                if not is_quiet():
1210
 
                    self.outf.write(gettext("Using saved parent location: %s\n") % display_url)
 
1034
                    self.outf.write("Using saved parent location: %s\n" % display_url)
1211
1035
                location = stored_loc
1212
1036
 
1213
1037
        revision = _get_one_revision('pull', revision)
1214
1038
        if mergeable is not None:
1215
1039
            if revision is not None:
1216
 
                raise errors.BzrCommandError(gettext(
1217
 
                    'Cannot use -r with merge directives or bundles'))
 
1040
                raise errors.BzrCommandError(
 
1041
                    'Cannot use -r with merge directives or bundles')
1218
1042
            mergeable.install_revisions(branch_to.repository)
1219
1043
            base_revision_id, revision_id, verified = \
1220
1044
                mergeable.get_merge_request(branch_to.repository)
1223
1047
            branch_from = Branch.open(location,
1224
1048
                possible_transports=possible_transports)
1225
1049
            self.add_cleanup(branch_from.lock_read().unlock)
1226
 
            # Remembers if asked explicitly or no previous location is set
1227
 
            if (remember
1228
 
                or (remember is None and branch_to.get_parent() is None)):
1229
 
                # FIXME: This shouldn't be done before the pull
1230
 
                # succeeds... -- vila 2012-01-02
 
1050
 
 
1051
            if branch_to.get_parent() is None or remember:
1231
1052
                branch_to.set_parent(branch_from.base)
1232
1053
 
1233
1054
        if revision is not None:
1240
1061
                view_info=view_info)
1241
1062
            result = tree_to.pull(
1242
1063
                branch_from, overwrite, revision_id, change_reporter,
1243
 
                local=local, show_base=show_base)
 
1064
                possible_transports=possible_transports, local=local,
 
1065
                show_base=show_base)
1244
1066
        else:
1245
1067
            result = branch_to.pull(
1246
1068
                branch_from, overwrite, revision_id, local=local)
1276
1098
    do a merge (see bzr help merge) from the other branch, and commit that.
1277
1099
    After that you will be able to do a push without '--overwrite'.
1278
1100
 
1279
 
    If there is no default push location set, the first push will set it (use
1280
 
    --no-remember to avoid setting it).  After that, you can omit the
1281
 
    location to use the default.  To change the default, use --remember. The
1282
 
    value will only be saved if the remote location can be accessed.
1283
 
 
1284
 
    The --verbose option will display the revisions pushed using the log_format
1285
 
    configuration option. You can use a different format by overriding it with
1286
 
    -Olog_format=<other_format>.
 
1101
    If there is no default push location set, the first push will set it.
 
1102
    After that, you can omit the location to use the default.  To change the
 
1103
    default, use --remember. The value will only be saved if the remote
 
1104
    location can be accessed.
1287
1105
    """
1288
1106
 
1289
1107
    _see_also = ['pull', 'update', 'working-trees']
1313
1131
        Option('no-tree',
1314
1132
               help="Don't populate the working tree, even for protocols"
1315
1133
               " that support it."),
1316
 
        Option('overwrite-tags',
1317
 
              help="Overwrite tags only."),
1318
1134
        ]
1319
1135
    takes_args = ['location?']
1320
1136
    encoding_type = 'replace'
1321
1137
 
1322
 
    def run(self, location=None, remember=None, overwrite=False,
 
1138
    def run(self, location=None, remember=False, overwrite=False,
1323
1139
        create_prefix=False, verbose=False, revision=None,
1324
1140
        use_existing_dir=False, directory=None, stacked_on=None,
1325
 
        stacked=False, strict=None, no_tree=False,
1326
 
        overwrite_tags=False):
 
1141
        stacked=False, strict=None, no_tree=False):
1327
1142
        from bzrlib.push import _show_push_branch
1328
1143
 
1329
 
        if overwrite:
1330
 
            overwrite = ["history", "tags"]
1331
 
        elif overwrite_tags:
1332
 
            overwrite = ["tags"]
1333
 
        else:
1334
 
            overwrite = []
1335
 
 
1336
1144
        if directory is None:
1337
1145
            directory = '.'
1338
1146
        # Get the source branch
1339
1147
        (tree, br_from,
1340
 
         _unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
 
1148
         _unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1341
1149
        # Get the tip's revision_id
1342
1150
        revision = _get_one_revision('push', revision)
1343
1151
        if revision is not None:
1364
1172
                    # error by the feedback given to them. RBC 20080227.
1365
1173
                    stacked_on = parent_url
1366
1174
            if not stacked_on:
1367
 
                raise errors.BzrCommandError(gettext(
1368
 
                    "Could not determine branch to refer to."))
 
1175
                raise errors.BzrCommandError(
 
1176
                    "Could not determine branch to refer to.")
1369
1177
 
1370
1178
        # Get the destination location
1371
1179
        if location is None:
1372
1180
            stored_loc = br_from.get_push_location()
1373
1181
            if stored_loc is None:
1374
 
                parent_loc = br_from.get_parent()
1375
 
                if parent_loc:
1376
 
                    raise errors.BzrCommandError(gettext(
1377
 
                        "No push location known or specified. To push to the "
1378
 
                        "parent branch (at %s), use 'bzr push :parent'." %
1379
 
                        urlutils.unescape_for_display(parent_loc,
1380
 
                            self.outf.encoding)))
1381
 
                else:
1382
 
                    raise errors.BzrCommandError(gettext(
1383
 
                        "No push location known or specified."))
 
1182
                raise errors.BzrCommandError(
 
1183
                    "No push location known or specified.")
1384
1184
            else:
1385
1185
                display_url = urlutils.unescape_for_display(stored_loc,
1386
1186
                        self.outf.encoding)
1387
 
                note(gettext("Using saved push location: %s") % display_url)
 
1187
                self.outf.write("Using saved push location: %s\n" % display_url)
1388
1188
                location = stored_loc
1389
1189
 
1390
1190
        _show_push_branch(br_from, revision_id, location, self.outf,
1448
1248
                deprecated_name=self.invoked_as,
1449
1249
                recommended_name='branch',
1450
1250
                deprecated_in_version='2.4')
1451
 
        accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
 
1251
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1452
1252
            from_location)
1453
1253
        if not (hardlink or files_from):
1454
1254
            # accelerator_tree is usually slower because you have to read N
1467
1267
            # RBC 20060209
1468
1268
            revision_id = br_from.last_revision()
1469
1269
        if to_location is None:
1470
 
            to_location = getattr(br_from, "name", None)
1471
 
            if not to_location:
1472
 
                to_location = urlutils.derive_to_location(from_location)
 
1270
            to_location = urlutils.derive_to_location(from_location)
1473
1271
        to_transport = transport.get_transport(to_location)
1474
1272
        try:
1475
1273
            to_transport.mkdir('.')
1476
1274
        except errors.FileExists:
1477
 
            try:
1478
 
                to_dir = controldir.ControlDir.open_from_transport(
1479
 
                    to_transport)
1480
 
            except errors.NotBranchError:
1481
 
                if not use_existing_dir:
1482
 
                    raise errors.BzrCommandError(gettext('Target directory "%s" '
1483
 
                        'already exists.') % to_location)
1484
 
                else:
1485
 
                    to_dir = None
 
1275
            if not use_existing_dir:
 
1276
                raise errors.BzrCommandError('Target directory "%s" '
 
1277
                    'already exists.' % to_location)
1486
1278
            else:
1487
1279
                try:
1488
 
                    to_dir.open_branch()
 
1280
                    bzrdir.BzrDir.open_from_transport(to_transport)
1489
1281
                except errors.NotBranchError:
1490
1282
                    pass
1491
1283
                else:
1492
1284
                    raise errors.AlreadyBranchError(to_location)
1493
1285
        except errors.NoSuchFile:
1494
 
            raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
 
1286
            raise errors.BzrCommandError('Parent of "%s" does not exist.'
1495
1287
                                         % to_location)
1496
 
        else:
1497
 
            to_dir = None
1498
 
        if to_dir is None:
1499
 
            try:
1500
 
                # preserve whatever source format we have.
1501
 
                to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1502
 
                                            possible_transports=[to_transport],
1503
 
                                            accelerator_tree=accelerator_tree,
1504
 
                                            hardlink=hardlink, stacked=stacked,
1505
 
                                            force_new_repo=standalone,
1506
 
                                            create_tree_if_local=not no_tree,
1507
 
                                            source_branch=br_from)
1508
 
                branch = to_dir.open_branch(
1509
 
                    possible_transports=[
1510
 
                        br_from.bzrdir.root_transport, to_transport])
1511
 
            except errors.NoSuchRevision:
1512
 
                to_transport.delete_tree('.')
1513
 
                msg = gettext("The branch {0} has no revision {1}.").format(
1514
 
                    from_location, revision)
1515
 
                raise errors.BzrCommandError(msg)
1516
 
        else:
1517
 
            try:
1518
 
                to_repo = to_dir.open_repository()
1519
 
            except errors.NoRepositoryPresent:
1520
 
                to_repo = to_dir.create_repository()
1521
 
            to_repo.fetch(br_from.repository, revision_id=revision_id)
1522
 
            branch = br_from.sprout(to_dir, revision_id=revision_id)
 
1288
        try:
 
1289
            # preserve whatever source format we have.
 
1290
            dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
 
1291
                                        possible_transports=[to_transport],
 
1292
                                        accelerator_tree=accelerator_tree,
 
1293
                                        hardlink=hardlink, stacked=stacked,
 
1294
                                        force_new_repo=standalone,
 
1295
                                        create_tree_if_local=not no_tree,
 
1296
                                        source_branch=br_from)
 
1297
            branch = dir.open_branch()
 
1298
        except errors.NoSuchRevision:
 
1299
            to_transport.delete_tree('.')
 
1300
            msg = "The branch %s has no revision %s." % (from_location,
 
1301
                revision)
 
1302
            raise errors.BzrCommandError(msg)
1523
1303
        _merge_tags_if_possible(br_from, branch)
1524
1304
        # If the source branch is stacked, the new branch may
1525
1305
        # be stacked whether we asked for that explicitly or not.
1526
1306
        # We therefore need a try/except here and not just 'if stacked:'
1527
1307
        try:
1528
 
            note(gettext('Created new stacked branch referring to %s.') %
 
1308
            note('Created new stacked branch referring to %s.' %
1529
1309
                branch.get_stacked_on_url())
1530
1310
        except (errors.NotStacked, errors.UnstackableBranchFormat,
1531
1311
            errors.UnstackableRepositoryFormat), e:
1532
 
            note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
 
1312
            note('Branched %d revision(s).' % branch.revno())
1533
1313
        if bind:
1534
1314
            # Bind to the parent
1535
1315
            parent_branch = Branch.open(from_location)
1536
1316
            branch.bind(parent_branch)
1537
 
            note(gettext('New branch bound to %s') % from_location)
 
1317
            note('New branch bound to %s' % from_location)
1538
1318
        if switch:
1539
1319
            # Switch to the new branch
1540
1320
            wt, _ = WorkingTree.open_containing('.')
1541
1321
            _mod_switch.switch(wt.bzrdir, branch)
1542
 
            note(gettext('Switched to branch: %s'),
 
1322
            note('Switched to branch: %s',
1543
1323
                urlutils.unescape_for_display(branch.base, 'utf-8'))
1544
1324
 
1545
1325
 
1546
 
class cmd_branches(Command):
1547
 
    __doc__ = """List the branches available at the current location.
1548
 
 
1549
 
    This command will print the names of all the branches at the current
1550
 
    location.
1551
 
    """
1552
 
 
1553
 
    takes_args = ['location?']
1554
 
    takes_options = [
1555
 
                  Option('recursive', short_name='R',
1556
 
                         help='Recursively scan for branches rather than '
1557
 
                              'just looking in the specified location.')]
1558
 
 
1559
 
    def run(self, location=".", recursive=False):
1560
 
        if recursive:
1561
 
            t = transport.get_transport(location)
1562
 
            if not t.listable():
1563
 
                raise errors.BzrCommandError(
1564
 
                    "Can't scan this type of location.")
1565
 
            for b in controldir.ControlDir.find_branches(t):
1566
 
                self.outf.write("%s\n" % urlutils.unescape_for_display(
1567
 
                    urlutils.relative_url(t.base, b.base),
1568
 
                    self.outf.encoding).rstrip("/"))
1569
 
        else:
1570
 
            dir = controldir.ControlDir.open_containing(location)[0]
1571
 
            try:
1572
 
                active_branch = dir.open_branch(name="")
1573
 
            except errors.NotBranchError:
1574
 
                active_branch = None
1575
 
            names = {}
1576
 
            for name, branch in iter_sibling_branches(dir):
1577
 
                if name == "":
1578
 
                    continue
1579
 
                active = (active_branch is not None and
1580
 
                          active_branch.base == branch.base)
1581
 
                names[name] = active
1582
 
            # Only mention the current branch explicitly if it's not
1583
 
            # one of the colocated branches
1584
 
            if not any(names.values()) and active_branch is not None:
1585
 
                self.outf.write("* %s\n" % gettext("(default)"))
1586
 
            for name in sorted(names.keys()):
1587
 
                active = names[name]
1588
 
                if active:
1589
 
                    prefix = "*"
1590
 
                else:
1591
 
                    prefix = " "
1592
 
                self.outf.write("%s %s\n" % (
1593
 
                    prefix, name.encode(self.outf.encoding)))
1594
 
 
1595
 
 
1596
1326
class cmd_checkout(Command):
1597
1327
    __doc__ = """Create a new checkout of an existing branch.
1598
1328
 
1614
1344
    code.)
1615
1345
    """
1616
1346
 
1617
 
    _see_also = ['checkouts', 'branch', 'working-trees', 'remove-tree']
 
1347
    _see_also = ['checkouts', 'branch']
1618
1348
    takes_args = ['branch_location?', 'to_location?']
1619
1349
    takes_options = ['revision',
1620
1350
                     Option('lightweight',
1637
1367
        if branch_location is None:
1638
1368
            branch_location = osutils.getcwd()
1639
1369
            to_location = branch_location
1640
 
        accelerator_tree, source = controldir.ControlDir.open_tree_or_branch(
 
1370
        accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1641
1371
            branch_location)
1642
1372
        if not (hardlink or files_from):
1643
1373
            # accelerator_tree is usually slower because you have to read N
1680
1410
    def run(self, dir=u'.'):
1681
1411
        tree = WorkingTree.open_containing(dir)[0]
1682
1412
        self.add_cleanup(tree.lock_read().unlock)
 
1413
        new_inv = tree.inventory
1683
1414
        old_tree = tree.basis_tree()
1684
1415
        self.add_cleanup(old_tree.lock_read().unlock)
 
1416
        old_inv = old_tree.inventory
1685
1417
        renames = []
1686
1418
        iterator = tree.iter_changes(old_tree, include_unchanged=True)
1687
1419
        for f, paths, c, v, p, n, k, e in iterator:
1696
1428
 
1697
1429
 
1698
1430
class cmd_update(Command):
1699
 
    __doc__ = """Update a working tree to a new revision.
1700
 
 
1701
 
    This will perform a merge of the destination revision (the tip of the
1702
 
    branch, or the specified revision) into the working tree, and then make
1703
 
    that revision the basis revision for the working tree.  
1704
 
 
1705
 
    You can use this to visit an older revision, or to update a working tree
1706
 
    that is out of date from its branch.
1707
 
    
1708
 
    If there are any uncommitted changes in the tree, they will be carried
1709
 
    across and remain as uncommitted changes after the update.  To discard
1710
 
    these changes, use 'bzr revert'.  The uncommitted changes may conflict
1711
 
    with the changes brought in by the change in basis revision.
1712
 
 
1713
 
    If the tree's branch is bound to a master branch, bzr will also update
 
1431
    __doc__ = """Update a tree to have the latest code committed to its branch.
 
1432
 
 
1433
    This will perform a merge into the working tree, and may generate
 
1434
    conflicts. If you have any local changes, you will still
 
1435
    need to commit them after the update for the update to be complete.
 
1436
 
 
1437
    If you want to discard your local changes, you can just do a
 
1438
    'bzr revert' instead of 'bzr commit' after the update.
 
1439
 
 
1440
    If you want to restore a file that has been removed locally, use
 
1441
    'bzr revert' instead of 'bzr update'.
 
1442
 
 
1443
    If the tree's branch is bound to a master branch, it will also update
1714
1444
    the branch from the master.
1715
 
 
1716
 
    You cannot update just a single file or directory, because each Bazaar
1717
 
    working tree has just a single basis revision.  If you want to restore a
1718
 
    file that has been removed locally, use 'bzr revert' instead of 'bzr
1719
 
    update'.  If you want to restore a file to its state in a previous
1720
 
    revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
1721
 
    out the old content of that file to a new location.
1722
 
 
1723
 
    The 'dir' argument, if given, must be the location of the root of a
1724
 
    working tree to update.  By default, the working tree that contains the 
1725
 
    current working directory is used.
1726
1445
    """
1727
1446
 
1728
1447
    _see_also = ['pull', 'working-trees', 'status-flags']
1733
1452
                     ]
1734
1453
    aliases = ['up']
1735
1454
 
1736
 
    def run(self, dir=None, revision=None, show_base=None):
 
1455
    def run(self, dir='.', revision=None, show_base=None):
1737
1456
        if revision is not None and len(revision) != 1:
1738
 
            raise errors.BzrCommandError(gettext(
1739
 
                "bzr update --revision takes exactly one revision"))
1740
 
        if dir is None:
1741
 
            tree = WorkingTree.open_containing('.')[0]
1742
 
        else:
1743
 
            tree, relpath = WorkingTree.open_containing(dir)
1744
 
            if relpath:
1745
 
                # See bug 557886.
1746
 
                raise errors.BzrCommandError(gettext(
1747
 
                    "bzr update can only update a whole tree, "
1748
 
                    "not a file or subdirectory"))
 
1457
            raise errors.BzrCommandError(
 
1458
                        "bzr update --revision takes exactly one revision")
 
1459
        tree = WorkingTree.open_containing(dir)[0]
1749
1460
        branch = tree.branch
1750
1461
        possible_transports = []
1751
1462
        master = branch.get_master_branch(
1775
1486
            revision_id = branch.last_revision()
1776
1487
        if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1777
1488
            revno = branch.revision_id_to_dotted_revno(revision_id)
1778
 
            note(gettext("Tree is up to date at revision {0} of branch {1}"
1779
 
                        ).format('.'.join(map(str, revno)), branch_location))
 
1489
            note("Tree is up to date at revision %s of branch %s" %
 
1490
                ('.'.join(map(str, revno)), branch_location))
1780
1491
            return 0
1781
1492
        view_info = _get_view_info_for_change_reporter(tree)
1782
1493
        change_reporter = delta._ChangeReporter(
1790
1501
                old_tip=old_tip,
1791
1502
                show_base=show_base)
1792
1503
        except errors.NoSuchRevision, e:
1793
 
            raise errors.BzrCommandError(gettext(
 
1504
            raise errors.BzrCommandError(
1794
1505
                                  "branch has no revision %s\n"
1795
1506
                                  "bzr update --revision only works"
1796
 
                                  " for a revision in the branch history")
 
1507
                                  " for a revision in the branch history"
1797
1508
                                  % (e.revision))
1798
1509
        revno = tree.branch.revision_id_to_dotted_revno(
1799
1510
            _mod_revision.ensure_null(tree.last_revision()))
1800
 
        note(gettext('Updated to revision {0} of branch {1}').format(
1801
 
             '.'.join(map(str, revno)), branch_location))
 
1511
        note('Updated to revision %s of branch %s' %
 
1512
             ('.'.join(map(str, revno)), branch_location))
1802
1513
        parent_ids = tree.get_parent_ids()
1803
1514
        if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1804
 
            note(gettext('Your local commits will now show as pending merges with '
1805
 
                 "'bzr status', and can be committed with 'bzr commit'."))
 
1515
            note('Your local commits will now show as pending merges with '
 
1516
                 "'bzr status', and can be committed with 'bzr commit'.")
1806
1517
        if conflicts != 0:
1807
1518
            return 1
1808
1519
        else:
1849
1560
        else:
1850
1561
            noise_level = 0
1851
1562
        from bzrlib.info import show_bzrdir_info
1852
 
        show_bzrdir_info(controldir.ControlDir.open_containing(location)[0],
 
1563
        show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1853
1564
                         verbose=noise_level, outfile=self.outf)
1854
1565
 
1855
1566
 
1858
1569
 
1859
1570
    This makes Bazaar stop tracking changes to the specified files. Bazaar will
1860
1571
    delete them if they can easily be recovered using revert otherwise they
1861
 
    will be backed up (adding an extension of the form .~#~). If no options or
 
1572
    will be backed up (adding an extention of the form .~#~). If no options or
1862
1573
    parameters are given Bazaar will scan for files that are being tracked by
1863
1574
    Bazaar but missing in your tree and stop tracking them for you.
1864
1575
    """
1870
1581
            title='Deletion Strategy', value_switches=True, enum_switch=False,
1871
1582
            safe='Backup changed files (default).',
1872
1583
            keep='Delete from bzr but leave the working copy.',
1873
 
            no_backup='Don\'t backup changed files.'),
1874
 
        ]
 
1584
            no_backup='Don\'t backup changed files.',
 
1585
            force='Delete all the specified files, even if they can not be '
 
1586
                'recovered and even if they are non-empty directories. '
 
1587
                '(deprecated, use no-backup)')]
1875
1588
    aliases = ['rm', 'del']
1876
1589
    encoding_type = 'replace'
1877
1590
 
1878
1591
    def run(self, file_list, verbose=False, new=False,
1879
1592
        file_deletion_strategy='safe'):
 
1593
        if file_deletion_strategy == 'force':
 
1594
            note("(The --force option is deprecated, rather use --no-backup "
 
1595
                "in future.)")
 
1596
            file_deletion_strategy = 'no-backup'
1880
1597
 
1881
1598
        tree, file_list = WorkingTree.open_containing_paths(file_list)
1882
1599
 
1891
1608
                specific_files=file_list).added
1892
1609
            file_list = sorted([f[0] for f in added], reverse=True)
1893
1610
            if len(file_list) == 0:
1894
 
                raise errors.BzrCommandError(gettext('No matching files.'))
 
1611
                raise errors.BzrCommandError('No matching files.')
1895
1612
        elif file_list is None:
1896
1613
            # missing files show up in iter_changes(basis) as
1897
1614
            # versioned-with-no-kind.
1981
1698
 
1982
1699
    def run(self, branch=".", canonicalize_chks=False):
1983
1700
        from bzrlib.reconcile import reconcile
1984
 
        dir = controldir.ControlDir.open(branch)
 
1701
        dir = bzrdir.BzrDir.open(branch)
1985
1702
        reconcile(dir, canonicalize_chks=canonicalize_chks)
1986
1703
 
1987
1704
 
1996
1713
    @display_command
1997
1714
    def run(self, location="."):
1998
1715
        branch = Branch.open_containing(location)[0]
1999
 
        self.add_cleanup(branch.lock_read().unlock)
2000
 
        graph = branch.repository.get_graph()
2001
 
        history = list(graph.iter_lefthand_ancestry(branch.last_revision(),
2002
 
            [_mod_revision.NULL_REVISION]))
2003
 
        for revid in reversed(history):
 
1716
        for revid in branch.revision_history():
2004
1717
            self.outf.write(revid)
2005
1718
            self.outf.write('\n')
2006
1719
 
2024
1737
            b = wt.branch
2025
1738
            last_revision = wt.last_revision()
2026
1739
 
2027
 
        self.add_cleanup(b.repository.lock_read().unlock)
2028
 
        graph = b.repository.get_graph()
2029
 
        revisions = [revid for revid, parents in
2030
 
            graph.iter_ancestry([last_revision])]
2031
 
        for revision_id in reversed(revisions):
2032
 
            if _mod_revision.is_null(revision_id):
2033
 
                continue
 
1740
        revision_ids = b.repository.get_ancestry(last_revision)
 
1741
        revision_ids.pop(0)
 
1742
        for revision_id in revision_ids:
2034
1743
            self.outf.write(revision_id + '\n')
2035
1744
 
2036
1745
 
2066
1775
         RegistryOption('format',
2067
1776
                help='Specify a format for this branch. '
2068
1777
                'See "help formats".',
2069
 
                lazy_registry=('bzrlib.controldir', 'format_registry'),
2070
 
                converter=lambda name: controldir.format_registry.make_bzrdir(name),
 
1778
                lazy_registry=('bzrlib.bzrdir', 'format_registry'),
 
1779
                converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
2071
1780
                value_switches=True,
2072
1781
                title="Branch format",
2073
1782
                ),
2080
1789
    def run(self, location=None, format=None, append_revisions_only=False,
2081
1790
            create_prefix=False, no_tree=False):
2082
1791
        if format is None:
2083
 
            format = controldir.format_registry.make_bzrdir('default')
 
1792
            format = bzrdir.format_registry.make_bzrdir('default')
2084
1793
        if location is None:
2085
1794
            location = u'.'
2086
1795
 
2095
1804
            to_transport.ensure_base()
2096
1805
        except errors.NoSuchFile:
2097
1806
            if not create_prefix:
2098
 
                raise errors.BzrCommandError(gettext("Parent directory of %s"
 
1807
                raise errors.BzrCommandError("Parent directory of %s"
2099
1808
                    " does not exist."
2100
1809
                    "\nYou may supply --create-prefix to create all"
2101
 
                    " leading parent directories.")
 
1810
                    " leading parent directories."
2102
1811
                    % location)
2103
1812
            to_transport.create_prefix()
2104
1813
 
2105
1814
        try:
2106
 
            a_bzrdir = controldir.ControlDir.open_from_transport(to_transport)
 
1815
            a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
2107
1816
        except errors.NotBranchError:
2108
1817
            # really a NotBzrDir error...
2109
 
            create_branch = controldir.ControlDir.create_branch_convenience
 
1818
            create_branch = bzrdir.BzrDir.create_branch_convenience
2110
1819
            if no_tree:
2111
1820
                force_new_tree = False
2112
1821
            else:
2123
1832
                        raise errors.BranchExistsWithoutWorkingTree(location)
2124
1833
                raise errors.AlreadyBranchError(location)
2125
1834
            branch = a_bzrdir.create_branch()
2126
 
            if not no_tree and not a_bzrdir.has_workingtree():
 
1835
            if not no_tree:
2127
1836
                a_bzrdir.create_workingtree()
2128
1837
        if append_revisions_only:
2129
1838
            try:
2130
1839
                branch.set_append_revisions_only(True)
2131
1840
            except errors.UpgradeRequired:
2132
 
                raise errors.BzrCommandError(gettext('This branch format cannot be set'
2133
 
                    ' to append-revisions-only.  Try --default.'))
 
1841
                raise errors.BzrCommandError('This branch format cannot be set'
 
1842
                    ' to append-revisions-only.  Try --default.')
2134
1843
        if not is_quiet():
2135
1844
            from bzrlib.info import describe_layout, describe_format
2136
1845
            try:
2140
1849
            repository = branch.repository
2141
1850
            layout = describe_layout(repository, branch, tree).lower()
2142
1851
            format = describe_format(a_bzrdir, repository, branch, tree)
2143
 
            self.outf.write(gettext("Created a {0} (format: {1})\n").format(
2144
 
                  layout, format))
 
1852
            self.outf.write("Created a %s (format: %s)\n" % (layout, format))
2145
1853
            if repository.is_shared():
2146
1854
                #XXX: maybe this can be refactored into transport.path_or_url()
2147
1855
                url = repository.bzrdir.root_transport.external_url()
2149
1857
                    url = urlutils.local_path_from_url(url)
2150
1858
                except errors.InvalidURL:
2151
1859
                    pass
2152
 
                self.outf.write(gettext("Using shared repository: %s\n") % url)
 
1860
                self.outf.write("Using shared repository: %s\n" % url)
2153
1861
 
2154
1862
 
2155
1863
class cmd_init_repository(Command):
2185
1893
    takes_options = [RegistryOption('format',
2186
1894
                            help='Specify a format for this repository. See'
2187
1895
                                 ' "bzr help formats" for details.',
2188
 
                            lazy_registry=('bzrlib.controldir', 'format_registry'),
2189
 
                            converter=lambda name: controldir.format_registry.make_bzrdir(name),
 
1896
                            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
 
1897
                            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
2190
1898
                            value_switches=True, title='Repository format'),
2191
1899
                     Option('no-trees',
2192
1900
                             help='Branches in the repository will default to'
2196
1904
 
2197
1905
    def run(self, location, format=None, no_trees=False):
2198
1906
        if format is None:
2199
 
            format = controldir.format_registry.make_bzrdir('default')
 
1907
            format = bzrdir.format_registry.make_bzrdir('default')
2200
1908
 
2201
1909
        if location is None:
2202
1910
            location = '.'
2203
1911
 
2204
1912
        to_transport = transport.get_transport(location)
 
1913
        to_transport.ensure_base()
2205
1914
 
2206
 
        (repo, newdir, require_stacking, repository_policy) = (
2207
 
            format.initialize_on_transport_ex(to_transport,
2208
 
            create_prefix=True, make_working_trees=not no_trees,
2209
 
            shared_repo=True, force_new_repo=True,
2210
 
            use_existing_dir=True,
2211
 
            repo_format_name=format.repository_format.get_format_string()))
 
1915
        newdir = format.initialize_on_transport(to_transport)
 
1916
        repo = newdir.create_repository(shared=True)
 
1917
        repo.set_make_working_trees(not no_trees)
2212
1918
        if not is_quiet():
2213
1919
            from bzrlib.info import show_bzrdir_info
2214
 
            show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
 
1920
            show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
2215
1921
 
2216
1922
 
2217
1923
class cmd_diff(Command):
2328
2034
            help='Diff format to use.',
2329
2035
            lazy_registry=('bzrlib.diff', 'format_registry'),
2330
2036
            title='Diff format'),
2331
 
        Option('context',
2332
 
            help='How many lines of context to show.',
2333
 
            type=int,
2334
 
            ),
2335
2037
        ]
2336
2038
    aliases = ['di', 'dif']
2337
2039
    encoding_type = 'exact'
2338
2040
 
2339
2041
    @display_command
2340
2042
    def run(self, revision=None, file_list=None, diff_options=None,
2341
 
            prefix=None, old=None, new=None, using=None, format=None, 
2342
 
            context=None):
 
2043
            prefix=None, old=None, new=None, using=None, format=None):
2343
2044
        from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
2344
2045
            show_diff_trees)
2345
2046
 
2353
2054
        elif ':' in prefix:
2354
2055
            old_label, new_label = prefix.split(":")
2355
2056
        else:
2356
 
            raise errors.BzrCommandError(gettext(
 
2057
            raise errors.BzrCommandError(
2357
2058
                '--prefix expects two values separated by a colon'
2358
 
                ' (eg "old/:new/")'))
 
2059
                ' (eg "old/:new/")')
2359
2060
 
2360
2061
        if revision and len(revision) > 2:
2361
 
            raise errors.BzrCommandError(gettext('bzr diff --revision takes exactly'
2362
 
                                         ' one or two revision specifiers'))
 
2062
            raise errors.BzrCommandError('bzr diff --revision takes exactly'
 
2063
                                         ' one or two revision specifiers')
2363
2064
 
2364
2065
        if using is not None and format is not None:
2365
 
            raise errors.BzrCommandError(gettext(
2366
 
                '{0} and {1} are mutually exclusive').format(
2367
 
                '--using', '--format'))
 
2066
            raise errors.BzrCommandError('--using and --format are mutually '
 
2067
                'exclusive.')
2368
2068
 
2369
2069
        (old_tree, new_tree,
2370
2070
         old_branch, new_branch,
2378
2078
                               old_label=old_label, new_label=new_label,
2379
2079
                               extra_trees=extra_trees,
2380
2080
                               path_encoding=path_encoding,
2381
 
                               using=using, context=context,
 
2081
                               using=using,
2382
2082
                               format_cls=format)
2383
2083
 
2384
2084
 
2400
2100
        self.add_cleanup(tree.lock_read().unlock)
2401
2101
        old = tree.basis_tree()
2402
2102
        self.add_cleanup(old.lock_read().unlock)
2403
 
        for path, ie in old.iter_entries_by_dir():
 
2103
        for path, ie in old.inventory.iter_entries():
2404
2104
            if not tree.has_id(ie.file_id):
2405
2105
                self.outf.write(path)
2406
2106
                if show_ids:
2444
2144
        self.add_cleanup(wt.lock_read().unlock)
2445
2145
        basis = wt.basis_tree()
2446
2146
        self.add_cleanup(basis.lock_read().unlock)
2447
 
        root_id = wt.get_root_id()
2448
 
        for file_id in wt.all_file_ids():
2449
 
            if basis.has_id(file_id):
2450
 
                continue
2451
 
            if root_id == file_id:
2452
 
                continue
2453
 
            path = wt.id2path(file_id)
 
2147
        basis_inv = basis.inventory
 
2148
        inv = wt.inventory
 
2149
        for file_id in inv:
 
2150
            if file_id in basis_inv:
 
2151
                continue
 
2152
            if inv.is_root(file_id) and len(basis_inv) == 0:
 
2153
                continue
 
2154
            path = inv.id2path(file_id)
2454
2155
            if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2455
2156
                continue
2456
2157
            if null:
2477
2178
    try:
2478
2179
        return int(limitstring)
2479
2180
    except ValueError:
2480
 
        msg = gettext("The limit argument must be an integer.")
 
2181
        msg = "The limit argument must be an integer."
2481
2182
        raise errors.BzrCommandError(msg)
2482
2183
 
2483
2184
 
2485
2186
    try:
2486
2187
        return int(s)
2487
2188
    except ValueError:
2488
 
        msg = gettext("The levels argument must be an integer.")
 
2189
        msg = "The levels argument must be an integer."
2489
2190
        raise errors.BzrCommandError(msg)
2490
2191
 
2491
2192
 
2601
2302
 
2602
2303
    :Other filtering:
2603
2304
 
2604
 
      The --match option can be used for finding revisions that match a
2605
 
      regular expression in a commit message, committer, author or bug.
2606
 
      Specifying the option several times will match any of the supplied
2607
 
      expressions. --match-author, --match-bugs, --match-committer and
2608
 
      --match-message can be used to only match a specific field.
 
2305
      The --message option can be used for finding revisions that match a
 
2306
      regular expression in a commit message.
2609
2307
 
2610
2308
    :Tips & tricks:
2611
2309
 
2671
2369
                   argname='N',
2672
2370
                   type=_parse_levels),
2673
2371
            Option('message',
 
2372
                   short_name='m',
2674
2373
                   help='Show revisions whose message matches this '
2675
2374
                        'regular expression.',
2676
 
                   type=str,
2677
 
                   hidden=True),
 
2375
                   type=str),
2678
2376
            Option('limit',
2679
2377
                   short_name='l',
2680
2378
                   help='Limit the output to the first N revisions.',
2683
2381
            Option('show-diff',
2684
2382
                   short_name='p',
2685
2383
                   help='Show changes made in each revision as a patch.'),
2686
 
            Option('include-merged',
 
2384
            Option('include-merges',
2687
2385
                   help='Show merged revisions like --levels 0 does.'),
2688
 
            Option('include-merges', hidden=True,
2689
 
                   help='Historical alias for --include-merged.'),
2690
 
            Option('omit-merges',
2691
 
                   help='Do not report commits with more than one parent.'),
2692
2386
            Option('exclude-common-ancestry',
2693
2387
                   help='Display only the revisions that are not part'
2694
 
                   ' of both ancestries (require -rX..Y).'
2695
 
                   ),
2696
 
            Option('signatures',
2697
 
                   help='Show digital signature validity.'),
2698
 
            ListOption('match',
2699
 
                short_name='m',
2700
 
                help='Show revisions whose properties match this '
2701
 
                'expression.',
2702
 
                type=str),
2703
 
            ListOption('match-message',
2704
 
                   help='Show revisions whose message matches this '
2705
 
                   'expression.',
2706
 
                type=str),
2707
 
            ListOption('match-committer',
2708
 
                   help='Show revisions whose committer matches this '
2709
 
                   'expression.',
2710
 
                type=str),
2711
 
            ListOption('match-author',
2712
 
                   help='Show revisions whose authors match this '
2713
 
                   'expression.',
2714
 
                type=str),
2715
 
            ListOption('match-bugs',
2716
 
                   help='Show revisions whose bugs match this '
2717
 
                   'expression.',
2718
 
                type=str)
 
2388
                   ' of both ancestries (require -rX..Y)'
 
2389
                   )
2719
2390
            ]
2720
2391
    encoding_type = 'replace'
2721
2392
 
2731
2402
            message=None,
2732
2403
            limit=None,
2733
2404
            show_diff=False,
2734
 
            include_merged=None,
 
2405
            include_merges=False,
2735
2406
            authors=None,
2736
2407
            exclude_common_ancestry=False,
2737
 
            signatures=False,
2738
 
            match=None,
2739
 
            match_message=None,
2740
 
            match_committer=None,
2741
 
            match_author=None,
2742
 
            match_bugs=None,
2743
 
            omit_merges=False,
2744
 
            include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2745
2408
            ):
2746
2409
        from bzrlib.log import (
2747
2410
            Logger,
2749
2412
            _get_info_for_log_files,
2750
2413
            )
2751
2414
        direction = (forward and 'forward') or 'reverse'
2752
 
        if symbol_versioning.deprecated_passed(include_merges):
2753
 
            ui.ui_factory.show_user_warning(
2754
 
                'deprecated_command_option',
2755
 
                deprecated_name='--include-merges',
2756
 
                recommended_name='--include-merged',
2757
 
                deprecated_in_version='2.5',
2758
 
                command=self.invoked_as)
2759
 
            if include_merged is None:
2760
 
                include_merged = include_merges
2761
 
            else:
2762
 
                raise errors.BzrCommandError(gettext(
2763
 
                    '{0} and {1} are mutually exclusive').format(
2764
 
                    '--include-merges', '--include-merged'))
2765
 
        if include_merged is None:
2766
 
            include_merged = False
2767
2415
        if (exclude_common_ancestry
2768
2416
            and (revision is None or len(revision) != 2)):
2769
 
            raise errors.BzrCommandError(gettext(
2770
 
                '--exclude-common-ancestry requires -r with two revisions'))
2771
 
        if include_merged:
 
2417
            raise errors.BzrCommandError(
 
2418
                '--exclude-common-ancestry requires -r with two revisions')
 
2419
        if include_merges:
2772
2420
            if levels is None:
2773
2421
                levels = 0
2774
2422
            else:
2775
 
                raise errors.BzrCommandError(gettext(
2776
 
                    '{0} and {1} are mutually exclusive').format(
2777
 
                    '--levels', '--include-merged'))
 
2423
                raise errors.BzrCommandError(
 
2424
                    '--levels and --include-merges are mutually exclusive')
2778
2425
 
2779
2426
        if change is not None:
2780
2427
            if len(change) > 1:
2781
2428
                raise errors.RangeInChangeOption()
2782
2429
            if revision is not None:
2783
 
                raise errors.BzrCommandError(gettext(
2784
 
                    '{0} and {1} are mutually exclusive').format(
2785
 
                    '--revision', '--change'))
 
2430
                raise errors.BzrCommandError(
 
2431
                    '--revision and --change are mutually exclusive')
2786
2432
            else:
2787
2433
                revision = change
2788
2434
 
2794
2440
                revision, file_list, self.add_cleanup)
2795
2441
            for relpath, file_id, kind in file_info_list:
2796
2442
                if file_id is None:
2797
 
                    raise errors.BzrCommandError(gettext(
2798
 
                        "Path unknown at end or start of revision range: %s") %
 
2443
                    raise errors.BzrCommandError(
 
2444
                        "Path unknown at end or start of revision range: %s" %
2799
2445
                        relpath)
2800
2446
                # If the relpath is the top of the tree, we log everything
2801
2447
                if relpath == '':
2813
2459
                location = revision[0].get_branch()
2814
2460
            else:
2815
2461
                location = '.'
2816
 
            dir, relpath = controldir.ControlDir.open_containing(location)
 
2462
            dir, relpath = bzrdir.BzrDir.open_containing(location)
2817
2463
            b = dir.open_branch()
2818
2464
            self.add_cleanup(b.lock_read().unlock)
2819
2465
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2820
2466
 
2821
 
        if b.get_config_stack().get('validate_signatures_in_log'):
2822
 
            signatures = True
2823
 
 
2824
 
        if signatures:
2825
 
            if not gpg.GPGStrategy.verify_signatures_available():
2826
 
                raise errors.GpgmeNotInstalled(None)
2827
 
 
2828
2467
        # Decide on the type of delta & diff filtering to use
2829
2468
        # TODO: add an --all-files option to make this configurable & consistent
2830
2469
        if not verbose:
2867
2506
        match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2868
2507
            or delta_type or partial_history)
2869
2508
 
2870
 
        match_dict = {}
2871
 
        if match:
2872
 
            match_dict[''] = match
2873
 
        if match_message:
2874
 
            match_dict['message'] = match_message
2875
 
        if match_committer:
2876
 
            match_dict['committer'] = match_committer
2877
 
        if match_author:
2878
 
            match_dict['author'] = match_author
2879
 
        if match_bugs:
2880
 
            match_dict['bugs'] = match_bugs
2881
 
 
2882
2509
        # Build the LogRequest and execute it
2883
2510
        if len(file_ids) == 0:
2884
2511
            file_ids = None
2887
2514
            start_revision=rev1, end_revision=rev2, limit=limit,
2888
2515
            message_search=message, delta_type=delta_type,
2889
2516
            diff_type=diff_type, _match_using_deltas=match_using_deltas,
2890
 
            exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
2891
 
            signature=signatures, omit_merges=omit_merges,
 
2517
            exclude_common_ancestry=exclude_common_ancestry,
2892
2518
            )
2893
2519
        Logger(b, rqst).show(lf)
2894
2520
 
2911
2537
            # b is taken from revision[0].get_branch(), and
2912
2538
            # show_log will use its revision_history. Having
2913
2539
            # different branches will lead to weird behaviors.
2914
 
            raise errors.BzrCommandError(gettext(
 
2540
            raise errors.BzrCommandError(
2915
2541
                "bzr %s doesn't accept two revisions in different"
2916
 
                " branches.") % command_name)
 
2542
                " branches." % command_name)
2917
2543
        if start_spec.spec is None:
2918
2544
            # Avoid loading all the history.
2919
2545
            rev1 = RevisionInfo(branch, None, None)
2927
2553
        else:
2928
2554
            rev2 = end_spec.in_history(branch)
2929
2555
    else:
2930
 
        raise errors.BzrCommandError(gettext(
2931
 
            'bzr %s --revision takes one or two values.') % command_name)
 
2556
        raise errors.BzrCommandError(
 
2557
            'bzr %s --revision takes one or two values.' % command_name)
2932
2558
    return rev1, rev2
2933
2559
 
2934
2560
 
3005
2631
            null=False, kind=None, show_ids=False, path=None, directory=None):
3006
2632
 
3007
2633
        if kind and kind not in ('file', 'directory', 'symlink'):
3008
 
            raise errors.BzrCommandError(gettext('invalid kind specified'))
 
2634
            raise errors.BzrCommandError('invalid kind specified')
3009
2635
 
3010
2636
        if verbose and null:
3011
 
            raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
 
2637
            raise errors.BzrCommandError('Cannot set both --verbose and --null')
3012
2638
        all = not (unknown or versioned or ignored)
3013
2639
 
3014
2640
        selection = {'I':ignored, '?':unknown, 'V':versioned}
3017
2643
            fs_path = '.'
3018
2644
        else:
3019
2645
            if from_root:
3020
 
                raise errors.BzrCommandError(gettext('cannot specify both --from-root'
3021
 
                                             ' and PATH'))
 
2646
                raise errors.BzrCommandError('cannot specify both --from-root'
 
2647
                                             ' and PATH')
3022
2648
            fs_path = path
3023
2649
        tree, branch, relpath = \
3024
2650
            _open_directory_or_containing_tree_or_branch(fs_path, directory)
3040
2666
            if view_files:
3041
2667
                apply_view = True
3042
2668
                view_str = views.view_display_str(view_files)
3043
 
                note(gettext("Ignoring files outside view. View is %s") % view_str)
 
2669
                note("Ignoring files outside view. View is %s" % view_str)
3044
2670
 
3045
2671
        self.add_cleanup(tree.lock_read().unlock)
3046
2672
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
3193
2819
                self.outf.write("%s\n" % pattern)
3194
2820
            return
3195
2821
        if not name_pattern_list:
3196
 
            raise errors.BzrCommandError(gettext("ignore requires at least one "
3197
 
                "NAME_PATTERN or --default-rules."))
 
2822
            raise errors.BzrCommandError("ignore requires at least one "
 
2823
                "NAME_PATTERN or --default-rules.")
3198
2824
        name_pattern_list = [globbing.normalize_pattern(p)
3199
2825
                             for p in name_pattern_list]
3200
2826
        bad_patterns = ''
3201
 
        bad_patterns_count = 0
3202
2827
        for p in name_pattern_list:
3203
2828
            if not globbing.Globster.is_pattern_valid(p):
3204
 
                bad_patterns_count += 1
3205
2829
                bad_patterns += ('\n  %s' % p)
3206
2830
        if bad_patterns:
3207
 
            msg = (ngettext('Invalid ignore pattern found. %s', 
3208
 
                            'Invalid ignore patterns found. %s',
3209
 
                            bad_patterns_count) % bad_patterns)
 
2831
            msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
3210
2832
            ui.ui_factory.show_error(msg)
3211
2833
            raise errors.InvalidPattern('')
3212
2834
        for name_pattern in name_pattern_list:
3213
2835
            if (name_pattern[0] == '/' or
3214
2836
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
3215
 
                raise errors.BzrCommandError(gettext(
3216
 
                    "NAME_PATTERN should not be an absolute path"))
 
2837
                raise errors.BzrCommandError(
 
2838
                    "NAME_PATTERN should not be an absolute path")
3217
2839
        tree, relpath = WorkingTree.open_containing(directory)
3218
2840
        ignores.tree_ignores_add_patterns(tree, name_pattern_list)
3219
2841
        ignored = globbing.Globster(name_pattern_list)
3226
2848
                if ignored.match(filename):
3227
2849
                    matches.append(filename)
3228
2850
        if len(matches) > 0:
3229
 
            self.outf.write(gettext("Warning: the following files are version "
3230
 
                  "controlled and match your ignore pattern:\n%s"
 
2851
            self.outf.write("Warning: the following files are version controlled and"
 
2852
                  " match your ignore pattern:\n%s"
3231
2853
                  "\nThese files will continue to be version controlled"
3232
 
                  " unless you 'bzr remove' them.\n") % ("\n".join(matches),))
 
2854
                  " unless you 'bzr remove' them.\n" % ("\n".join(matches),))
3233
2855
 
3234
2856
 
3235
2857
class cmd_ignored(Command):
3274
2896
        try:
3275
2897
            revno = int(revno)
3276
2898
        except ValueError:
3277
 
            raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
 
2899
            raise errors.BzrCommandError("not a valid revision-number: %r"
3278
2900
                                         % revno)
3279
2901
        revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
3280
2902
        self.outf.write("%s\n" % revid)
3323
2945
        Option('per-file-timestamps',
3324
2946
               help='Set modification time of files to that of the last '
3325
2947
                    'revision in which it was changed.'),
3326
 
        Option('uncommitted',
3327
 
               help='Export the working tree contents rather than that of the '
3328
 
                    'last revision.'),
3329
2948
        ]
3330
2949
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3331
 
        root=None, filters=False, per_file_timestamps=False, uncommitted=False,
3332
 
        directory=u'.'):
 
2950
        root=None, filters=False, per_file_timestamps=False, directory=u'.'):
3333
2951
        from bzrlib.export import export
3334
2952
 
3335
2953
        if branch_or_subdir is None:
3336
 
            branch_or_subdir = directory
3337
 
 
3338
 
        (tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3339
 
            branch_or_subdir)
3340
 
        if tree is not None:
3341
 
            self.add_cleanup(tree.lock_read().unlock)
3342
 
 
3343
 
        if uncommitted:
3344
 
            if tree is None:
3345
 
                raise errors.BzrCommandError(
3346
 
                    gettext("--uncommitted requires a working tree"))
3347
 
            export_tree = tree
 
2954
            tree = WorkingTree.open_containing(directory)[0]
 
2955
            b = tree.branch
 
2956
            subdir = None
3348
2957
        else:
3349
 
            export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
 
2958
            b, subdir = Branch.open_containing(branch_or_subdir)
 
2959
            tree = None
 
2960
 
 
2961
        rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3350
2962
        try:
3351
 
            export(export_tree, dest, format, root, subdir, filtered=filters,
 
2963
            export(rev_tree, dest, format, root, subdir, filtered=filters,
3352
2964
                   per_file_timestamps=per_file_timestamps)
3353
2965
        except errors.NoSuchExportFormat, e:
3354
 
            raise errors.BzrCommandError(
3355
 
                gettext('Unsupported export format: %s') % e.format)
 
2966
            raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
3356
2967
 
3357
2968
 
3358
2969
class cmd_cat(Command):
3378
2989
    def run(self, filename, revision=None, name_from_revision=False,
3379
2990
            filters=False, directory=None):
3380
2991
        if revision is not None and len(revision) != 1:
3381
 
            raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
3382
 
                                         " one revision specifier"))
 
2992
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
 
2993
                                         " one revision specifier")
3383
2994
        tree, branch, relpath = \
3384
2995
            _open_directory_or_containing_tree_or_branch(filename, directory)
3385
2996
        self.add_cleanup(branch.lock_read().unlock)
3395
3006
 
3396
3007
        old_file_id = rev_tree.path2id(relpath)
3397
3008
 
3398
 
        # TODO: Split out this code to something that generically finds the
3399
 
        # best id for a path across one or more trees; it's like
3400
 
        # find_ids_across_trees but restricted to find just one. -- mbp
3401
 
        # 20110705.
3402
3009
        if name_from_revision:
3403
3010
            # Try in revision if requested
3404
3011
            if old_file_id is None:
3405
 
                raise errors.BzrCommandError(gettext(
3406
 
                    "{0!r} is not present in revision {1}").format(
 
3012
                raise errors.BzrCommandError(
 
3013
                    "%r is not present in revision %s" % (
3407
3014
                        filename, rev_tree.get_revision_id()))
3408
3015
            else:
3409
 
                actual_file_id = old_file_id
 
3016
                content = rev_tree.get_file_text(old_file_id)
3410
3017
        else:
3411
3018
            cur_file_id = tree.path2id(relpath)
3412
 
            if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3413
 
                actual_file_id = cur_file_id
3414
 
            elif old_file_id is not None:
3415
 
                actual_file_id = old_file_id
3416
 
            else:
3417
 
                raise errors.BzrCommandError(gettext(
3418
 
                    "{0!r} is not present in revision {1}").format(
 
3019
            found = False
 
3020
            if cur_file_id is not None:
 
3021
                # Then try with the actual file id
 
3022
                try:
 
3023
                    content = rev_tree.get_file_text(cur_file_id)
 
3024
                    found = True
 
3025
                except errors.NoSuchId:
 
3026
                    # The actual file id didn't exist at that time
 
3027
                    pass
 
3028
            if not found and old_file_id is not None:
 
3029
                # Finally try with the old file id
 
3030
                content = rev_tree.get_file_text(old_file_id)
 
3031
                found = True
 
3032
            if not found:
 
3033
                # Can't be found anywhere
 
3034
                raise errors.BzrCommandError(
 
3035
                    "%r is not present in revision %s" % (
3419
3036
                        filename, rev_tree.get_revision_id()))
3420
3037
        if filtered:
3421
 
            from bzrlib.filter_tree import ContentFilterTree
3422
 
            filter_tree = ContentFilterTree(rev_tree,
3423
 
                rev_tree._content_filter_stack)
3424
 
            content = filter_tree.get_file_text(actual_file_id)
 
3038
            from bzrlib.filters import (
 
3039
                ContentFilterContext,
 
3040
                filtered_output_bytes,
 
3041
                )
 
3042
            filters = rev_tree._content_filter_stack(relpath)
 
3043
            chunks = content.splitlines(True)
 
3044
            content = filtered_output_bytes(chunks, filters,
 
3045
                ContentFilterContext(relpath, rev_tree))
 
3046
            self.cleanup_now()
 
3047
            self.outf.writelines(content)
3425
3048
        else:
3426
 
            content = rev_tree.get_file_text(actual_file_id)
3427
 
        self.cleanup_now()
3428
 
        self.outf.write(content)
 
3049
            self.cleanup_now()
 
3050
            self.outf.write(content)
3429
3051
 
3430
3052
 
3431
3053
class cmd_local_time_offset(Command):
3538
3160
    aliases = ['ci', 'checkin']
3539
3161
 
3540
3162
    def _iter_bug_fix_urls(self, fixes, branch):
3541
 
        default_bugtracker  = None
3542
3163
        # Configure the properties for bug fixing attributes.
3543
3164
        for fixed_bug in fixes:
3544
3165
            tokens = fixed_bug.split(':')
3545
 
            if len(tokens) == 1:
3546
 
                if default_bugtracker is None:
3547
 
                    branch_config = branch.get_config_stack()
3548
 
                    default_bugtracker = branch_config.get(
3549
 
                        "bugtracker")
3550
 
                if default_bugtracker is None:
3551
 
                    raise errors.BzrCommandError(gettext(
3552
 
                        "No tracker specified for bug %s. Use the form "
3553
 
                        "'tracker:id' or specify a default bug tracker "
3554
 
                        "using the `bugtracker` option.\nSee "
3555
 
                        "\"bzr help bugs\" for more information on this "
3556
 
                        "feature. Commit refused.") % fixed_bug)
3557
 
                tag = default_bugtracker
3558
 
                bug_id = tokens[0]
3559
 
            elif len(tokens) != 2:
3560
 
                raise errors.BzrCommandError(gettext(
 
3166
            if len(tokens) != 2:
 
3167
                raise errors.BzrCommandError(
3561
3168
                    "Invalid bug %s. Must be in the form of 'tracker:id'. "
3562
3169
                    "See \"bzr help bugs\" for more information on this "
3563
 
                    "feature.\nCommit refused.") % fixed_bug)
3564
 
            else:
3565
 
                tag, bug_id = tokens
 
3170
                    "feature.\nCommit refused." % fixed_bug)
 
3171
            tag, bug_id = tokens
3566
3172
            try:
3567
3173
                yield bugtracker.get_bug_url(tag, branch, bug_id)
3568
3174
            except errors.UnknownBugTrackerAbbreviation:
3569
 
                raise errors.BzrCommandError(gettext(
3570
 
                    'Unrecognized bug %s. Commit refused.') % fixed_bug)
 
3175
                raise errors.BzrCommandError(
 
3176
                    'Unrecognized bug %s. Commit refused.' % fixed_bug)
3571
3177
            except errors.MalformedBugIdentifier, e:
3572
 
                raise errors.BzrCommandError(gettext(
3573
 
                    "%s\nCommit refused.") % (str(e),))
 
3178
                raise errors.BzrCommandError(
 
3179
                    "%s\nCommit refused." % (str(e),))
3574
3180
 
3575
3181
    def run(self, message=None, file=None, verbose=False, selected_list=None,
3576
3182
            unchanged=False, strict=False, local=False, fixes=None,
3584
3190
        from bzrlib.msgeditor import (
3585
3191
            edit_commit_message_encoded,
3586
3192
            generate_commit_message_template,
3587
 
            make_commit_message_template_encoded,
3588
 
            set_commit_message,
 
3193
            make_commit_message_template_encoded
3589
3194
        )
3590
3195
 
3591
3196
        commit_stamp = offset = None
3593
3198
            try:
3594
3199
                commit_stamp, offset = timestamp.parse_patch_date(commit_time)
3595
3200
            except ValueError, e:
3596
 
                raise errors.BzrCommandError(gettext(
3597
 
                    "Could not parse --commit-time: " + str(e)))
 
3201
                raise errors.BzrCommandError(
 
3202
                    "Could not parse --commit-time: " + str(e))
3598
3203
 
3599
3204
        properties = {}
3600
3205
 
3633
3238
                message = message.replace('\r\n', '\n')
3634
3239
                message = message.replace('\r', '\n')
3635
3240
            if file:
3636
 
                raise errors.BzrCommandError(gettext(
3637
 
                    "please specify either --message or --file"))
 
3241
                raise errors.BzrCommandError(
 
3242
                    "please specify either --message or --file")
3638
3243
 
3639
3244
        def get_message(commit_obj):
3640
3245
            """Callback to get commit message"""
3657
3262
                # make_commit_message_template_encoded returns user encoding.
3658
3263
                # We probably want to be using edit_commit_message instead to
3659
3264
                # avoid this.
3660
 
                my_message = set_commit_message(commit_obj)
3661
 
                if my_message is None:
3662
 
                    start_message = generate_commit_message_template(commit_obj)
3663
 
                    my_message = edit_commit_message_encoded(text,
3664
 
                        start_message=start_message)
3665
 
                if my_message is None:
3666
 
                    raise errors.BzrCommandError(gettext("please specify a commit"
3667
 
                        " message with either --message or --file"))
3668
 
                if my_message == "":
3669
 
                    raise errors.BzrCommandError(gettext("Empty commit message specified."
3670
 
                            " Please specify a commit message with either"
3671
 
                            " --message or --file or leave a blank message"
3672
 
                            " with --message \"\"."))
 
3265
                start_message = generate_commit_message_template(commit_obj)
 
3266
                my_message = edit_commit_message_encoded(text,
 
3267
                    start_message=start_message)
 
3268
                if my_message is None:
 
3269
                    raise errors.BzrCommandError("please specify a commit"
 
3270
                        " message with either --message or --file")
 
3271
            if my_message == "":
 
3272
                raise errors.BzrCommandError("empty commit message specified")
3673
3273
            return my_message
3674
3274
 
3675
3275
        # The API permits a commit with a filter of [] to mean 'select nothing'
3686
3286
                        exclude=tree.safe_relpath_files(exclude),
3687
3287
                        lossy=lossy)
3688
3288
        except PointlessCommit:
3689
 
            raise errors.BzrCommandError(gettext("No changes to commit."
 
3289
            raise errors.BzrCommandError("No changes to commit."
3690
3290
                " Please 'bzr add' the files you want to commit, or use"
3691
 
                " --unchanged to force an empty commit."))
 
3291
                " --unchanged to force an empty commit.")
3692
3292
        except ConflictsInTree:
3693
 
            raise errors.BzrCommandError(gettext('Conflicts detected in working '
 
3293
            raise errors.BzrCommandError('Conflicts detected in working '
3694
3294
                'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
3695
 
                ' resolve.'))
 
3295
                ' resolve.')
3696
3296
        except StrictCommitFailed:
3697
 
            raise errors.BzrCommandError(gettext("Commit refused because there are"
3698
 
                              " unknown files in the working tree."))
 
3297
            raise errors.BzrCommandError("Commit refused because there are"
 
3298
                              " unknown files in the working tree.")
3699
3299
        except errors.BoundBranchOutOfDate, e:
3700
 
            e.extra_help = (gettext("\n"
 
3300
            e.extra_help = ("\n"
3701
3301
                'To commit to master branch, run update and then commit.\n'
3702
3302
                'You can also pass --local to commit to continue working '
3703
 
                'disconnected.'))
 
3303
                'disconnected.')
3704
3304
            raise
3705
3305
 
3706
3306
 
3813
3413
        RegistryOption('format',
3814
3414
            help='Upgrade to a specific format.  See "bzr help'
3815
3415
                 ' formats" for details.',
3816
 
            lazy_registry=('bzrlib.controldir', 'format_registry'),
3817
 
            converter=lambda name: controldir.format_registry.make_bzrdir(name),
 
3416
            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
 
3417
            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3818
3418
            value_switches=True, title='Branch format'),
3819
3419
        Option('clean',
3820
3420
            help='Remove the backup.bzr directory if successful.'),
3861
3461
            if directory is None:
3862
3462
                # use branch if we're inside one; otherwise global config
3863
3463
                try:
3864
 
                    c = Branch.open_containing(u'.')[0].get_config_stack()
 
3464
                    c = Branch.open_containing(u'.')[0].get_config()
3865
3465
                except errors.NotBranchError:
3866
 
                    c = _mod_config.GlobalStack()
 
3466
                    c = _mod_config.GlobalConfig()
3867
3467
            else:
3868
 
                c = Branch.open(directory).get_config_stack()
3869
 
            identity = c.get('email')
 
3468
                c = Branch.open(directory).get_config()
3870
3469
            if email:
3871
 
                self.outf.write(_mod_config.extract_email_address(identity)
3872
 
                                + '\n')
 
3470
                self.outf.write(c.user_email() + '\n')
3873
3471
            else:
3874
 
                self.outf.write(identity + '\n')
 
3472
                self.outf.write(c.username() + '\n')
3875
3473
            return
3876
3474
 
3877
3475
        if email:
3878
 
            raise errors.BzrCommandError(gettext("--email can only be used to display existing "
3879
 
                                         "identity"))
 
3476
            raise errors.BzrCommandError("--email can only be used to display existing "
 
3477
                                         "identity")
3880
3478
 
3881
3479
        # display a warning if an email address isn't included in the given name.
3882
3480
        try:
3888
3486
        # use global config unless --branch given
3889
3487
        if branch:
3890
3488
            if directory is None:
3891
 
                c = Branch.open_containing(u'.')[0].get_config_stack()
 
3489
                c = Branch.open_containing(u'.')[0].get_config()
3892
3490
            else:
3893
 
                b = Branch.open(directory)
3894
 
                self.add_cleanup(b.lock_write().unlock)
3895
 
                c = b.get_config_stack()
 
3491
                c = Branch.open(directory).get_config()
3896
3492
        else:
3897
 
            c = _mod_config.GlobalStack()
3898
 
        c.set('email', name)
 
3493
            c = _mod_config.GlobalConfig()
 
3494
        c.set_user_option('email', name)
3899
3495
 
3900
3496
 
3901
3497
class cmd_nick(Command):
3902
3498
    __doc__ = """Print or set the branch nickname.
3903
3499
 
3904
 
    If unset, the colocated branch name is used for colocated branches, and
3905
 
    the branch directory name is used for other branches.  To print the
3906
 
    current nickname, execute with no argument.
 
3500
    If unset, the tree root directory name is used as the nickname.
 
3501
    To print the current nickname, execute with no argument.
3907
3502
 
3908
3503
    Bound branches use the nickname of its master branch unless it is set
3909
3504
    locally.
3964
3559
 
3965
3560
    def remove_alias(self, alias_name):
3966
3561
        if alias_name is None:
3967
 
            raise errors.BzrCommandError(gettext(
3968
 
                'bzr alias --remove expects an alias to remove.'))
 
3562
            raise errors.BzrCommandError(
 
3563
                'bzr alias --remove expects an alias to remove.')
3969
3564
        # If alias is not found, print something like:
3970
3565
        # unalias: foo: not found
3971
3566
        c = _mod_config.GlobalConfig()
4050
3645
        if typestring == "sftp":
4051
3646
            from bzrlib.tests import stub_sftp
4052
3647
            return stub_sftp.SFTPAbsoluteServer
4053
 
        elif typestring == "memory":
 
3648
        if typestring == "memory":
4054
3649
            from bzrlib.tests import test_server
4055
3650
            return memory.MemoryServer
4056
 
        elif typestring == "fakenfs":
 
3651
        if typestring == "fakenfs":
4057
3652
            from bzrlib.tests import test_server
4058
3653
            return test_server.FakeNFSServer
4059
3654
        msg = "No known transport type %s. Supported types are: sftp\n" %\
4093
3688
                     Option('randomize', type=str, argname="SEED",
4094
3689
                            help='Randomize the order of tests using the given'
4095
3690
                                 ' seed or "now" for the current time.'),
4096
 
                     ListOption('exclude', type=str, argname="PATTERN",
4097
 
                                short_name='x',
4098
 
                                help='Exclude tests that match this regular'
4099
 
                                ' expression.'),
 
3691
                     Option('exclude', type=str, argname="PATTERN",
 
3692
                            short_name='x',
 
3693
                            help='Exclude tests that match this regular'
 
3694
                                 ' expression.'),
4100
3695
                     Option('subunit',
4101
3696
                        help='Output test progress via subunit.'),
4102
3697
                     Option('strict', help='Fail on missing dependencies or '
4109
3704
                                param_name='starting_with', short_name='s',
4110
3705
                                help=
4111
3706
                                'Load only the tests starting with TESTID.'),
4112
 
                     Option('sync',
4113
 
                            help="By default we disable fsync and fdatasync"
4114
 
                                 " while running the test suite.")
4115
3707
                     ]
4116
3708
    encoding_type = 'replace'
4117
3709
 
4125
3717
            first=False, list_only=False,
4126
3718
            randomize=None, exclude=None, strict=False,
4127
3719
            load_list=None, debugflag=None, starting_with=None, subunit=False,
4128
 
            parallel=None, lsprof_tests=False,
4129
 
            sync=False):
4130
 
 
4131
 
        # During selftest, disallow proxying, as it can cause severe
4132
 
        # performance penalties and is only needed for thread
4133
 
        # safety. The selftest command is assumed to not use threads
4134
 
        # too heavily. The call should be as early as possible, as
4135
 
        # error reporting for past duplicate imports won't have useful
4136
 
        # backtraces.
4137
 
        lazy_import.disallow_proxying()
4138
 
 
 
3720
            parallel=None, lsprof_tests=False):
4139
3721
        from bzrlib import tests
4140
3722
 
4141
3723
        if testspecs_list is not None:
4146
3728
            try:
4147
3729
                from bzrlib.tests import SubUnitBzrRunner
4148
3730
            except ImportError:
4149
 
                raise errors.BzrCommandError(gettext("subunit not available. subunit "
4150
 
                    "needs to be installed to use --subunit."))
 
3731
                raise errors.BzrCommandError("subunit not available. subunit "
 
3732
                    "needs to be installed to use --subunit.")
4151
3733
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
4152
3734
            # On Windows, disable automatic conversion of '\n' to '\r\n' in
4153
3735
            # stdout, which would corrupt the subunit stream. 
4162
3744
            self.additional_selftest_args.setdefault(
4163
3745
                'suite_decorators', []).append(parallel)
4164
3746
        if benchmark:
4165
 
            raise errors.BzrCommandError(gettext(
 
3747
            raise errors.BzrCommandError(
4166
3748
                "--benchmark is no longer supported from bzr 2.2; "
4167
 
                "use bzr-usertest instead"))
 
3749
                "use bzr-usertest instead")
4168
3750
        test_suite_factory = None
4169
 
        if not exclude:
4170
 
            exclude_pattern = None
4171
 
        else:
4172
 
            exclude_pattern = '(' + '|'.join(exclude) + ')'
4173
 
        if not sync:
4174
 
            self._disable_fsync()
4175
3751
        selftest_kwargs = {"verbose": verbose,
4176
3752
                          "pattern": pattern,
4177
3753
                          "stop_on_failure": one,
4182
3758
                          "matching_tests_first": first,
4183
3759
                          "list_only": list_only,
4184
3760
                          "random_seed": randomize,
4185
 
                          "exclude_pattern": exclude_pattern,
 
3761
                          "exclude_pattern": exclude,
4186
3762
                          "strict": strict,
4187
3763
                          "load_list": load_list,
4188
3764
                          "debug_flags": debugflag,
4199
3775
            cleanup()
4200
3776
        return int(not result)
4201
3777
 
4202
 
    def _disable_fsync(self):
4203
 
        """Change the 'os' functionality to not synchronize."""
4204
 
        self._orig_fsync = getattr(os, 'fsync', None)
4205
 
        if self._orig_fsync is not None:
4206
 
            os.fsync = lambda filedes: None
4207
 
        self._orig_fdatasync = getattr(os, 'fdatasync', None)
4208
 
        if self._orig_fdatasync is not None:
4209
 
            os.fdatasync = lambda filedes: None
4210
 
 
4211
3778
 
4212
3779
class cmd_version(Command):
4213
3780
    __doc__ = """Show version of bzr."""
4233
3800
 
4234
3801
    @display_command
4235
3802
    def run(self):
4236
 
        self.outf.write(gettext("It sure does!\n"))
 
3803
        self.outf.write("It sure does!\n")
4237
3804
 
4238
3805
 
4239
3806
class cmd_find_merge_base(Command):
4257
3824
        graph = branch1.repository.get_graph(branch2.repository)
4258
3825
        base_rev_id = graph.find_unique_lca(last1, last2)
4259
3826
 
4260
 
        self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
 
3827
        self.outf.write('merge base is revision %s\n' % base_rev_id)
4261
3828
 
4262
3829
 
4263
3830
class cmd_merge(Command):
4266
3833
    The source of the merge can be specified either in the form of a branch,
4267
3834
    or in the form of a path to a file containing a merge directive generated
4268
3835
    with bzr send. If neither is specified, the default is the upstream branch
4269
 
    or the branch most recently merged using --remember.  The source of the
4270
 
    merge may also be specified in the form of a path to a file in another
4271
 
    branch:  in this case, only the modifications to that file are merged into
4272
 
    the current working tree.
 
3836
    or the branch most recently merged using --remember.
4273
3837
 
4274
3838
    When merging from a branch, by default bzr will try to merge in all new
4275
3839
    work from the other branch, automatically determining an appropriate base
4282
3846
    through OTHER, excluding BASE but including OTHER, will be merged.  If this
4283
3847
    causes some revisions to be skipped, i.e. if the destination branch does
4284
3848
    not already contain revision BASE, such a merge is commonly referred to as
4285
 
    a "cherrypick". Unlike a normal merge, Bazaar does not currently track
4286
 
    cherrypicks. The changes look like a normal commit, and the history of the
4287
 
    changes from the other branch is not stored in the commit.
 
3849
    a "cherrypick".
4288
3850
 
4289
3851
    Revision numbers are always relative to the source branch.
4290
3852
 
4291
3853
    Merge will do its best to combine the changes in two branches, but there
4292
3854
    are some kinds of problems only a human can fix.  When it encounters those,
4293
3855
    it will mark a conflict.  A conflict means that you need to fix something,
4294
 
    before you can commit.
 
3856
    before you should commit.
4295
3857
 
4296
3858
    Use bzr resolve when you have fixed a problem.  See also bzr conflicts.
4297
3859
 
4298
 
    If there is no default branch set, the first merge will set it (use
4299
 
    --no-remember to avoid setting it). After that, you can omit the branch
4300
 
    to use the default.  To change the default, use --remember. The value will
4301
 
    only be saved if the remote location can be accessed.
 
3860
    If there is no default branch set, the first merge will set it. After
 
3861
    that, you can omit the branch to use the default.  To change the
 
3862
    default, use --remember. The value will only be saved if the remote
 
3863
    location can be accessed.
4302
3864
 
4303
3865
    The results of the merge are placed into the destination working
4304
3866
    directory, where they can be reviewed (with bzr diff), tested, and then
4305
3867
    committed to record the result of the merge.
4306
3868
 
4307
3869
    merge refuses to run if there are any uncommitted changes, unless
4308
 
    --force is given.  If --force is given, then the changes from the source 
4309
 
    will be merged with the current working tree, including any uncommitted
4310
 
    changes in the tree.  The --force option can also be used to create a
 
3870
    --force is given. The --force option can also be used to create a
4311
3871
    merge revision which has more than two parents.
4312
3872
 
4313
3873
    If one would like to merge changes from the working tree of the other
4371
3931
    ]
4372
3932
 
4373
3933
    def run(self, location=None, revision=None, force=False,
4374
 
            merge_type=None, show_base=False, reprocess=None, remember=None,
 
3934
            merge_type=None, show_base=False, reprocess=None, remember=False,
4375
3935
            uncommitted=False, pull=False,
4376
3936
            directory=None,
4377
3937
            preview=False,
4385
3945
        merger = None
4386
3946
        allow_pending = True
4387
3947
        verified = 'inapplicable'
4388
 
 
4389
3948
        tree = WorkingTree.open_containing(directory)[0]
4390
 
        if tree.branch.revno() == 0:
4391
 
            raise errors.BzrCommandError(gettext('Merging into empty branches not currently supported, '
4392
 
                                         'https://bugs.launchpad.net/bzr/+bug/308562'))
4393
3949
 
4394
3950
        try:
4395
3951
            basis_tree = tree.revision_tree(tree.last_revision())
4415
3971
                mergeable = None
4416
3972
            else:
4417
3973
                if uncommitted:
4418
 
                    raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
4419
 
                        ' with bundles or merge directives.'))
 
3974
                    raise errors.BzrCommandError('Cannot use --uncommitted'
 
3975
                        ' with bundles or merge directives.')
4420
3976
 
4421
3977
                if revision is not None:
4422
 
                    raise errors.BzrCommandError(gettext(
4423
 
                        'Cannot use -r with merge directives or bundles'))
 
3978
                    raise errors.BzrCommandError(
 
3979
                        'Cannot use -r with merge directives or bundles')
4424
3980
                merger, verified = _mod_merge.Merger.from_mergeable(tree,
4425
3981
                   mergeable, None)
4426
3982
 
4427
3983
        if merger is None and uncommitted:
4428
3984
            if revision is not None and len(revision) > 0:
4429
 
                raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
4430
 
                    ' --revision at the same time.'))
 
3985
                raise errors.BzrCommandError('Cannot use --uncommitted and'
 
3986
                    ' --revision at the same time.')
4431
3987
            merger = self.get_merger_from_uncommitted(tree, location, None)
4432
3988
            allow_pending = False
4433
3989
 
4441
3997
        self.sanity_check_merger(merger)
4442
3998
        if (merger.base_rev_id == merger.other_rev_id and
4443
3999
            merger.other_rev_id is not None):
4444
 
            # check if location is a nonexistent file (and not a branch) to
4445
 
            # disambiguate the 'Nothing to do'
4446
 
            if merger.interesting_files:
4447
 
                if not merger.other_tree.has_filename(
4448
 
                    merger.interesting_files[0]):
4449
 
                    note(gettext("merger: ") + str(merger))
4450
 
                    raise errors.PathsDoNotExist([location])
4451
 
            note(gettext('Nothing to do.'))
 
4000
            note('Nothing to do.')
4452
4001
            return 0
4453
 
        if pull and not preview:
 
4002
        if pull:
4454
4003
            if merger.interesting_files is not None:
4455
 
                raise errors.BzrCommandError(gettext('Cannot pull individual files'))
 
4004
                raise errors.BzrCommandError('Cannot pull individual files')
4456
4005
            if (merger.base_rev_id == tree.last_revision()):
4457
4006
                result = tree.pull(merger.other_branch, False,
4458
4007
                                   merger.other_rev_id)
4459
4008
                result.report(self.outf)
4460
4009
                return 0
4461
4010
        if merger.this_basis is None:
4462
 
            raise errors.BzrCommandError(gettext(
 
4011
            raise errors.BzrCommandError(
4463
4012
                "This branch has no commits."
4464
 
                " (perhaps you would prefer 'bzr pull')"))
 
4013
                " (perhaps you would prefer 'bzr pull')")
4465
4014
        if preview:
4466
4015
            return self._do_preview(merger)
4467
4016
        elif interactive:
4518
4067
    def sanity_check_merger(self, merger):
4519
4068
        if (merger.show_base and
4520
4069
            not merger.merge_type is _mod_merge.Merge3Merger):
4521
 
            raise errors.BzrCommandError(gettext("Show-base is not supported for this"
4522
 
                                         " merge type. %s") % merger.merge_type)
 
4070
            raise errors.BzrCommandError("Show-base is not supported for this"
 
4071
                                         " merge type. %s" % merger.merge_type)
4523
4072
        if merger.reprocess is None:
4524
4073
            if merger.show_base:
4525
4074
                merger.reprocess = False
4527
4076
                # Use reprocess if the merger supports it
4528
4077
                merger.reprocess = merger.merge_type.supports_reprocess
4529
4078
        if merger.reprocess and not merger.merge_type.supports_reprocess:
4530
 
            raise errors.BzrCommandError(gettext("Conflict reduction is not supported"
4531
 
                                         " for merge type %s.") %
 
4079
            raise errors.BzrCommandError("Conflict reduction is not supported"
 
4080
                                         " for merge type %s." %
4532
4081
                                         merger.merge_type)
4533
4082
        if merger.reprocess and merger.show_base:
4534
 
            raise errors.BzrCommandError(gettext("Cannot do conflict reduction and"
4535
 
                                         " show base."))
 
4083
            raise errors.BzrCommandError("Cannot do conflict reduction and"
 
4084
                                         " show base.")
4536
4085
 
4537
4086
    def _get_merger_from_branch(self, tree, location, revision, remember,
4538
4087
                                possible_transports, pb):
4565
4114
        if other_revision_id is None:
4566
4115
            other_revision_id = _mod_revision.ensure_null(
4567
4116
                other_branch.last_revision())
4568
 
        # Remember where we merge from. We need to remember if:
4569
 
        # - user specify a location (and we don't merge from the parent
4570
 
        #   branch)
4571
 
        # - user ask to remember or there is no previous location set to merge
4572
 
        #   from and user didn't ask to *not* remember
4573
 
        if (user_location is not None
4574
 
            and ((remember
4575
 
                  or (remember is None
4576
 
                      and tree.branch.get_submit_branch() is None)))):
 
4117
        # Remember where we merge from
 
4118
        if ((remember or tree.branch.get_submit_branch() is None) and
 
4119
             user_location is not None):
4577
4120
            tree.branch.set_submit_branch(other_branch.base)
4578
4121
        # Merge tags (but don't set them in the master branch yet, the user
4579
4122
        # might revert this merge).  Commit will propagate them.
4642
4185
            stored_location_type = "parent"
4643
4186
        mutter("%s", stored_location)
4644
4187
        if stored_location is None:
4645
 
            raise errors.BzrCommandError(gettext("No location specified or remembered"))
 
4188
            raise errors.BzrCommandError("No location specified or remembered")
4646
4189
        display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4647
 
        note(gettext("{0} remembered {1} location {2}").format(verb_string,
4648
 
                stored_location_type, display_url))
 
4190
        note(u"%s remembered %s location %s", verb_string,
 
4191
                stored_location_type, display_url)
4649
4192
        return stored_location
4650
4193
 
4651
4194
 
4688
4231
        self.add_cleanup(tree.lock_write().unlock)
4689
4232
        parents = tree.get_parent_ids()
4690
4233
        if len(parents) != 2:
4691
 
            raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
 
4234
            raise errors.BzrCommandError("Sorry, remerge only works after normal"
4692
4235
                                         " merges.  Not cherrypicking or"
4693
 
                                         " multi-merges."))
 
4236
                                         " multi-merges.")
4694
4237
        repository = tree.branch.repository
4695
4238
        interesting_ids = None
4696
4239
        new_conflicts = []
4705
4248
                if tree.kind(file_id) != "directory":
4706
4249
                    continue
4707
4250
 
4708
 
                # FIXME: Support nested trees
4709
 
                for name, ie in tree.root_inventory.iter_entries(file_id):
 
4251
                for name, ie in tree.inventory.iter_entries(file_id):
4710
4252
                    interesting_ids.add(ie.file_id)
4711
4253
            new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4712
4254
        else:
4745
4287
 
4746
4288
 
4747
4289
class cmd_revert(Command):
4748
 
    __doc__ = """\
4749
 
    Set files in the working tree back to the contents of a previous revision.
 
4290
    __doc__ = """Revert files to a previous revision.
4750
4291
 
4751
4292
    Giving a list of files will revert only those files.  Otherwise, all files
4752
4293
    will be reverted.  If the revision is not specified with '--revision', the
4753
 
    working tree basis revision is used. A revert operation affects only the
4754
 
    working tree, not any revision history like the branch and repository or
4755
 
    the working tree basis revision.
 
4294
    last committed revision is used.
4756
4295
 
4757
4296
    To remove only some changes, without reverting to a prior version, use
4758
4297
    merge instead.  For example, "merge . -r -2..-3" (don't forget the ".")
4759
4298
    will remove the changes introduced by the second last commit (-2), without
4760
4299
    affecting the changes introduced by the last commit (-1).  To remove
4761
4300
    certain changes on a hunk-by-hunk basis, see the shelve command.
4762
 
    To update the branch to a specific revision or the latest revision and
4763
 
    update the working tree accordingly while preserving local changes, see the
4764
 
    update command.
4765
4301
 
4766
 
    Uncommitted changes to files that are reverted will be discarded.
4767
 
    Howver, by default, any files that have been manually changed will be
4768
 
    backed up first.  (Files changed only by merge are not backed up.)  Backup
4769
 
    files have '.~#~' appended to their name, where # is a number.
 
4302
    By default, any files that have been manually changed will be backed up
 
4303
    first.  (Files changed only by merge are not backed up.)  Backup files have
 
4304
    '.~#~' appended to their name, where # is a number.
4770
4305
 
4771
4306
    When you provide files, you can use their current pathname or the pathname
4772
4307
    from the target revision.  So you can use revert to "undelete" a file by
4863
4398
 
4864
4399
    @display_command
4865
4400
    def run(self, context=None):
4866
 
        from bzrlib import shellcomplete
 
4401
        import shellcomplete
4867
4402
        shellcomplete.shellcomplete(context)
4868
4403
 
4869
4404
 
4923
4458
            type=_parse_revision_str,
4924
4459
            help='Filter on local branch revisions (inclusive). '
4925
4460
                'See "help revisionspec" for details.'),
4926
 
        Option('include-merged',
 
4461
        Option('include-merges',
4927
4462
               'Show all revisions in addition to the mainline ones.'),
4928
 
        Option('include-merges', hidden=True,
4929
 
               help='Historical alias for --include-merged.'),
4930
4463
        ]
4931
4464
    encoding_type = 'replace'
4932
4465
 
4935
4468
            theirs_only=False,
4936
4469
            log_format=None, long=False, short=False, line=False,
4937
4470
            show_ids=False, verbose=False, this=False, other=False,
4938
 
            include_merged=None, revision=None, my_revision=None,
4939
 
            directory=u'.',
4940
 
            include_merges=symbol_versioning.DEPRECATED_PARAMETER):
 
4471
            include_merges=False, revision=None, my_revision=None,
 
4472
            directory=u'.'):
4941
4473
        from bzrlib.missing import find_unmerged, iter_log_revisions
4942
4474
        def message(s):
4943
4475
            if not is_quiet():
4944
4476
                self.outf.write(s)
4945
4477
 
4946
 
        if symbol_versioning.deprecated_passed(include_merges):
4947
 
            ui.ui_factory.show_user_warning(
4948
 
                'deprecated_command_option',
4949
 
                deprecated_name='--include-merges',
4950
 
                recommended_name='--include-merged',
4951
 
                deprecated_in_version='2.5',
4952
 
                command=self.invoked_as)
4953
 
            if include_merged is None:
4954
 
                include_merged = include_merges
4955
 
            else:
4956
 
                raise errors.BzrCommandError(gettext(
4957
 
                    '{0} and {1} are mutually exclusive').format(
4958
 
                    '--include-merges', '--include-merged'))
4959
 
        if include_merged is None:
4960
 
            include_merged = False
4961
4478
        if this:
4962
4479
            mine_only = this
4963
4480
        if other:
4978
4495
        if other_branch is None:
4979
4496
            other_branch = parent
4980
4497
            if other_branch is None:
4981
 
                raise errors.BzrCommandError(gettext("No peer location known"
4982
 
                                             " or specified."))
 
4498
                raise errors.BzrCommandError("No peer location known"
 
4499
                                             " or specified.")
4983
4500
            display_url = urlutils.unescape_for_display(parent,
4984
4501
                                                        self.outf.encoding)
4985
 
            message(gettext("Using saved parent location: {0}\n").format(
4986
 
                    display_url))
 
4502
            message("Using saved parent location: "
 
4503
                    + display_url + "\n")
4987
4504
 
4988
4505
        remote_branch = Branch.open(other_branch)
4989
4506
        if remote_branch.base == local_branch.base:
5002
4519
        local_extra, remote_extra = find_unmerged(
5003
4520
            local_branch, remote_branch, restrict,
5004
4521
            backward=not reverse,
5005
 
            include_merged=include_merged,
 
4522
            include_merges=include_merges,
5006
4523
            local_revid_range=local_revid_range,
5007
4524
            remote_revid_range=remote_revid_range)
5008
4525
 
5015
4532
 
5016
4533
        status_code = 0
5017
4534
        if local_extra and not theirs_only:
5018
 
            message(ngettext("You have %d extra revision:\n",
5019
 
                             "You have %d extra revisions:\n", 
5020
 
                             len(local_extra)) %
 
4535
            message("You have %d extra revision(s):\n" %
5021
4536
                len(local_extra))
5022
 
            rev_tag_dict = {}
5023
 
            if local_branch.supports_tags():
5024
 
                rev_tag_dict = local_branch.tags.get_reverse_tag_dict()
5025
4537
            for revision in iter_log_revisions(local_extra,
5026
4538
                                local_branch.repository,
5027
 
                                verbose,
5028
 
                                rev_tag_dict):
 
4539
                                verbose):
5029
4540
                lf.log_revision(revision)
5030
4541
            printed_local = True
5031
4542
            status_code = 1
5035
4546
        if remote_extra and not mine_only:
5036
4547
            if printed_local is True:
5037
4548
                message("\n\n\n")
5038
 
            message(ngettext("You are missing %d revision:\n",
5039
 
                             "You are missing %d revisions:\n",
5040
 
                             len(remote_extra)) %
 
4549
            message("You are missing %d revision(s):\n" %
5041
4550
                len(remote_extra))
5042
 
            if remote_branch.supports_tags():
5043
 
                rev_tag_dict = remote_branch.tags.get_reverse_tag_dict()
5044
4551
            for revision in iter_log_revisions(remote_extra,
5045
4552
                                remote_branch.repository,
5046
 
                                verbose,
5047
 
                                rev_tag_dict):
 
4553
                                verbose):
5048
4554
                lf.log_revision(revision)
5049
4555
            status_code = 1
5050
4556
 
5051
4557
        if mine_only and not local_extra:
5052
4558
            # We checked local, and found nothing extra
5053
 
            message(gettext('This branch has no new revisions.\n'))
 
4559
            message('This branch is up to date.\n')
5054
4560
        elif theirs_only and not remote_extra:
5055
4561
            # We checked remote, and found nothing extra
5056
 
            message(gettext('Other branch has no new revisions.\n'))
 
4562
            message('Other branch is up to date.\n')
5057
4563
        elif not (mine_only or theirs_only or local_extra or
5058
4564
                  remote_extra):
5059
4565
            # We checked both branches, and neither one had extra
5060
4566
            # revisions
5061
 
            message(gettext("Branches are up to date.\n"))
 
4567
            message("Branches are up to date.\n")
5062
4568
        self.cleanup_now()
5063
4569
        if not status_code and parent is None and other_branch is not None:
5064
4570
            self.add_cleanup(local_branch.lock_write().unlock)
5094
4600
        ]
5095
4601
 
5096
4602
    def run(self, branch_or_repo='.', clean_obsolete_packs=False):
5097
 
        dir = controldir.ControlDir.open_containing(branch_or_repo)[0]
 
4603
        dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
5098
4604
        try:
5099
4605
            branch = dir.open_branch()
5100
4606
            repository = branch.repository
5127
4633
    @display_command
5128
4634
    def run(self, verbose=False):
5129
4635
        from bzrlib import plugin
5130
 
        # Don't give writelines a generator as some codecs don't like that
5131
4636
        self.outf.writelines(
5132
 
            list(plugin.describe_plugins(show_paths=verbose)))
 
4637
            plugin.describe_plugins(show_paths=verbose))
5133
4638
 
5134
4639
 
5135
4640
class cmd_testament(Command):
5140
4645
            Option('strict',
5141
4646
                   help='Produce a strict-format testament.')]
5142
4647
    takes_args = ['branch?']
5143
 
    encoding_type = 'exact'
5144
4648
    @display_command
5145
4649
    def run(self, branch=u'.', revision=None, long=False, strict=False):
5146
4650
        from bzrlib.testament import Testament, StrictTestament
5159
4663
            rev_id = revision[0].as_revision_id(b)
5160
4664
        t = testament_class.from_revision(b.repository, rev_id)
5161
4665
        if long:
5162
 
            self.outf.writelines(t.as_text_lines())
 
4666
            sys.stdout.writelines(t.as_text_lines())
5163
4667
        else:
5164
 
            self.outf.write(t.as_short_text())
 
4668
            sys.stdout.write(t.as_short_text())
5165
4669
 
5166
4670
 
5167
4671
class cmd_annotate(Command):
5189
4693
    @display_command
5190
4694
    def run(self, filename, all=False, long=False, revision=None,
5191
4695
            show_ids=False, directory=None):
5192
 
        from bzrlib.annotate import (
5193
 
            annotate_file_tree,
5194
 
            )
 
4696
        from bzrlib.annotate import annotate_file, annotate_file_tree
5195
4697
        wt, branch, relpath = \
5196
4698
            _open_directory_or_containing_tree_or_branch(filename, directory)
5197
4699
        if wt is not None:
5212
4714
            annotate_file_tree(wt, file_id, self.outf, long, all,
5213
4715
                show_ids=show_ids)
5214
4716
        else:
5215
 
            annotate_file_tree(tree, file_id, self.outf, long, all,
5216
 
                show_ids=show_ids, branch=branch)
 
4717
            file_version = tree.get_file_revision(file_id)
 
4718
            annotate_file(branch, file_version, file_id, long, all, self.outf,
 
4719
                          show_ids=show_ids)
5217
4720
 
5218
4721
 
5219
4722
class cmd_re_sign(Command):
5226
4729
 
5227
4730
    def run(self, revision_id_list=None, revision=None, directory=u'.'):
5228
4731
        if revision_id_list is not None and revision is not None:
5229
 
            raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
 
4732
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
5230
4733
        if revision_id_list is None and revision is None:
5231
 
            raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
 
4734
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
5232
4735
        b = WorkingTree.open_containing(directory)[0].branch
5233
4736
        self.add_cleanup(b.lock_write().unlock)
5234
4737
        return self._run(b, revision_id_list, revision)
5235
4738
 
5236
4739
    def _run(self, b, revision_id_list, revision):
5237
4740
        import bzrlib.gpg as gpg
5238
 
        gpg_strategy = gpg.GPGStrategy(b.get_config_stack())
 
4741
        gpg_strategy = gpg.GPGStrategy(b.get_config())
5239
4742
        if revision_id_list is not None:
5240
4743
            b.repository.start_write_group()
5241
4744
            try:
5266
4769
                if to_revid is None:
5267
4770
                    to_revno = b.revno()
5268
4771
                if from_revno is None or to_revno is None:
5269
 
                    raise errors.BzrCommandError(gettext('Cannot sign a range of non-revision-history revisions'))
 
4772
                    raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
5270
4773
                b.repository.start_write_group()
5271
4774
                try:
5272
4775
                    for revno in range(from_revno, to_revno + 1):
5278
4781
                else:
5279
4782
                    b.repository.commit_write_group()
5280
4783
            else:
5281
 
                raise errors.BzrCommandError(gettext('Please supply either one revision, or a range.'))
 
4784
                raise errors.BzrCommandError('Please supply either one revision, or a range.')
5282
4785
 
5283
4786
 
5284
4787
class cmd_bind(Command):
5303
4806
            try:
5304
4807
                location = b.get_old_bound_location()
5305
4808
            except errors.UpgradeRequired:
5306
 
                raise errors.BzrCommandError(gettext('No location supplied.  '
5307
 
                    'This format does not remember old locations.'))
 
4809
                raise errors.BzrCommandError('No location supplied.  '
 
4810
                    'This format does not remember old locations.')
5308
4811
            else:
5309
4812
                if location is None:
5310
4813
                    if b.get_bound_location() is not None:
5311
 
                        raise errors.BzrCommandError(
5312
 
                            gettext('Branch is already bound'))
 
4814
                        raise errors.BzrCommandError('Branch is already bound')
5313
4815
                    else:
5314
 
                        raise errors.BzrCommandError(
5315
 
                            gettext('No location supplied'
5316
 
                                    ' and no previous location known'))
 
4816
                        raise errors.BzrCommandError('No location supplied '
 
4817
                            'and no previous location known')
5317
4818
        b_other = Branch.open(location)
5318
4819
        try:
5319
4820
            b.bind(b_other)
5320
4821
        except errors.DivergedBranches:
5321
 
            raise errors.BzrCommandError(gettext('These branches have diverged.'
5322
 
                                         ' Try merging, and then bind again.'))
 
4822
            raise errors.BzrCommandError('These branches have diverged.'
 
4823
                                         ' Try merging, and then bind again.')
5323
4824
        if b.get_config().has_explicit_nickname():
5324
4825
            b.nick = b_other.nick
5325
4826
 
5338
4839
    def run(self, directory=u'.'):
5339
4840
        b, relpath = Branch.open_containing(directory)
5340
4841
        if not b.unbind():
5341
 
            raise errors.BzrCommandError(gettext('Local branch is not bound'))
 
4842
            raise errors.BzrCommandError('Local branch is not bound')
5342
4843
 
5343
4844
 
5344
4845
class cmd_uncommit(Command):
5365
4866
    takes_options = ['verbose', 'revision',
5366
4867
                    Option('dry-run', help='Don\'t actually make changes.'),
5367
4868
                    Option('force', help='Say yes to all questions.'),
5368
 
                    Option('keep-tags',
5369
 
                           help='Keep tags that point to removed revisions.'),
5370
4869
                    Option('local',
5371
4870
                           help="Only remove the commits from the local branch"
5372
4871
                                " when in a checkout."
5376
4875
    aliases = []
5377
4876
    encoding_type = 'replace'
5378
4877
 
5379
 
    def run(self, location=None, dry_run=False, verbose=False,
5380
 
            revision=None, force=False, local=False, keep_tags=False):
 
4878
    def run(self, location=None,
 
4879
            dry_run=False, verbose=False,
 
4880
            revision=None, force=False, local=False):
5381
4881
        if location is None:
5382
4882
            location = u'.'
5383
 
        control, relpath = controldir.ControlDir.open_containing(location)
 
4883
        control, relpath = bzrdir.BzrDir.open_containing(location)
5384
4884
        try:
5385
4885
            tree = control.open_workingtree()
5386
4886
            b = tree.branch
5392
4892
            self.add_cleanup(tree.lock_write().unlock)
5393
4893
        else:
5394
4894
            self.add_cleanup(b.lock_write().unlock)
5395
 
        return self._run(b, tree, dry_run, verbose, revision, force,
5396
 
                         local, keep_tags)
 
4895
        return self._run(b, tree, dry_run, verbose, revision, force, local=local)
5397
4896
 
5398
 
    def _run(self, b, tree, dry_run, verbose, revision, force, local,
5399
 
             keep_tags):
 
4897
    def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
5400
4898
        from bzrlib.log import log_formatter, show_log
5401
4899
        from bzrlib.uncommit import uncommit
5402
4900
 
5417
4915
                rev_id = b.get_rev_id(revno)
5418
4916
 
5419
4917
        if rev_id is None or _mod_revision.is_null(rev_id):
5420
 
            self.outf.write(gettext('No revisions to uncommit.\n'))
 
4918
            self.outf.write('No revisions to uncommit.\n')
5421
4919
            return 1
5422
4920
 
5423
4921
        lf = log_formatter('short',
5432
4930
                 end_revision=last_revno)
5433
4931
 
5434
4932
        if dry_run:
5435
 
            self.outf.write(gettext('Dry-run, pretending to remove'
5436
 
                            ' the above revisions.\n'))
 
4933
            self.outf.write('Dry-run, pretending to remove'
 
4934
                            ' the above revisions.\n')
5437
4935
        else:
5438
 
            self.outf.write(gettext('The above revision(s) will be removed.\n'))
 
4936
            self.outf.write('The above revision(s) will be removed.\n')
5439
4937
 
5440
4938
        if not force:
5441
4939
            if not ui.ui_factory.confirm_action(
5442
 
                    gettext(u'Uncommit these revisions'),
 
4940
                    'Uncommit these revisions',
5443
4941
                    'bzrlib.builtins.uncommit',
5444
4942
                    {}):
5445
 
                self.outf.write(gettext('Canceled\n'))
 
4943
                self.outf.write('Canceled\n')
5446
4944
                return 0
5447
4945
 
5448
4946
        mutter('Uncommitting from {%s} to {%s}',
5449
4947
               last_rev_id, rev_id)
5450
4948
        uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5451
 
                 revno=revno, local=local, keep_tags=keep_tags)
5452
 
        self.outf.write(gettext('You can restore the old tip by running:\n'
5453
 
             '  bzr pull . -r revid:%s\n') % last_rev_id)
 
4949
                 revno=revno, local=local)
 
4950
        self.outf.write('You can restore the old tip by running:\n'
 
4951
             '  bzr pull . -r revid:%s\n' % last_rev_id)
5454
4952
 
5455
4953
 
5456
4954
class cmd_break_lock(Command):
5490
4988
            conf = _mod_config.LockableConfig(file_name=location)
5491
4989
            conf.break_lock()
5492
4990
        else:
5493
 
            control, relpath = controldir.ControlDir.open_containing(location)
 
4991
            control, relpath = bzrdir.BzrDir.open_containing(location)
5494
4992
            try:
5495
4993
                control.break_lock()
5496
4994
            except NotImplementedError:
5523
5021
               help="Protocol to serve.",
5524
5022
               lazy_registry=('bzrlib.transport', 'transport_server_registry'),
5525
5023
               value_switches=True),
5526
 
        Option('listen',
5527
 
               help='Listen for connections on nominated address.', type=str),
5528
5024
        Option('port',
5529
 
               help='Listen for connections on nominated port.  Passing 0 as '
5530
 
                    'the port number will result in a dynamically allocated '
5531
 
                    'port.  The default port depends on the protocol.',
5532
 
               type=int),
 
5025
               help='Listen for connections on nominated port of the form '
 
5026
                    '[hostname:]portnumber.  Passing 0 as the port number will '
 
5027
                    'result in a dynamically allocated port.  The default port '
 
5028
                    'depends on the protocol.',
 
5029
               type=str),
5533
5030
        custom_help('directory',
5534
5031
               help='Serve contents of this directory.'),
5535
5032
        Option('allow-writes',
5541
5038
                    'option leads to global uncontrolled write access to your '
5542
5039
                    'file system.'
5543
5040
                ),
5544
 
        Option('client-timeout', type=float,
5545
 
               help='Override the default idle client timeout (5min).'),
5546
5041
        ]
5547
5042
 
5548
 
    def run(self, listen=None, port=None, inet=False, directory=None,
5549
 
            allow_writes=False, protocol=None, client_timeout=None):
 
5043
    def get_host_and_port(self, port):
 
5044
        """Return the host and port to run the smart server on.
 
5045
 
 
5046
        If 'port' is None, None will be returned for the host and port.
 
5047
 
 
5048
        If 'port' has a colon in it, the string before the colon will be
 
5049
        interpreted as the host.
 
5050
 
 
5051
        :param port: A string of the port to run the server on.
 
5052
        :return: A tuple of (host, port), where 'host' is a host name or IP,
 
5053
            and port is an integer TCP/IP port.
 
5054
        """
 
5055
        host = None
 
5056
        if port is not None:
 
5057
            if ':' in port:
 
5058
                host, port = port.split(':')
 
5059
            port = int(port)
 
5060
        return host, port
 
5061
 
 
5062
    def run(self, port=None, inet=False, directory=None, allow_writes=False,
 
5063
            protocol=None):
5550
5064
        from bzrlib import transport
5551
5065
        if directory is None:
5552
5066
            directory = os.getcwd()
5553
5067
        if protocol is None:
5554
5068
            protocol = transport.transport_server_registry.get()
5555
 
        url = transport.location_to_url(directory)
 
5069
        host, port = self.get_host_and_port(port)
 
5070
        url = urlutils.local_path_to_url(directory)
5556
5071
        if not allow_writes:
5557
5072
            url = 'readonly+' + url
5558
 
        t = transport.get_transport_from_url(url)
5559
 
        protocol(t, listen, port, inet, client_timeout)
 
5073
        t = transport.get_transport(url)
 
5074
        protocol(t, host, port, inet)
5560
5075
 
5561
5076
 
5562
5077
class cmd_join(Command):
5585
5100
        containing_tree = WorkingTree.open_containing(parent_dir)[0]
5586
5101
        repo = containing_tree.branch.repository
5587
5102
        if not repo.supports_rich_root():
5588
 
            raise errors.BzrCommandError(gettext(
 
5103
            raise errors.BzrCommandError(
5589
5104
                "Can't join trees because %s doesn't support rich root data.\n"
5590
 
                "You can use bzr upgrade on the repository.")
 
5105
                "You can use bzr upgrade on the repository."
5591
5106
                % (repo,))
5592
5107
        if reference:
5593
5108
            try:
5595
5110
            except errors.BadReferenceTarget, e:
5596
5111
                # XXX: Would be better to just raise a nicely printable
5597
5112
                # exception from the real origin.  Also below.  mbp 20070306
5598
 
                raise errors.BzrCommandError(
5599
 
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
 
5113
                raise errors.BzrCommandError("Cannot join %s.  %s" %
 
5114
                                             (tree, e.reason))
5600
5115
        else:
5601
5116
            try:
5602
5117
                containing_tree.subsume(sub_tree)
5603
5118
            except errors.BadSubsumeSource, e:
5604
 
                raise errors.BzrCommandError(
5605
 
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
 
5119
                raise errors.BzrCommandError("Cannot join %s.  %s" %
 
5120
                                             (tree, e.reason))
5606
5121
 
5607
5122
 
5608
5123
class cmd_split(Command):
5692
5207
        if submit_branch is None:
5693
5208
            submit_branch = branch.get_parent()
5694
5209
        if submit_branch is None:
5695
 
            raise errors.BzrCommandError(gettext('No submit branch specified or known'))
 
5210
            raise errors.BzrCommandError('No submit branch specified or known')
5696
5211
 
5697
5212
        stored_public_branch = branch.get_public_branch()
5698
5213
        if public_branch is None:
5699
5214
            public_branch = stored_public_branch
5700
5215
        elif stored_public_branch is None:
5701
 
            # FIXME: Should be done only if we succeed ? -- vila 2012-01-03
5702
5216
            branch.set_public_branch(public_branch)
5703
5217
        if not include_bundle and public_branch is None:
5704
 
            raise errors.BzrCommandError(gettext('No public branch specified or'
5705
 
                                         ' known'))
 
5218
            raise errors.BzrCommandError('No public branch specified or'
 
5219
                                         ' known')
5706
5220
        base_revision_id = None
5707
5221
        if revision is not None:
5708
5222
            if len(revision) > 2:
5709
 
                raise errors.BzrCommandError(gettext('bzr merge-directive takes '
5710
 
                    'at most two one revision identifiers'))
 
5223
                raise errors.BzrCommandError('bzr merge-directive takes '
 
5224
                    'at most two one revision identifiers')
5711
5225
            revision_id = revision[-1].as_revision_id(branch)
5712
5226
            if len(revision) == 2:
5713
5227
                base_revision_id = revision[0].as_revision_id(branch)
5715
5229
            revision_id = branch.last_revision()
5716
5230
        revision_id = ensure_null(revision_id)
5717
5231
        if revision_id == NULL_REVISION:
5718
 
            raise errors.BzrCommandError(gettext('No revisions to bundle.'))
 
5232
            raise errors.BzrCommandError('No revisions to bundle.')
5719
5233
        directive = merge_directive.MergeDirective2.from_objects(
5720
5234
            branch.repository, revision_id, time.time(),
5721
5235
            osutils.local_time_offset(), submit_branch,
5729
5243
                self.outf.writelines(directive.to_lines())
5730
5244
        else:
5731
5245
            message = directive.to_email(mail_to, branch, sign)
5732
 
            s = SMTPConnection(branch.get_config_stack())
 
5246
            s = SMTPConnection(branch.get_config())
5733
5247
            s.send_email(message)
5734
5248
 
5735
5249
 
5765
5279
    source branch defaults to that containing the working directory, but can
5766
5280
    be changed using --from.
5767
5281
 
5768
 
    Both the submit branch and the public branch follow the usual behavior with
5769
 
    respect to --remember: If there is no default location set, the first send
5770
 
    will set it (use --no-remember to avoid setting it). After that, you can
5771
 
    omit the location to use the default.  To change the default, use
5772
 
    --remember. The value will only be saved if the location can be accessed.
5773
 
 
5774
5282
    In order to calculate those changes, bzr must analyse the submit branch.
5775
5283
    Therefore it is most efficient for the submit branch to be a local mirror.
5776
5284
    If a public location is known for the submit_branch, that location is used
5845
5353
        ]
5846
5354
 
5847
5355
    def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5848
 
            no_patch=False, revision=None, remember=None, output=None,
 
5356
            no_patch=False, revision=None, remember=False, output=None,
5849
5357
            format=None, mail_to=None, message=None, body=None,
5850
5358
            strict=None, **kwargs):
5851
5359
        from bzrlib.send import send
5975
5483
        self.add_cleanup(branch.lock_write().unlock)
5976
5484
        if delete:
5977
5485
            if tag_name is None:
5978
 
                raise errors.BzrCommandError(gettext("No tag specified to delete."))
 
5486
                raise errors.BzrCommandError("No tag specified to delete.")
5979
5487
            branch.tags.delete_tag(tag_name)
5980
 
            note(gettext('Deleted tag %s.') % tag_name)
 
5488
            note('Deleted tag %s.' % tag_name)
5981
5489
        else:
5982
5490
            if revision:
5983
5491
                if len(revision) != 1:
5984
 
                    raise errors.BzrCommandError(gettext(
 
5492
                    raise errors.BzrCommandError(
5985
5493
                        "Tags can only be placed on a single revision, "
5986
 
                        "not on a range"))
 
5494
                        "not on a range")
5987
5495
                revision_id = revision[0].as_revision_id(branch)
5988
5496
            else:
5989
5497
                revision_id = branch.last_revision()
5990
5498
            if tag_name is None:
5991
5499
                tag_name = branch.automatic_tag_name(revision_id)
5992
5500
                if tag_name is None:
5993
 
                    raise errors.BzrCommandError(gettext(
5994
 
                        "Please specify a tag name."))
5995
 
            try:
5996
 
                existing_target = branch.tags.lookup_tag(tag_name)
5997
 
            except errors.NoSuchTag:
5998
 
                existing_target = None
5999
 
            if not force and existing_target not in (None, revision_id):
 
5501
                    raise errors.BzrCommandError(
 
5502
                        "Please specify a tag name.")
 
5503
            if (not force) and branch.tags.has_tag(tag_name):
6000
5504
                raise errors.TagAlreadyExists(tag_name)
6001
 
            if existing_target == revision_id:
6002
 
                note(gettext('Tag %s already exists for that revision.') % tag_name)
6003
 
            else:
6004
 
                branch.tags.set_tag(tag_name, revision_id)
6005
 
                if existing_target is None:
6006
 
                    note(gettext('Created tag %s.') % tag_name)
6007
 
                else:
6008
 
                    note(gettext('Updated tag %s.') % tag_name)
 
5505
            branch.tags.set_tag(tag_name, revision_id)
 
5506
            note('Created tag %s.' % tag_name)
6009
5507
 
6010
5508
 
6011
5509
class cmd_tags(Command):
6037
5535
 
6038
5536
        self.add_cleanup(branch.lock_read().unlock)
6039
5537
        if revision:
6040
 
            # Restrict to the specified range
6041
 
            tags = self._tags_for_range(branch, revision)
 
5538
            graph = branch.repository.get_graph()
 
5539
            rev1, rev2 = _get_revision_range(revision, branch, self.name())
 
5540
            revid1, revid2 = rev1.rev_id, rev2.rev_id
 
5541
            # only show revisions between revid1 and revid2 (inclusive)
 
5542
            tags = [(tag, revid) for tag, revid in tags if
 
5543
                graph.is_between(revid, revid1, revid2)]
6042
5544
        if sort is None:
6043
5545
            sort = tag_sort_methods.get()
6044
5546
        sort(branch, tags)
6049
5551
                    revno = branch.revision_id_to_dotted_revno(revid)
6050
5552
                    if isinstance(revno, tuple):
6051
5553
                        revno = '.'.join(map(str, revno))
6052
 
                except (errors.NoSuchRevision,
6053
 
                        errors.GhostRevisionsHaveNoRevno,
6054
 
                        errors.UnsupportedOperation):
 
5554
                except (errors.NoSuchRevision, errors.GhostRevisionsHaveNoRevno):
6055
5555
                    # Bad tag data/merges can lead to tagged revisions
6056
5556
                    # which are not in this branch. Fail gracefully ...
6057
5557
                    revno = '?'
6060
5560
        for tag, revspec in tags:
6061
5561
            self.outf.write('%-20s %s\n' % (tag, revspec))
6062
5562
 
6063
 
    def _tags_for_range(self, branch, revision):
6064
 
        range_valid = True
6065
 
        rev1, rev2 = _get_revision_range(revision, branch, self.name())
6066
 
        revid1, revid2 = rev1.rev_id, rev2.rev_id
6067
 
        # _get_revision_range will always set revid2 if it's not specified.
6068
 
        # If revid1 is None, it means we want to start from the branch
6069
 
        # origin which is always a valid ancestor. If revid1 == revid2, the
6070
 
        # ancestry check is useless.
6071
 
        if revid1 and revid1 != revid2:
6072
 
            # FIXME: We really want to use the same graph than
6073
 
            # branch.iter_merge_sorted_revisions below, but this is not
6074
 
            # easily available -- vila 2011-09-23
6075
 
            if branch.repository.get_graph().is_ancestor(revid2, revid1):
6076
 
                # We don't want to output anything in this case...
6077
 
                return []
6078
 
        # only show revisions between revid1 and revid2 (inclusive)
6079
 
        tagged_revids = branch.tags.get_reverse_tag_dict()
6080
 
        found = []
6081
 
        for r in branch.iter_merge_sorted_revisions(
6082
 
            start_revision_id=revid2, stop_revision_id=revid1,
6083
 
            stop_rule='include'):
6084
 
            revid_tags = tagged_revids.get(r[0], None)
6085
 
            if revid_tags:
6086
 
                found.extend([(tag, r[0]) for tag in revid_tags])
6087
 
        return found
6088
 
 
6089
5563
 
6090
5564
class cmd_reconfigure(Command):
6091
5565
    __doc__ = """Reconfigure the type of a bzr directory.
6105
5579
    takes_args = ['location?']
6106
5580
    takes_options = [
6107
5581
        RegistryOption.from_kwargs(
6108
 
            'tree_type',
6109
 
            title='Tree type',
6110
 
            help='The relation between branch and tree.',
 
5582
            'target_type',
 
5583
            title='Target type',
 
5584
            help='The type to reconfigure the directory to.',
6111
5585
            value_switches=True, enum_switch=False,
6112
5586
            branch='Reconfigure to be an unbound branch with no working tree.',
6113
5587
            tree='Reconfigure to be an unbound branch with a working tree.',
6114
5588
            checkout='Reconfigure to be a bound branch with a working tree.',
6115
5589
            lightweight_checkout='Reconfigure to be a lightweight'
6116
5590
                ' checkout (with no local history).',
6117
 
            ),
6118
 
        RegistryOption.from_kwargs(
6119
 
            'repository_type',
6120
 
            title='Repository type',
6121
 
            help='Location fo the repository.',
6122
 
            value_switches=True, enum_switch=False,
6123
5591
            standalone='Reconfigure to be a standalone branch '
6124
5592
                '(i.e. stop using shared repository).',
6125
5593
            use_shared='Reconfigure to use a shared repository.',
6126
 
            ),
6127
 
        RegistryOption.from_kwargs(
6128
 
            'repository_trees',
6129
 
            title='Trees in Repository',
6130
 
            help='Whether new branches in the repository have trees.',
6131
 
            value_switches=True, enum_switch=False,
6132
5594
            with_trees='Reconfigure repository to create '
6133
5595
                'working trees on branches by default.',
6134
5596
            with_no_trees='Reconfigure repository to not create '
6148
5610
            ),
6149
5611
        ]
6150
5612
 
6151
 
    def run(self, location=None, bind_to=None, force=False,
6152
 
            tree_type=None, repository_type=None, repository_trees=None,
6153
 
            stacked_on=None, unstacked=None):
6154
 
        directory = controldir.ControlDir.open(location)
 
5613
    def run(self, location=None, target_type=None, bind_to=None, force=False,
 
5614
            stacked_on=None,
 
5615
            unstacked=None):
 
5616
        directory = bzrdir.BzrDir.open(location)
6155
5617
        if stacked_on and unstacked:
6156
 
            raise errors.BzrCommandError(gettext("Can't use both --stacked-on and --unstacked"))
 
5618
            raise BzrCommandError("Can't use both --stacked-on and --unstacked")
6157
5619
        elif stacked_on is not None:
6158
5620
            reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
6159
5621
        elif unstacked:
6161
5623
        # At the moment you can use --stacked-on and a different
6162
5624
        # reconfiguration shape at the same time; there seems no good reason
6163
5625
        # to ban it.
6164
 
        if (tree_type is None and
6165
 
            repository_type is None and
6166
 
            repository_trees is None):
 
5626
        if target_type is None:
6167
5627
            if stacked_on or unstacked:
6168
5628
                return
6169
5629
            else:
6170
 
                raise errors.BzrCommandError(gettext('No target configuration '
6171
 
                    'specified'))
6172
 
        reconfiguration = None
6173
 
        if tree_type == 'branch':
 
5630
                raise errors.BzrCommandError('No target configuration '
 
5631
                    'specified')
 
5632
        elif target_type == 'branch':
6174
5633
            reconfiguration = reconfigure.Reconfigure.to_branch(directory)
6175
 
        elif tree_type == 'tree':
 
5634
        elif target_type == 'tree':
6176
5635
            reconfiguration = reconfigure.Reconfigure.to_tree(directory)
6177
 
        elif tree_type == 'checkout':
 
5636
        elif target_type == 'checkout':
6178
5637
            reconfiguration = reconfigure.Reconfigure.to_checkout(
6179
5638
                directory, bind_to)
6180
 
        elif tree_type == 'lightweight-checkout':
 
5639
        elif target_type == 'lightweight-checkout':
6181
5640
            reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
6182
5641
                directory, bind_to)
6183
 
        if reconfiguration:
6184
 
            reconfiguration.apply(force)
6185
 
            reconfiguration = None
6186
 
        if repository_type == 'use-shared':
 
5642
        elif target_type == 'use-shared':
6187
5643
            reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
6188
 
        elif repository_type == 'standalone':
 
5644
        elif target_type == 'standalone':
6189
5645
            reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
6190
 
        if reconfiguration:
6191
 
            reconfiguration.apply(force)
6192
 
            reconfiguration = None
6193
 
        if repository_trees == 'with-trees':
 
5646
        elif target_type == 'with-trees':
6194
5647
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6195
5648
                directory, True)
6196
 
        elif repository_trees == 'with-no-trees':
 
5649
        elif target_type == 'with-no-trees':
6197
5650
            reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6198
5651
                directory, False)
6199
 
        if reconfiguration:
6200
 
            reconfiguration.apply(force)
6201
 
            reconfiguration = None
 
5652
        reconfiguration.apply(force)
6202
5653
 
6203
5654
 
6204
5655
class cmd_switch(Command):
6232
5683
                     Option('create-branch', short_name='b',
6233
5684
                        help='Create the target branch from this one before'
6234
5685
                             ' switching to it.'),
6235
 
                     Option('store',
6236
 
                        help='Store and restore uncommitted changes in the'
6237
 
                             ' branch.'),
6238
5686
                    ]
6239
5687
 
6240
5688
    def run(self, to_location=None, force=False, create_branch=False,
6241
 
            revision=None, directory=u'.', store=False):
 
5689
            revision=None, directory=u'.'):
6242
5690
        from bzrlib import switch
6243
5691
        tree_location = directory
6244
5692
        revision = _get_one_revision('switch', revision)
6245
 
        possible_transports = []
6246
 
        control_dir = controldir.ControlDir.open_containing(tree_location,
6247
 
            possible_transports=possible_transports)[0]
 
5693
        control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
6248
5694
        if to_location is None:
6249
5695
            if revision is None:
6250
 
                raise errors.BzrCommandError(gettext('You must supply either a'
6251
 
                                             ' revision or a location'))
 
5696
                raise errors.BzrCommandError('You must supply either a'
 
5697
                                             ' revision or a location')
6252
5698
            to_location = tree_location
6253
5699
        try:
6254
 
            branch = control_dir.open_branch(
6255
 
                possible_transports=possible_transports)
 
5700
            branch = control_dir.open_branch()
6256
5701
            had_explicit_nick = branch.get_config().has_explicit_nickname()
6257
5702
        except errors.NotBranchError:
6258
5703
            branch = None
6259
5704
            had_explicit_nick = False
6260
5705
        if create_branch:
6261
5706
            if branch is None:
6262
 
                raise errors.BzrCommandError(
6263
 
                    gettext('cannot create branch without source branch'))
6264
 
            to_location = lookup_new_sibling_branch(control_dir, to_location,
6265
 
                 possible_transports=possible_transports)
 
5707
                raise errors.BzrCommandError('cannot create branch without'
 
5708
                                             ' source branch')
 
5709
            to_location = directory_service.directories.dereference(
 
5710
                              to_location)
 
5711
            if '/' not in to_location and '\\' not in to_location:
 
5712
                # This path is meant to be relative to the existing branch
 
5713
                this_url = self._get_branch_location(control_dir)
 
5714
                to_location = urlutils.join(this_url, '..', to_location)
6266
5715
            to_branch = branch.bzrdir.sprout(to_location,
6267
 
                 possible_transports=possible_transports,
6268
 
                 source_branch=branch).open_branch()
 
5716
                                 possible_transports=[branch.bzrdir.root_transport],
 
5717
                                 source_branch=branch).open_branch()
6269
5718
        else:
6270
5719
            try:
6271
 
                to_branch = Branch.open(to_location,
6272
 
                    possible_transports=possible_transports)
 
5720
                to_branch = Branch.open(to_location)
6273
5721
            except errors.NotBranchError:
6274
 
                to_branch = open_sibling_branch(control_dir, to_location,
6275
 
                    possible_transports=possible_transports)
 
5722
                this_url = self._get_branch_location(control_dir)
 
5723
                to_branch = Branch.open(
 
5724
                    urlutils.join(this_url, '..', to_location))
6276
5725
        if revision is not None:
6277
5726
            revision = revision.as_revision_id(to_branch)
6278
 
        switch.switch(control_dir, to_branch, force, revision_id=revision,
6279
 
                      store_uncommitted=store)
 
5727
        switch.switch(control_dir, to_branch, force, revision_id=revision)
6280
5728
        if had_explicit_nick:
6281
5729
            branch = control_dir.open_branch() #get the new branch!
6282
5730
            branch.nick = to_branch.nick
6283
 
        note(gettext('Switched to branch: %s'),
 
5731
        note('Switched to branch: %s',
6284
5732
            urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6285
5733
 
 
5734
    def _get_branch_location(self, control_dir):
 
5735
        """Return location of branch for this control dir."""
 
5736
        try:
 
5737
            this_branch = control_dir.open_branch()
 
5738
            # This may be a heavy checkout, where we want the master branch
 
5739
            master_location = this_branch.get_bound_location()
 
5740
            if master_location is not None:
 
5741
                return master_location
 
5742
            # If not, use a local sibling
 
5743
            return this_branch.base
 
5744
        except errors.NotBranchError:
 
5745
            format = control_dir.find_branch_format()
 
5746
            if getattr(format, 'get_reference', None) is not None:
 
5747
                return format.get_reference(control_dir)
 
5748
            else:
 
5749
                return control_dir.root_transport.base
6286
5750
 
6287
5751
 
6288
5752
class cmd_view(Command):
6379
5843
            name = current_view
6380
5844
        if delete:
6381
5845
            if file_list:
6382
 
                raise errors.BzrCommandError(gettext(
6383
 
                    "Both --delete and a file list specified"))
 
5846
                raise errors.BzrCommandError(
 
5847
                    "Both --delete and a file list specified")
6384
5848
            elif switch:
6385
 
                raise errors.BzrCommandError(gettext(
6386
 
                    "Both --delete and --switch specified"))
 
5849
                raise errors.BzrCommandError(
 
5850
                    "Both --delete and --switch specified")
6387
5851
            elif all:
6388
5852
                tree.views.set_view_info(None, {})
6389
 
                self.outf.write(gettext("Deleted all views.\n"))
 
5853
                self.outf.write("Deleted all views.\n")
6390
5854
            elif name is None:
6391
 
                raise errors.BzrCommandError(gettext("No current view to delete"))
 
5855
                raise errors.BzrCommandError("No current view to delete")
6392
5856
            else:
6393
5857
                tree.views.delete_view(name)
6394
 
                self.outf.write(gettext("Deleted '%s' view.\n") % name)
 
5858
                self.outf.write("Deleted '%s' view.\n" % name)
6395
5859
        elif switch:
6396
5860
            if file_list:
6397
 
                raise errors.BzrCommandError(gettext(
6398
 
                    "Both --switch and a file list specified"))
 
5861
                raise errors.BzrCommandError(
 
5862
                    "Both --switch and a file list specified")
6399
5863
            elif all:
6400
 
                raise errors.BzrCommandError(gettext(
6401
 
                    "Both --switch and --all specified"))
 
5864
                raise errors.BzrCommandError(
 
5865
                    "Both --switch and --all specified")
6402
5866
            elif switch == 'off':
6403
5867
                if current_view is None:
6404
 
                    raise errors.BzrCommandError(gettext("No current view to disable"))
 
5868
                    raise errors.BzrCommandError("No current view to disable")
6405
5869
                tree.views.set_view_info(None, view_dict)
6406
 
                self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
 
5870
                self.outf.write("Disabled '%s' view.\n" % (current_view))
6407
5871
            else:
6408
5872
                tree.views.set_view_info(switch, view_dict)
6409
5873
                view_str = views.view_display_str(tree.views.lookup_view())
6410
 
                self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
 
5874
                self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
6411
5875
        elif all:
6412
5876
            if view_dict:
6413
 
                self.outf.write(gettext('Views defined:\n'))
 
5877
                self.outf.write('Views defined:\n')
6414
5878
                for view in sorted(view_dict):
6415
5879
                    if view == current_view:
6416
5880
                        active = "=>"
6419
5883
                    view_str = views.view_display_str(view_dict[view])
6420
5884
                    self.outf.write('%s %-20s %s\n' % (active, view, view_str))
6421
5885
            else:
6422
 
                self.outf.write(gettext('No views defined.\n'))
 
5886
                self.outf.write('No views defined.\n')
6423
5887
        elif file_list:
6424
5888
            if name is None:
6425
5889
                # No name given and no current view set
6426
5890
                name = 'my'
6427
5891
            elif name == 'off':
6428
 
                raise errors.BzrCommandError(gettext(
6429
 
                    "Cannot change the 'off' pseudo view"))
 
5892
                raise errors.BzrCommandError(
 
5893
                    "Cannot change the 'off' pseudo view")
6430
5894
            tree.views.set_view(name, sorted(file_list))
6431
5895
            view_str = views.view_display_str(tree.views.lookup_view())
6432
 
            self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
 
5896
            self.outf.write("Using '%s' view: %s\n" % (name, view_str))
6433
5897
        else:
6434
5898
            # list the files
6435
5899
            if name is None:
6436
5900
                # No name given and no current view set
6437
 
                self.outf.write(gettext('No current view.\n'))
 
5901
                self.outf.write('No current view.\n')
6438
5902
            else:
6439
5903
                view_str = views.view_display_str(tree.views.lookup_view(name))
6440
 
                self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
 
5904
                self.outf.write("'%s' view is: %s\n" % (name, view_str))
6441
5905
 
6442
5906
 
6443
5907
class cmd_hooks(Command):
6457
5921
                        self.outf.write("    %s\n" %
6458
5922
                                        (some_hooks.get_hook_name(hook),))
6459
5923
                else:
6460
 
                    self.outf.write(gettext("    <no hooks installed>\n"))
 
5924
                    self.outf.write("    <no hooks installed>\n")
6461
5925
 
6462
5926
 
6463
5927
class cmd_remove_branch(Command):
6476
5940
 
6477
5941
    takes_args = ["location?"]
6478
5942
 
6479
 
    takes_options = ['directory',
6480
 
        Option('force', help='Remove branch even if it is the active branch.')]
6481
 
 
6482
5943
    aliases = ["rmbranch"]
6483
5944
 
6484
 
    def run(self, directory=None, location=None, force=False):
6485
 
        br = open_nearby_branch(near=directory, location=location)
6486
 
        if not force and br.bzrdir.has_workingtree():
6487
 
            try:
6488
 
                active_branch = br.bzrdir.open_branch(name="")
6489
 
            except errors.NotBranchError:
6490
 
                active_branch = None
6491
 
            if (active_branch is not None and
6492
 
                br.control_url == active_branch.control_url):
6493
 
                raise errors.BzrCommandError(
6494
 
                    gettext("Branch is active. Use --force to remove it."))
6495
 
        br.bzrdir.destroy_branch(br.name)
 
5945
    def run(self, location=None):
 
5946
        if location is None:
 
5947
            location = "."
 
5948
        branch = Branch.open_containing(location)[0]
 
5949
        branch.bzrdir.destroy_branch()
6496
5950
 
6497
5951
 
6498
5952
class cmd_shelve(Command):
6574
6028
        manager = tree.get_shelf_manager()
6575
6029
        shelves = manager.active_shelves()
6576
6030
        if len(shelves) == 0:
6577
 
            note(gettext('No shelved changes.'))
 
6031
            note('No shelved changes.')
6578
6032
            return 0
6579
6033
        for shelf_id in reversed(shelves):
6580
6034
            message = manager.get_metadata(shelf_id).get('message')
6669
6123
        if path is not None:
6670
6124
            branchdir = path
6671
6125
        tree, branch, relpath =(
6672
 
            controldir.ControlDir.open_containing_tree_or_branch(branchdir))
 
6126
            bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
6673
6127
        if path is not None:
6674
6128
            path = relpath
6675
6129
        if tree is None:
6699
6153
            self.outf.write('%s %s\n' % (path, location))
6700
6154
 
6701
6155
 
6702
 
class cmd_export_pot(Command):
6703
 
    __doc__ = """Export command helps and error messages in po format."""
6704
 
 
6705
 
    hidden = True
6706
 
    takes_options = [Option('plugin', 
6707
 
                            help='Export help text from named command '\
6708
 
                                 '(defaults to all built in commands).',
6709
 
                            type=str),
6710
 
                     Option('include-duplicates',
6711
 
                            help='Output multiple copies of the same msgid '
6712
 
                                 'string if it appears more than once.'),
6713
 
                            ]
6714
 
 
6715
 
    def run(self, plugin=None, include_duplicates=False):
6716
 
        from bzrlib.export_pot import export_pot
6717
 
        export_pot(self.outf, plugin, include_duplicates)
6718
 
 
6719
 
 
6720
6156
def _register_lazy_builtins():
6721
6157
    # register lazy builtins from other modules; called at startup and should
6722
6158
    # be only called once.
6727
6163
        ('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6728
6164
        ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6729
6165
        ('cmd_conflicts', [], 'bzrlib.conflicts'),
6730
 
        ('cmd_ping', [], 'bzrlib.smart.ping'),
6731
 
        ('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6732
 
        ('cmd_verify_signatures', [], 'bzrlib.commit_signature_commands'),
 
6166
        ('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6733
6167
        ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6734
6168
        ]:
6735
6169
        builtin_command_registry.register_lazy(name, aliases, module_name)