/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Richard Wilbur
  • Date: 2016-02-04 19:07:28 UTC
  • mto: This revision was merged to the branch mainline in revision 6618.
  • Revision ID: richard.wilbur@gmail.com-20160204190728-p0zvfii6zase0fw7
Update COPYING.txt from the original http://www.gnu.org/licenses/gpl-2.0.txt  (Only differences were in whitespace.)  Thanks to Petr Stodulka for pointing out the discrepancy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
"""builtin brz commands"""
18
 
 
 
17
"""builtin bzr commands"""
 
18
 
 
19
from __future__ import absolute_import
 
20
 
 
21
import os
 
22
 
 
23
import bzrlib.bzrdir
 
24
 
 
25
from bzrlib import lazy_import
 
26
lazy_import.lazy_import(globals(), """
 
27
import cStringIO
19
28
import errno
20
 
import os
21
29
import sys
22
 
 
23
 
import breezy.bzr
24
 
import breezy.git
25
 
 
26
 
from . import (
27
 
    errors,
28
 
    )
29
 
 
30
 
from . import lazy_import
31
 
lazy_import.lazy_import(globals(), """
32
30
import time
33
31
 
34
 
import breezy
35
 
from breezy import (
36
 
    branch as _mod_branch,
 
32
import bzrlib
 
33
from bzrlib import (
37
34
    bugtracker,
38
 
    cache_utf8,
 
35
    bundle,
 
36
    btree_index,
39
37
    controldir,
40
38
    directory_service,
41
39
    delta,
42
40
    config as _mod_config,
 
41
    errors,
43
42
    globbing,
44
 
    gpg,
45
43
    hooks,
46
 
    lazy_regex,
47
44
    log,
48
45
    merge as _mod_merge,
49
 
    mergeable as _mod_mergeable,
50
46
    merge_directive,
51
47
    osutils,
52
48
    reconfigure,
53
49
    rename_map,
54
50
    revision as _mod_revision,
55
 
    symbol_versioning,
 
51
    static_tuple,
56
52
    timestamp,
57
53
    transport,
58
 
    tree as _mod_tree,
59
54
    ui,
60
55
    urlutils,
61
56
    views,
 
57
    gpg,
62
58
    )
63
 
from breezy.branch import Branch
64
 
from breezy.conflicts import ConflictList
65
 
from breezy.transport import memory
66
 
from breezy.smtp_connection import SMTPConnection
67
 
from breezy.workingtree import WorkingTree
68
 
from breezy.i18n import gettext, ngettext
 
59
from bzrlib.branch import Branch
 
60
from bzrlib.conflicts import ConflictList
 
61
from bzrlib.transport import memory
 
62
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
 
63
from bzrlib.smtp_connection import SMTPConnection
 
64
from bzrlib.workingtree import WorkingTree
 
65
from bzrlib.i18n import gettext, ngettext
69
66
""")
70
67
 
71
 
from .commands import (
 
68
from bzrlib.commands import (
72
69
    Command,
73
70
    builtin_command_registry,
74
71
    display_command,
75
72
    )
76
 
from .option import (
 
73
from bzrlib.option import (
77
74
    ListOption,
78
75
    Option,
79
76
    RegistryOption,
80
77
    custom_help,
81
78
    _parse_revision_str,
82
79
    )
83
 
from .revisionspec import (
84
 
    RevisionSpec,
85
 
    RevisionInfo,
 
80
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
 
81
from bzrlib import (
 
82
    symbol_versioning,
86
83
    )
87
 
from .trace import mutter, note, warning, is_quiet, get_verbosity_level
88
84
 
89
85
 
90
86
def _get_branch_location(control_dir, possible_transports=None):
113
109
        and the full URL to the actual branch
114
110
    """
115
111
    # This path is meant to be relative to the existing branch
116
 
    this_url = _get_branch_location(
117
 
        control_dir, possible_transports=possible_transports)
 
112
    this_url = _get_branch_location(control_dir,
 
113
        possible_transports=possible_transports)
118
114
    # Perhaps the target control dir supports colocated branches?
119
115
    try:
120
 
        root = controldir.ControlDir.open(
121
 
            this_url, possible_transports=possible_transports)
 
116
        root = controldir.ControlDir.open(this_url,
 
117
            possible_transports=possible_transports)
122
118
    except errors.NotBranchError:
123
119
        return (False, this_url)
124
120
    else:
125
121
        try:
126
 
            control_dir.open_workingtree()
 
122
            wt = control_dir.open_workingtree()
127
123
        except (errors.NoWorkingTree, errors.NotLocalUrl):
128
124
            return (False, this_url)
129
125
        else:
145
141
        (colocated, this_url) = _is_colocated(control_dir, possible_transports)
146
142
 
147
143
        if colocated:
148
 
            return urlutils.join_segment_parameters(
149
 
                this_url, {"branch": urlutils.escape(location)})
 
144
            return urlutils.join_segment_parameters(this_url,
 
145
                {"branch": urlutils.escape(location)})
150
146
        else:
151
147
            return urlutils.join(this_url, '..', urlutils.escape(location))
152
148
    return location
162
158
    """
163
159
    try:
164
160
        # Perhaps it's a colocated branch?
165
 
        return control_dir.open_branch(
166
 
            location, possible_transports=possible_transports)
 
161
        return control_dir.open_branch(location, 
 
162
            possible_transports=possible_transports)
167
163
    except (errors.NotBranchError, errors.NoColocatedBranchSupport):
168
164
        this_url = _get_branch_location(control_dir)
169
165
        return Branch.open(
182
178
        if location is None:
183
179
            location = "."
184
180
        try:
185
 
            return Branch.open(
186
 
                location, possible_transports=possible_transports)
 
181
            return Branch.open(location,
 
182
                possible_transports=possible_transports)
187
183
        except errors.NotBranchError:
188
184
            near = "."
189
 
    cdir = controldir.ControlDir.open(
190
 
        near, possible_transports=possible_transports)
191
 
    return open_sibling_branch(
192
 
        cdir, location, possible_transports=possible_transports)
 
185
    cdir = controldir.ControlDir.open(near,
 
186
        possible_transports=possible_transports)
 
187
    return open_sibling_branch(cdir, location,
 
188
        possible_transports=possible_transports)
193
189
 
194
190
 
195
191
def iter_sibling_branches(control_dir, possible_transports=None):
198
194
    :param control_dir: Control directory for which to look up the siblings
199
195
    :return: Iterator over tuples with branch name and branch object
200
196
    """
 
197
    seen_urls = set()
201
198
    try:
202
199
        reference = control_dir.get_branch_reference()
203
200
    except errors.NotBranchError:
204
 
        reference = None
 
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
205
    if reference is not None:
206
 
        try:
207
 
            ref_branch = Branch.open(
208
 
                reference, possible_transports=possible_transports)
209
 
        except errors.NotBranchError:
210
 
            ref_branch = None
 
206
        ref_branch = Branch.open(reference,
 
207
            possible_transports=possible_transports)
211
208
    else:
212
209
        ref_branch = None
213
210
    if ref_branch is None or ref_branch.name:
214
211
        if ref_branch is not None:
215
 
            control_dir = ref_branch.controldir
216
 
        for name, branch in control_dir.get_branches().items():
 
212
            control_dir = ref_branch.bzrdir
 
213
        for name, branch in control_dir.get_branches().iteritems():
217
214
            yield name, branch
218
215
    else:
219
 
        repo = ref_branch.controldir.find_repository()
 
216
        repo = ref_branch.bzrdir.find_repository()
220
217
        for branch in repo.find_branches(using=True):
221
 
            name = urlutils.relative_url(
222
 
                repo.user_url, branch.user_url).rstrip("/")
 
218
            name = urlutils.relative_url(repo.user_url,
 
219
                branch.user_url).rstrip("/")
223
220
            yield name, branch
224
221
 
225
222
 
241
238
            if view_files:
242
239
                for filename in file_list:
243
240
                    if not osutils.is_inside_any(view_files, filename):
244
 
                        raise views.FileOutsideView(filename, view_files)
 
241
                        raise errors.FileOutsideView(filename, view_files)
245
242
        file_list = file_list[:]
246
243
        file_list[0] = tree.abspath(relpath)
247
244
    else:
251
248
            if view_files:
252
249
                file_list = view_files
253
250
                view_str = views.view_display_str(view_files)
254
 
                note(gettext("Ignoring files outside view. View is %s"),
255
 
                     view_str)
 
251
                note(gettext("Ignoring files outside view. View is %s") % view_str)
256
252
    return tree, file_list
257
253
 
258
254
 
260
256
    if revisions is None:
261
257
        return None
262
258
    if len(revisions) != 1:
263
 
        raise errors.CommandError(gettext(
264
 
            'brz %s --revision takes exactly one revision identifier') % (
 
259
        raise errors.BzrCommandError(gettext(
 
260
            'bzr %s --revision takes exactly one revision identifier') % (
265
261
                command_name,))
266
262
    return revisions[0]
267
263
 
268
264
 
269
265
def _get_one_revision_tree(command_name, revisions, branch=None, tree=None):
270
266
    """Get a revision tree. Not suitable for commands that change the tree.
271
 
 
 
267
    
272
268
    Specifically, the basis tree in dirstate trees is coupled to the dirstate
273
269
    and doing a commit/uncommit/pull will at best fail due to changing the
274
270
    basis revision data.
296
292
        current_view = tree.views.get_view_info()[0]
297
293
        if current_view is not None:
298
294
            view_info = (current_view, tree.views.lookup_view())
299
 
    except views.ViewsNotSupported:
 
295
    except errors.ViewsNotSupported:
300
296
        pass
301
297
    return view_info
302
298
 
343
339
        Not versioned and not matching an ignore pattern.
344
340
 
345
341
    Additionally for directories, symlinks and files with a changed
346
 
    executable bit, Breezy indicates their type using a trailing
 
342
    executable bit, Bazaar indicates their type using a trailing
347
343
    character: '/', '@' or '*' respectively. These decorations can be
348
344
    disabled using the '--no-classify' option.
349
345
 
350
 
    To see ignored files use 'brz ignored'.  For details on the
351
 
    changes to file texts, use 'brz diff'.
 
346
    To see ignored files use 'bzr ignored'.  For details on the
 
347
    changes to file texts, use 'bzr diff'.
352
348
 
353
349
    Note that --short or -S gives status flags for each item, similar
354
350
    to Subversion's status command. To get output similar to svn -q,
355
 
    use brz status -SV.
 
351
    use bzr status -SV.
356
352
 
357
353
    If no arguments are specified, the status of the entire working
358
354
    directory is shown.  Otherwise, only the status of the specified
369
365
 
370
366
    To see which files have changed in a specific revision, or between
371
367
    two revisions, pass a revision range to the revision argument.
372
 
    This will produce the same results as calling 'brz diff --summarize'.
 
368
    This will produce the same results as calling 'bzr diff --summarize'.
373
369
    """
374
370
 
375
371
    # TODO: --no-recurse/-N, --recurse options
380
376
                            short_name='S'),
381
377
                     Option('versioned', help='Only show versioned files.',
382
378
                            short_name='V'),
383
 
                     Option('no-pending', help='Don\'t show pending merges.'),
 
379
                     Option('no-pending', help='Don\'t show pending merges.',
 
380
                           ),
384
381
                     Option('no-classify',
385
 
                            help='Do not mark object type using indicator.'),
 
382
                            help='Do not mark object type using indicator.',
 
383
                           ),
386
384
                     ]
387
385
    aliases = ['st', 'stat']
388
386
 
393
391
    def run(self, show_ids=False, file_list=None, revision=None, short=False,
394
392
            versioned=False, no_pending=False, verbose=False,
395
393
            no_classify=False):
396
 
        from .status import show_tree_status
 
394
        from bzrlib.status import show_tree_status
397
395
 
398
396
        if revision and len(revision) > 2:
399
 
            raise errors.CommandError(
400
 
                gettext('brz status --revision takes exactly'
401
 
                        ' one or two revision specifiers'))
 
397
            raise errors.BzrCommandError(gettext('bzr status --revision takes exactly'
 
398
                                         ' one or two revision specifiers'))
402
399
 
403
400
        tree, relfile_list = WorkingTree.open_containing_paths(file_list)
404
401
        # Avoid asking for specific files when that is not needed.
432
429
 
433
430
    def print_revision(self, revisions, revid):
434
431
        stream = revisions.get_record_stream([(revid,)], 'unordered', True)
435
 
        record = next(stream)
 
432
        record = stream.next()
436
433
        if record.storage_kind == 'absent':
437
434
            raise errors.NoSuchRevision(revisions, revid)
438
435
        revtext = record.get_bytes_as('fulltext')
441
438
    @display_command
442
439
    def run(self, revision_id=None, revision=None, directory=u'.'):
443
440
        if revision_id is not None and revision is not None:
444
 
            raise errors.CommandError(gettext('You can only supply one of'
445
 
                                                 ' revision_id or --revision'))
 
441
            raise errors.BzrCommandError(gettext('You can only supply one of'
 
442
                                         ' revision_id or --revision'))
446
443
        if revision_id is None and revision is None:
447
 
            raise errors.CommandError(
448
 
                gettext('You must supply either --revision or a revision_id'))
 
444
            raise errors.BzrCommandError(gettext('You must supply either'
 
445
                                         ' --revision or a revision_id'))
449
446
 
450
447
        b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
451
448
 
452
 
        revisions = getattr(b.repository, "revisions", None)
 
449
        revisions = b.repository.revisions
453
450
        if revisions is None:
454
 
            raise errors.CommandError(
455
 
                gettext('Repository %r does not support '
456
 
                        'access to raw revision texts') % b.repository)
 
451
            raise errors.BzrCommandError(gettext('Repository %r does not support '
 
452
                'access to raw revision texts'))
457
453
 
458
 
        with b.repository.lock_read():
 
454
        b.repository.lock_read()
 
455
        try:
459
456
            # TODO: jam 20060112 should cat-revision always output utf-8?
460
457
            if revision_id is not None:
461
 
                revision_id = cache_utf8.encode(revision_id)
 
458
                revision_id = osutils.safe_revision_id(revision_id, warn=False)
462
459
                try:
463
460
                    self.print_revision(revisions, revision_id)
464
461
                except errors.NoSuchRevision:
465
 
                    msg = gettext(
466
 
                        "The repository {0} contains no revision {1}.").format(
467
 
                            b.repository.base, revision_id.decode('utf-8'))
468
 
                    raise errors.CommandError(msg)
 
462
                    msg = gettext("The repository {0} contains no revision {1}.").format(
 
463
                        b.repository.base, revision_id)
 
464
                    raise errors.BzrCommandError(msg)
469
465
            elif revision is not None:
470
466
                for rev in revision:
471
467
                    if rev is None:
472
 
                        raise errors.CommandError(
 
468
                        raise errors.BzrCommandError(
473
469
                            gettext('You cannot specify a NULL revision.'))
474
470
                    rev_id = rev.as_revision_id(b)
475
471
                    self.print_revision(revisions, rev_id)
 
472
        finally:
 
473
            b.repository.unlock()
 
474
        
 
475
 
 
476
class cmd_dump_btree(Command):
 
477
    __doc__ = """Dump the contents of a btree index file to stdout.
 
478
 
 
479
    PATH is a btree index file, it can be any URL. This includes things like
 
480
    .bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
 
481
 
 
482
    By default, the tuples stored in the index file will be displayed. With
 
483
    --raw, we will uncompress the pages, but otherwise display the raw bytes
 
484
    stored in the index.
 
485
    """
 
486
 
 
487
    # TODO: Do we want to dump the internal nodes as well?
 
488
    # TODO: It would be nice to be able to dump the un-parsed information,
 
489
    #       rather than only going through iter_all_entries. However, this is
 
490
    #       good enough for a start
 
491
    hidden = True
 
492
    encoding_type = 'exact'
 
493
    takes_args = ['path']
 
494
    takes_options = [Option('raw', help='Write the uncompressed bytes out,'
 
495
                                        ' rather than the parsed tuples.'),
 
496
                    ]
 
497
 
 
498
    def run(self, path, raw=False):
 
499
        dirname, basename = osutils.split(path)
 
500
        t = transport.get_transport(dirname)
 
501
        if raw:
 
502
            self._dump_raw_bytes(t, basename)
 
503
        else:
 
504
            self._dump_entries(t, basename)
 
505
 
 
506
    def _get_index_and_bytes(self, trans, basename):
 
507
        """Create a BTreeGraphIndex and raw bytes."""
 
508
        bt = btree_index.BTreeGraphIndex(trans, basename, None)
 
509
        bytes = trans.get_bytes(basename)
 
510
        bt._file = cStringIO.StringIO(bytes)
 
511
        bt._size = len(bytes)
 
512
        return bt, bytes
 
513
 
 
514
    def _dump_raw_bytes(self, trans, basename):
 
515
        import zlib
 
516
 
 
517
        # We need to parse at least the root node.
 
518
        # This is because the first page of every row starts with an
 
519
        # uncompressed header.
 
520
        bt, bytes = self._get_index_and_bytes(trans, basename)
 
521
        for page_idx, page_start in enumerate(xrange(0, len(bytes),
 
522
                                                     btree_index._PAGE_SIZE)):
 
523
            page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
 
524
            page_bytes = bytes[page_start:page_end]
 
525
            if page_idx == 0:
 
526
                self.outf.write('Root node:\n')
 
527
                header_end, data = bt._parse_header_from_bytes(page_bytes)
 
528
                self.outf.write(page_bytes[:header_end])
 
529
                page_bytes = data
 
530
            self.outf.write('\nPage %d\n' % (page_idx,))
 
531
            if len(page_bytes) == 0:
 
532
                self.outf.write('(empty)\n');
 
533
            else:
 
534
                decomp_bytes = zlib.decompress(page_bytes)
 
535
                self.outf.write(decomp_bytes)
 
536
                self.outf.write('\n')
 
537
 
 
538
    def _dump_entries(self, trans, basename):
 
539
        try:
 
540
            st = trans.stat(basename)
 
541
        except errors.TransportNotPossible:
 
542
            # We can't stat, so we'll fake it because we have to do the 'get()'
 
543
            # anyway.
 
544
            bt, _ = self._get_index_and_bytes(trans, basename)
 
545
        else:
 
546
            bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
 
547
        for node in bt.iter_all_entries():
 
548
            # Node is made up of:
 
549
            # (index, key, value, [references])
 
550
            try:
 
551
                refs = node[3]
 
552
            except IndexError:
 
553
                refs_as_tuples = None
 
554
            else:
 
555
                refs_as_tuples = static_tuple.as_tuples(refs)
 
556
            as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
 
557
            self.outf.write('%s\n' % (as_tuple,))
476
558
 
477
559
 
478
560
class cmd_remove_tree(Command):
481
563
    Since a lightweight checkout is little more than a working tree
482
564
    this will refuse to run against one.
483
565
 
484
 
    To re-create the working tree, use "brz checkout".
 
566
    To re-create the working tree, use "bzr checkout".
485
567
    """
486
568
    _see_also = ['checkout', 'working-trees']
487
569
    takes_args = ['location*']
493
575
 
494
576
    def run(self, location_list, force=False):
495
577
        if not location_list:
496
 
            location_list = ['.']
 
578
            location_list=['.']
497
579
 
498
580
        for location in location_list:
499
581
            d = controldir.ControlDir.open(location)
501
583
            try:
502
584
                working = d.open_workingtree()
503
585
            except errors.NoWorkingTree:
504
 
                raise errors.CommandError(
505
 
                    gettext("No working tree to remove"))
 
586
                raise errors.BzrCommandError(gettext("No working tree to remove"))
506
587
            except errors.NotLocalUrl:
507
 
                raise errors.CommandError(
508
 
                    gettext("You cannot remove the working tree"
509
 
                            " of a remote path"))
 
588
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
589
                                             " of a remote path"))
510
590
            if not force:
511
591
                if (working.has_changes()):
512
592
                    raise errors.UncommittedChanges(working)
514
594
                    raise errors.ShelvedChanges(working)
515
595
 
516
596
            if working.user_url != working.branch.user_url:
517
 
                raise errors.CommandError(
518
 
                    gettext("You cannot remove the working tree"
519
 
                            " from a lightweight checkout"))
 
597
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
 
598
                                             " from a lightweight checkout"))
520
599
 
521
600
            d.destroy_workingtree()
522
601
 
529
608
    'known good' state. Any new modifications (adding a file, renaming, etc)
530
609
    will be lost, though modified files will still be detected as such.
531
610
 
532
 
    Most users will want something more like "brz revert" or "brz update"
 
611
    Most users will want something more like "bzr revert" or "bzr update"
533
612
    unless the state file has become corrupted.
534
613
 
535
614
    By default this attempts to recover the current state by looking at the
537
616
    that, you can supply --revision to force the state of the tree.
538
617
    """
539
618
 
540
 
    takes_options = [
541
 
        'revision', 'directory',
 
619
    takes_options = ['revision', 'directory',
542
620
        Option('force',
543
621
               help='Reset the tree even if it doesn\'t appear to be'
544
622
                    ' corrupted.'),
547
625
 
548
626
    def run(self, revision=None, directory='.', force=False):
549
627
        tree, _ = WorkingTree.open_containing(directory)
550
 
        self.enter_context(tree.lock_tree_write())
 
628
        self.add_cleanup(tree.lock_tree_write().unlock)
551
629
        if not force:
552
630
            try:
553
631
                tree.check_state()
554
632
            except errors.BzrError:
555
 
                pass  # There seems to be a real error here, so we'll reset
 
633
                pass # There seems to be a real error here, so we'll reset
556
634
            else:
557
635
                # Refuse
558
 
                raise errors.CommandError(gettext(
 
636
                raise errors.BzrCommandError(gettext(
559
637
                    'The tree does not appear to be corrupt. You probably'
560
 
                    ' want "brz revert" instead. Use "--force" if you are'
 
638
                    ' want "bzr revert" instead. Use "--force" if you are'
561
639
                    ' sure you want to reset the working tree.'))
562
640
        if revision is None:
563
641
            revision_ids = None
565
643
            revision_ids = [r.as_revision_id(tree.branch) for r in revision]
566
644
        try:
567
645
            tree.reset_state(revision_ids)
568
 
        except errors.BzrError:
 
646
        except errors.BzrError, e:
569
647
            if revision_ids is None:
570
 
                extra = gettext(', the header appears corrupt, try passing '
571
 
                                '-r -1 to set the state to the last commit')
 
648
                extra = (gettext(', the header appears corrupt, try passing -r -1'
 
649
                         ' to set the state to the last commit'))
572
650
            else:
573
651
                extra = ''
574
 
            raise errors.CommandError(
575
 
                gettext('failed to reset the tree state{0}').format(extra))
 
652
            raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
576
653
 
577
654
 
578
655
class cmd_revno(Command):
591
668
    @display_command
592
669
    def run(self, tree=False, location=u'.', revision=None):
593
670
        if revision is not None and tree:
594
 
            raise errors.CommandError(
595
 
                gettext("--tree and --revision can not be used together"))
 
671
            raise errors.BzrCommandError(gettext("--tree and --revision can "
 
672
                "not be used together"))
596
673
 
597
674
        if tree:
598
675
            try:
599
676
                wt = WorkingTree.open_containing(location)[0]
600
 
                self.enter_context(wt.lock_read())
 
677
                self.add_cleanup(wt.lock_read().unlock)
601
678
            except (errors.NoWorkingTree, errors.NotLocalUrl):
602
679
                raise errors.NoWorkingTree(location)
603
680
            b = wt.branch
604
681
            revid = wt.last_revision()
605
682
        else:
606
683
            b = Branch.open_containing(location)[0]
607
 
            self.enter_context(b.lock_read())
 
684
            self.add_cleanup(b.lock_read().unlock)
608
685
            if revision:
609
686
                if len(revision) != 1:
610
 
                    raise errors.CommandError(gettext(
 
687
                    raise errors.BzrCommandError(gettext(
611
688
                        "Revision numbers only make sense for single "
612
689
                        "revisions, not ranges"))
613
690
                revid = revision[0].as_revision_id(b)
615
692
                revid = b.last_revision()
616
693
        try:
617
694
            revno_t = b.revision_id_to_dotted_revno(revid)
618
 
        except (errors.NoSuchRevision, errors.GhostRevisionsHaveNoRevno):
 
695
        except errors.NoSuchRevision:
619
696
            revno_t = ('???',)
620
697
        revno = ".".join(str(n) for n in revno_t)
621
698
        self.cleanup_now()
629
706
    takes_args = ['revision_info*']
630
707
    takes_options = [
631
708
        'revision',
632
 
        custom_help('directory', help='Branch to examine, '
633
 
                    'rather than the one containing the working directory.'),
 
709
        custom_help('directory',
 
710
            help='Branch to examine, '
 
711
                 'rather than the one containing the working directory.'),
634
712
        Option('tree', help='Show revno of working tree.'),
635
713
        ]
636
714
 
641
719
        try:
642
720
            wt = WorkingTree.open_containing(directory)[0]
643
721
            b = wt.branch
644
 
            self.enter_context(wt.lock_read())
 
722
            self.add_cleanup(wt.lock_read().unlock)
645
723
        except (errors.NoWorkingTree, errors.NotLocalUrl):
646
724
            wt = None
647
725
            b = Branch.open_containing(directory)[0]
648
 
            self.enter_context(b.lock_read())
 
726
            self.add_cleanup(b.lock_read().unlock)
649
727
        revision_ids = []
650
728
        if revision is not None:
651
729
            revision_ids.extend(rev.as_revision_id(b) for rev in revision)
671
749
            except errors.NoSuchRevision:
672
750
                revno = '???'
673
751
            maxlen = max(maxlen, len(revno))
674
 
            revinfos.append((revno, revision_id))
 
752
            revinfos.append([revno, revision_id])
675
753
 
676
754
        self.cleanup_now()
677
 
        for revno, revid in revinfos:
678
 
            self.outf.write(
679
 
                '%*s %s\n' % (maxlen, revno, revid.decode('utf-8')))
 
755
        for ri in revinfos:
 
756
            self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
680
757
 
681
758
 
682
759
class cmd_add(Command):
697
774
    A warning will be printed when nested trees are encountered,
698
775
    unless they are explicitly ignored.
699
776
 
700
 
    Therefore simply saying 'brz add' will version all files that
 
777
    Therefore simply saying 'bzr add' will version all files that
701
778
    are currently unknown.
702
779
 
703
780
    Adding a file whose parent directory is not versioned will
715
792
    branches that will be merged later (without showing the two different
716
793
    adds as a conflict). It is also useful when merging another project
717
794
    into a subdirectory of this one.
718
 
 
 
795
    
719
796
    Any files matching patterns in the ignore list will not be added
720
797
    unless they are explicitly mentioned.
721
 
 
722
 
    In recursive mode, files larger than the configuration option
 
798
    
 
799
    In recursive mode, files larger than the configuration option 
723
800
    add.maximum_file_size will be skipped. Named items are never skipped due
724
801
    to file size.
725
802
    """
729
806
               help="Don't recursively add the contents of directories.",
730
807
               short_name='N'),
731
808
        Option('dry-run',
732
 
               help="Show what would be done, but don't actually do "
733
 
                    "anything."),
 
809
               help="Show what would be done, but don't actually do anything."),
734
810
        'verbose',
735
811
        Option('file-ids-from',
736
 
               type=str,
 
812
               type=unicode,
737
813
               help='Lookup file ids from this tree.'),
738
814
        ]
739
815
    encoding_type = 'replace'
741
817
 
742
818
    def run(self, file_list, no_recurse=False, dry_run=False, verbose=False,
743
819
            file_ids_from=None):
744
 
        import breezy.add
745
 
        tree, file_list = tree_files_for_add(file_list)
746
 
 
747
 
        if file_ids_from is not None and not tree.supports_setting_file_ids():
748
 
            warning(
749
 
                gettext('Ignoring --file-ids-from, since the tree does not '
750
 
                        'support setting file ids.'))
751
 
            file_ids_from = None
 
820
        import bzrlib.add
752
821
 
753
822
        base_tree = None
754
823
        if file_ids_from is not None:
755
824
            try:
756
825
                base_tree, base_path = WorkingTree.open_containing(
757
 
                    file_ids_from)
 
826
                                            file_ids_from)
758
827
            except errors.NoWorkingTree:
759
828
                base_branch, base_path = Branch.open_containing(
760
 
                    file_ids_from)
 
829
                                            file_ids_from)
761
830
                base_tree = base_branch.basis_tree()
762
831
 
763
 
            action = breezy.add.AddFromBaseAction(
764
 
                base_tree, base_path, to_file=self.outf,
 
832
            action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
 
833
                          to_file=self.outf, should_print=(not is_quiet()))
 
834
        else:
 
835
            action = bzrlib.add.AddWithSkipLargeAction(to_file=self.outf,
765
836
                should_print=(not is_quiet()))
766
 
        else:
767
 
            action = breezy.add.AddWithSkipLargeAction(
768
 
                to_file=self.outf, should_print=(not is_quiet()))
769
837
 
770
838
        if base_tree:
771
 
            self.enter_context(base_tree.lock_read())
772
 
        added, ignored = tree.smart_add(
773
 
            file_list, not no_recurse, action=action, save=not dry_run)
 
839
            self.add_cleanup(base_tree.lock_read().unlock)
 
840
        tree, file_list = tree_files_for_add(file_list)
 
841
        added, ignored = tree.smart_add(file_list, not
 
842
            no_recurse, action=action, save=not dry_run)
774
843
        self.cleanup_now()
775
844
        if len(ignored) > 0:
776
845
            if verbose:
777
 
                for glob in sorted(ignored):
 
846
                for glob in sorted(ignored.keys()):
778
847
                    for path in ignored[glob]:
779
848
                        self.outf.write(
780
 
                            gettext("ignored {0} matching \"{1}\"\n").format(
781
 
                                path, glob))
 
849
                         gettext("ignored {0} matching \"{1}\"\n").format(
 
850
                         path, glob))
782
851
 
783
852
 
784
853
class cmd_mkdir(Command):
799
868
 
800
869
    @classmethod
801
870
    def add_file_with_parents(cls, wt, relpath):
802
 
        if wt.is_versioned(relpath):
 
871
        if wt.path2id(relpath) is not None:
803
872
            return
804
873
        cls.add_file_with_parents(wt, osutils.dirname(relpath))
805
874
        wt.add([relpath])
818
887
            if parents:
819
888
                try:
820
889
                    os.makedirs(dir)
821
 
                except OSError as e:
 
890
                except OSError, e:
822
891
                    if e.errno != errno.EEXIST:
823
892
                        raise
824
893
            else:
850
919
    type using the --kind option.  For example: --kind file.
851
920
 
852
921
    It is also possible to restrict the list of files to a specific
853
 
    set. For example: brz inventory --show-ids this/file
 
922
    set. For example: bzr inventory --show-ids this/file
854
923
    """
855
924
 
856
925
    hidden = True
858
927
    takes_options = [
859
928
        'revision',
860
929
        'show-ids',
861
 
        Option('include-root',
862
 
               help='Include the entry for the root of the tree, if any.'),
863
930
        Option('kind',
864
 
               help='List entries of a particular kind: file, directory, '
865
 
                    'symlink.',
866
 
               type=str),
 
931
               help='List entries of a particular kind: file, directory, symlink.',
 
932
               type=unicode),
867
933
        ]
868
934
    takes_args = ['file*']
869
935
 
870
936
    @display_command
871
 
    def run(self, revision=None, show_ids=False, kind=None, include_root=False,
872
 
            file_list=None):
 
937
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
873
938
        if kind and kind not in ['file', 'directory', 'symlink']:
874
 
            raise errors.CommandError(
875
 
                gettext('invalid kind %r specified') % (kind,))
 
939
            raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
876
940
 
877
941
        revision = _get_one_revision('inventory', revision)
878
942
        work_tree, file_list = WorkingTree.open_containing_paths(file_list)
879
 
        self.enter_context(work_tree.lock_read())
 
943
        self.add_cleanup(work_tree.lock_read().unlock)
880
944
        if revision is not None:
881
945
            tree = revision.as_tree(work_tree.branch)
882
946
 
883
947
            extra_trees = [work_tree]
884
 
            self.enter_context(tree.lock_read())
 
948
            self.add_cleanup(tree.lock_read().unlock)
885
949
        else:
886
950
            tree = work_tree
887
951
            extra_trees = []
888
952
 
889
 
        self.enter_context(tree.lock_read())
 
953
        self.add_cleanup(tree.lock_read().unlock)
890
954
        if file_list is not None:
891
 
            paths = tree.find_related_paths_across_trees(
892
 
                file_list, extra_trees, require_versioned=True)
 
955
            file_ids = tree.paths2ids(file_list, trees=extra_trees,
 
956
                                      require_versioned=True)
893
957
            # find_ids_across_trees may include some paths that don't
894
958
            # exist in 'tree'.
895
 
            entries = tree.iter_entries_by_dir(specific_files=paths)
 
959
            entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
896
960
        else:
897
961
            entries = tree.iter_entries_by_dir()
898
962
 
899
963
        for path, entry in sorted(entries):
900
964
            if kind and kind != entry.kind:
901
965
                continue
902
 
            if path == "" and not include_root:
 
966
            if path == "":
903
967
                continue
904
968
            if show_ids:
905
 
                self.outf.write('%-50s %s\n' % (
906
 
                    path, entry.file_id.decode('utf-8')))
 
969
                self.outf.write('%-50s %s\n' % (path, entry.file_id))
907
970
            else:
908
971
                self.outf.write(path)
909
972
                self.outf.write('\n')
910
973
 
911
974
 
912
 
class cmd_cp(Command):
913
 
    __doc__ = """Copy a file.
914
 
 
915
 
    :Usage:
916
 
        brz cp OLDNAME NEWNAME
917
 
 
918
 
        brz cp SOURCE... DESTINATION
919
 
 
920
 
    If the last argument is a versioned directory, all the other names
921
 
    are copied into it.  Otherwise, there must be exactly two arguments
922
 
    and the file is copied to a new name.
923
 
 
924
 
    Files cannot be copied between branches. Only files can be copied
925
 
    at the moment.
926
 
    """
927
 
 
928
 
    takes_args = ['names*']
929
 
    takes_options = []
930
 
    aliases = ['copy']
931
 
    encoding_type = 'replace'
932
 
 
933
 
    def run(self, names_list):
934
 
        if names_list is None:
935
 
            names_list = []
936
 
        if len(names_list) < 2:
937
 
            raise errors.CommandError(gettext("missing file argument"))
938
 
        tree, rel_names = WorkingTree.open_containing_paths(
939
 
            names_list, canonicalize=False)
940
 
        for file_name in rel_names[0:-1]:
941
 
            if file_name == '':
942
 
                raise errors.CommandError(
943
 
                    gettext("can not copy root of branch"))
944
 
        self.enter_context(tree.lock_tree_write())
945
 
        into_existing = osutils.isdir(names_list[-1])
946
 
        if not into_existing:
947
 
            try:
948
 
                (src, dst) = rel_names
949
 
            except IndexError:
950
 
                raise errors.CommandError(
951
 
                    gettext('to copy multiple files the'
952
 
                            ' destination must be a versioned'
953
 
                            ' directory'))
954
 
            pairs = [(src, dst)]
955
 
        else:
956
 
            pairs = [
957
 
                (n, osutils.joinpath([rel_names[-1], osutils.basename(n)]))
958
 
                for n in rel_names[:-1]]
959
 
 
960
 
        for src, dst in pairs:
961
 
            try:
962
 
                src_kind = tree.stored_kind(src)
963
 
            except errors.NoSuchFile:
964
 
                raise errors.CommandError(
965
 
                    gettext('Could not copy %s => %s: %s is not versioned.')
966
 
                    % (src, dst, src))
967
 
            if src_kind is None:
968
 
                raise errors.CommandError(
969
 
                    gettext('Could not copy %s => %s . %s is not versioned\\.'
970
 
                            % (src, dst, src)))
971
 
            if src_kind == 'directory':
972
 
                raise errors.CommandError(
973
 
                    gettext('Could not copy %s => %s . %s is a directory.'
974
 
                            % (src, dst, src)))
975
 
            dst_parent = osutils.split(dst)[0]
976
 
            if dst_parent != '':
977
 
                try:
978
 
                    dst_parent_kind = tree.stored_kind(dst_parent)
979
 
                except errors.NoSuchFile:
980
 
                    raise errors.CommandError(
981
 
                        gettext('Could not copy %s => %s: %s is not versioned.')
982
 
                        % (src, dst, dst_parent))
983
 
                if dst_parent_kind != 'directory':
984
 
                    raise errors.CommandError(
985
 
                        gettext('Could not copy to %s: %s is not a directory.')
986
 
                        % (dst_parent, dst_parent))
987
 
 
988
 
            tree.copy_one(src, dst)
989
 
 
990
 
 
991
975
class cmd_mv(Command):
992
976
    __doc__ = """Move or rename a file.
993
977
 
994
978
    :Usage:
995
 
        brz mv OLDNAME NEWNAME
 
979
        bzr mv OLDNAME NEWNAME
996
980
 
997
 
        brz mv SOURCE... DESTINATION
 
981
        bzr mv SOURCE... DESTINATION
998
982
 
999
983
    If the last argument is a versioned directory, all the other names
1000
984
    are moved into it.  Otherwise, there must be exactly two arguments
1010
994
    """
1011
995
 
1012
996
    takes_args = ['names*']
1013
 
    takes_options = [Option("after", help="Move only the brz identifier"
1014
 
                            " of the file, because the file has already been moved."),
1015
 
                     Option('auto', help='Automatically guess renames.'),
1016
 
                     Option(
1017
 
                         'dry-run', help='Avoid making changes when guessing renames.'),
1018
 
                     ]
 
997
    takes_options = [Option("after", help="Move only the bzr identifier"
 
998
        " of the file, because the file has already been moved."),
 
999
        Option('auto', help='Automatically guess renames.'),
 
1000
        Option('dry-run', help='Avoid making changes when guessing renames.'),
 
1001
        ]
1019
1002
    aliases = ['move', 'rename']
1020
1003
    encoding_type = 'replace'
1021
1004
 
1023
1006
        if auto:
1024
1007
            return self.run_auto(names_list, after, dry_run)
1025
1008
        elif dry_run:
1026
 
            raise errors.CommandError(gettext('--dry-run requires --auto.'))
 
1009
            raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
1027
1010
        if names_list is None:
1028
1011
            names_list = []
1029
1012
        if len(names_list) < 2:
1030
 
            raise errors.CommandError(gettext("missing file argument"))
1031
 
        tree, rel_names = WorkingTree.open_containing_paths(
1032
 
            names_list, canonicalize=False)
 
1013
            raise errors.BzrCommandError(gettext("missing file argument"))
 
1014
        tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
1033
1015
        for file_name in rel_names[0:-1]:
1034
1016
            if file_name == '':
1035
 
                raise errors.CommandError(
1036
 
                    gettext("can not move root of branch"))
1037
 
        self.enter_context(tree.lock_tree_write())
 
1017
                raise errors.BzrCommandError(gettext("can not move root of branch"))
 
1018
        self.add_cleanup(tree.lock_tree_write().unlock)
1038
1019
        self._run(tree, names_list, rel_names, after)
1039
1020
 
1040
1021
    def run_auto(self, names_list, after, dry_run):
1041
1022
        if names_list is not None and len(names_list) > 1:
1042
 
            raise errors.CommandError(
1043
 
                gettext('Only one path may be specified to --auto.'))
 
1023
            raise errors.BzrCommandError(gettext('Only one path may be specified to'
 
1024
                                         ' --auto.'))
1044
1025
        if after:
1045
 
            raise errors.CommandError(
1046
 
                gettext('--after cannot be specified with --auto.'))
 
1026
            raise errors.BzrCommandError(gettext('--after cannot be specified with'
 
1027
                                         ' --auto.'))
1047
1028
        work_tree, file_list = WorkingTree.open_containing_paths(
1048
1029
            names_list, default_directory='.')
1049
 
        self.enter_context(work_tree.lock_tree_write())
1050
 
        rename_map.RenameMap.guess_renames(
1051
 
            work_tree.basis_tree(), work_tree, dry_run)
 
1030
        self.add_cleanup(work_tree.lock_tree_write().unlock)
 
1031
        rename_map.RenameMap.guess_renames(work_tree, dry_run)
1052
1032
 
1053
1033
    def _run(self, tree, names_list, rel_names, after):
1054
1034
        into_existing = osutils.isdir(names_list[-1])
1059
1039
            #    a directory, but now doesn't exist in the working tree
1060
1040
            #    and the target is an existing directory, just rename it)
1061
1041
            if (not tree.case_sensitive
1062
 
                    and rel_names[0].lower() == rel_names[1].lower()):
 
1042
                and rel_names[0].lower() == rel_names[1].lower()):
1063
1043
                into_existing = False
1064
1044
            else:
1065
1045
                # 'fix' the case of a potential 'from'
1066
 
                from_path = tree.get_canonical_path(rel_names[0])
 
1046
                from_id = tree.path2id(
 
1047
                            tree.get_canonical_inventory_path(rel_names[0]))
1067
1048
                if (not osutils.lexists(names_list[0]) and
1068
 
                    tree.is_versioned(from_path) and
1069
 
                        tree.stored_kind(from_path) == "directory"):
 
1049
                    from_id and tree.stored_kind(from_id) == "directory"):
1070
1050
                    into_existing = False
1071
1051
        # move/rename
1072
1052
        if into_existing:
1073
1053
            # move into existing directory
1074
1054
            # All entries reference existing inventory items, so fix them up
1075
1055
            # for cicp file-systems.
1076
 
            rel_names = list(tree.get_canonical_paths(rel_names))
 
1056
            rel_names = tree.get_canonical_inventory_paths(rel_names)
1077
1057
            for src, dest in tree.move(rel_names[:-1], rel_names[-1], after=after):
1078
1058
                if not is_quiet():
1079
1059
                    self.outf.write("%s => %s\n" % (src, dest))
1080
1060
        else:
1081
1061
            if len(names_list) != 2:
1082
 
                raise errors.CommandError(gettext('to mv multiple files the'
1083
 
                                                     ' destination must be a versioned'
1084
 
                                                     ' directory'))
 
1062
                raise errors.BzrCommandError(gettext('to mv multiple files the'
 
1063
                                             ' destination must be a versioned'
 
1064
                                             ' directory'))
1085
1065
 
1086
1066
            # for cicp file-systems: the src references an existing inventory
1087
1067
            # item:
1088
 
            src = tree.get_canonical_path(rel_names[0])
 
1068
            src = tree.get_canonical_inventory_path(rel_names[0])
1089
1069
            # Find the canonical version of the destination:  In all cases, the
1090
1070
            # parent of the target must be in the inventory, so we fetch the
1091
1071
            # canonical version from there (we do not always *use* the
1092
1072
            # canonicalized tail portion - we may be attempting to rename the
1093
1073
            # case of the tail)
1094
 
            canon_dest = tree.get_canonical_path(rel_names[1])
 
1074
            canon_dest = tree.get_canonical_inventory_path(rel_names[1])
1095
1075
            dest_parent = osutils.dirname(canon_dest)
1096
1076
            spec_tail = osutils.basename(rel_names[1])
1097
1077
            # For a CICP file-system, we need to avoid creating 2 inventory
1108
1088
                if after:
1109
1089
                    # If 'after' is specified, the tail must refer to a file on disk.
1110
1090
                    if dest_parent:
1111
 
                        dest_parent_fq = osutils.pathjoin(
1112
 
                            tree.basedir, dest_parent)
 
1091
                        dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
1113
1092
                    else:
1114
1093
                        # pathjoin with an empty tail adds a slash, which breaks
1115
1094
                        # relpath :(
1116
1095
                        dest_parent_fq = tree.basedir
1117
1096
 
1118
1097
                    dest_tail = osutils.canonical_relpath(
1119
 
                        dest_parent_fq,
1120
 
                        osutils.pathjoin(dest_parent_fq, spec_tail))
 
1098
                                    dest_parent_fq,
 
1099
                                    osutils.pathjoin(dest_parent_fq, spec_tail))
1121
1100
                else:
1122
1101
                    # not 'after', so case as specified is used
1123
1102
                    dest_tail = spec_tail
1135
1114
    __doc__ = """Turn this branch into a mirror of another branch.
1136
1115
 
1137
1116
    By default, this command only works on branches that have not diverged.
1138
 
    Branches are considered diverged if the destination branch's most recent
1139
 
    commit is one that has not been merged (directly or indirectly) into the
 
1117
    Branches are considered diverged if the destination branch's most recent 
 
1118
    commit is one that has not been merged (directly or indirectly) into the 
1140
1119
    parent.
1141
1120
 
1142
 
    If branches have diverged, you can use 'brz merge' to integrate the changes
 
1121
    If branches have diverged, you can use 'bzr merge' to integrate the changes
1143
1122
    from one into the other.  Once one branch has merged, the other should
1144
1123
    be able to pull it again.
1145
1124
 
1158
1137
 
1159
1138
    Note: The location can be specified either in the form of a branch,
1160
1139
    or in the form of a path to a file containing a merge directive generated
1161
 
    with brz send.
 
1140
    with bzr send.
1162
1141
    """
1163
1142
 
1164
1143
    _see_also = ['push', 'update', 'status-flags', 'send']
1165
1144
    takes_options = ['remember', 'overwrite', 'revision',
1166
 
                     custom_help('verbose',
1167
 
                                 help='Show logs of pulled revisions.'),
1168
 
                     custom_help('directory',
1169
 
                                 help='Branch to pull into, '
1170
 
                                 'rather than the one containing the working directory.'),
1171
 
                     Option('local',
1172
 
                            help="Perform a local pull in a bound "
1173
 
                            "branch.  Local pulls are not applied to "
1174
 
                            "the master branch."
1175
 
                            ),
1176
 
                     Option('show-base',
1177
 
                            help="Show base revision text in conflicts."),
1178
 
                     Option('overwrite-tags',
1179
 
                            help="Overwrite tags only."),
1180
 
                     ]
 
1145
        custom_help('verbose',
 
1146
            help='Show logs of pulled revisions.'),
 
1147
        custom_help('directory',
 
1148
            help='Branch to pull into, '
 
1149
                 'rather than the one containing the working directory.'),
 
1150
        Option('local',
 
1151
            help="Perform a local pull in a bound "
 
1152
                 "branch.  Local pulls are not applied to "
 
1153
                 "the master branch."
 
1154
            ),
 
1155
        Option('show-base',
 
1156
            help="Show base revision text in conflicts."),
 
1157
        Option('overwrite-tags',
 
1158
            help="Overwrite tags only."),
 
1159
        ]
1181
1160
    takes_args = ['location?']
1182
1161
    encoding_type = 'replace'
1183
1162
 
1200
1179
        try:
1201
1180
            tree_to = WorkingTree.open_containing(directory)[0]
1202
1181
            branch_to = tree_to.branch
1203
 
            self.enter_context(tree_to.lock_write())
 
1182
            self.add_cleanup(tree_to.lock_write().unlock)
1204
1183
        except errors.NoWorkingTree:
1205
1184
            tree_to = None
1206
1185
            branch_to = Branch.open_containing(directory)[0]
1207
 
            self.enter_context(branch_to.lock_write())
 
1186
            self.add_cleanup(branch_to.lock_write().unlock)
1208
1187
            if show_base:
1209
1188
                warning(gettext("No working tree, ignoring --show-base"))
1210
1189
 
1214
1193
        possible_transports = []
1215
1194
        if location is not None:
1216
1195
            try:
1217
 
                mergeable = _mod_mergeable.read_mergeable_from_url(
1218
 
                    location, possible_transports=possible_transports)
 
1196
                mergeable = bundle.read_mergeable_from_url(location,
 
1197
                    possible_transports=possible_transports)
1219
1198
            except errors.NotABundle:
1220
1199
                mergeable = None
1221
1200
 
1222
1201
        stored_loc = branch_to.get_parent()
1223
1202
        if location is None:
1224
1203
            if stored_loc is None:
1225
 
                raise errors.CommandError(gettext("No pull location known or"
1226
 
                                                     " specified."))
 
1204
                raise errors.BzrCommandError(gettext("No pull location known or"
 
1205
                                             " specified."))
1227
1206
            else:
1228
1207
                display_url = urlutils.unescape_for_display(stored_loc,
1229
 
                                                            self.outf.encoding)
 
1208
                        self.outf.encoding)
1230
1209
                if not is_quiet():
1231
 
                    self.outf.write(
1232
 
                        gettext("Using saved parent location: %s\n") % display_url)
 
1210
                    self.outf.write(gettext("Using saved parent location: %s\n") % display_url)
1233
1211
                location = stored_loc
1234
1212
 
1235
1213
        revision = _get_one_revision('pull', revision)
1236
1214
        if mergeable is not None:
1237
1215
            if revision is not None:
1238
 
                raise errors.CommandError(gettext(
 
1216
                raise errors.BzrCommandError(gettext(
1239
1217
                    'Cannot use -r with merge directives or bundles'))
1240
1218
            mergeable.install_revisions(branch_to.repository)
1241
1219
            base_revision_id, revision_id, verified = \
1243
1221
            branch_from = branch_to
1244
1222
        else:
1245
1223
            branch_from = Branch.open(location,
1246
 
                                      possible_transports=possible_transports)
1247
 
            self.enter_context(branch_from.lock_read())
 
1224
                possible_transports=possible_transports)
 
1225
            self.add_cleanup(branch_from.lock_read().unlock)
1248
1226
            # Remembers if asked explicitly or no previous location is set
1249
1227
            if (remember
1250
 
                    or (remember is None and branch_to.get_parent() is None)):
 
1228
                or (remember is None and branch_to.get_parent() is None)):
1251
1229
                # FIXME: This shouldn't be done before the pull
1252
1230
                # succeeds... -- vila 2012-01-02
1253
1231
                branch_to.set_parent(branch_from.base)
1291
1269
    considered diverged if the destination branch's most recent commit is one
1292
1270
    that has not been merged (directly or indirectly) by the source branch.
1293
1271
 
1294
 
    If branches have diverged, you can use 'brz push --overwrite' to replace
 
1272
    If branches have diverged, you can use 'bzr push --overwrite' to replace
1295
1273
    the other branch completely, discarding its unmerged changes.
1296
1274
 
1297
1275
    If you want to ensure you have the different changes in the other branch,
1298
 
    do a merge (see brz help merge) from the other branch, and commit that.
 
1276
    do a merge (see bzr help merge) from the other branch, and commit that.
1299
1277
    After that you will be able to do a push without '--overwrite'.
1300
1278
 
1301
1279
    If there is no default push location set, the first push will set it (use
1310
1288
 
1311
1289
    _see_also = ['pull', 'update', 'working-trees']
1312
1290
    takes_options = ['remember', 'overwrite', 'verbose', 'revision',
1313
 
                     Option('create-prefix',
1314
 
                            help='Create the path leading up to the branch '
1315
 
                            'if it does not already exist.'),
1316
 
                     custom_help('directory',
1317
 
                                 help='Branch to push from, '
1318
 
                                 'rather than the one containing the working directory.'),
1319
 
                     Option('use-existing-dir',
1320
 
                            help='By default push will fail if the target'
1321
 
                            ' directory exists, but does not already'
1322
 
                            ' have a control directory.  This flag will'
1323
 
                            ' allow push to proceed.'),
1324
 
                     Option('stacked',
1325
 
                            help='Create a stacked branch that references the public location '
1326
 
                            'of the parent branch.'),
1327
 
                     Option('stacked-on',
1328
 
                            help='Create a stacked branch that refers to another branch '
1329
 
                            'for the commit history. Only the work not present in the '
1330
 
                            'referenced branch is included in the branch created.',
1331
 
                            type=str),
1332
 
                     Option('strict',
1333
 
                            help='Refuse to push if there are uncommitted changes in'
1334
 
                            ' the working tree, --no-strict disables the check.'),
1335
 
                     Option('no-tree',
1336
 
                            help="Don't populate the working tree, even for protocols"
1337
 
                            " that support it."),
1338
 
                     Option('overwrite-tags',
1339
 
                            help="Overwrite tags only."),
1340
 
                     Option('lossy', help="Allow lossy push, i.e. dropping metadata "
1341
 
                            "that can't be represented in the target.")
1342
 
                     ]
 
1291
        Option('create-prefix',
 
1292
               help='Create the path leading up to the branch '
 
1293
                    'if it does not already exist.'),
 
1294
        custom_help('directory',
 
1295
            help='Branch to push from, '
 
1296
                 'rather than the one containing the working directory.'),
 
1297
        Option('use-existing-dir',
 
1298
               help='By default push will fail if the target'
 
1299
                    ' directory exists, but does not already'
 
1300
                    ' have a control directory.  This flag will'
 
1301
                    ' allow push to proceed.'),
 
1302
        Option('stacked',
 
1303
            help='Create a stacked branch that references the public location '
 
1304
                'of the parent branch.'),
 
1305
        Option('stacked-on',
 
1306
            help='Create a stacked branch that refers to another branch '
 
1307
                'for the commit history. Only the work not present in the '
 
1308
                'referenced branch is included in the branch created.',
 
1309
            type=unicode),
 
1310
        Option('strict',
 
1311
               help='Refuse to push if there are uncommitted changes in'
 
1312
               ' the working tree, --no-strict disables the check.'),
 
1313
        Option('no-tree',
 
1314
               help="Don't populate the working tree, even for protocols"
 
1315
               " that support it."),
 
1316
        Option('overwrite-tags',
 
1317
              help="Overwrite tags only."),
 
1318
        ]
1343
1319
    takes_args = ['location?']
1344
1320
    encoding_type = 'replace'
1345
1321
 
1346
1322
    def run(self, location=None, remember=None, overwrite=False,
1347
 
            create_prefix=False, verbose=False, revision=None,
1348
 
            use_existing_dir=False, directory=None, stacked_on=None,
1349
 
            stacked=False, strict=None, no_tree=False,
1350
 
            overwrite_tags=False, lossy=False):
1351
 
        from .location import location_to_url
1352
 
        from .push import _show_push_branch
 
1323
        create_prefix=False, verbose=False, revision=None,
 
1324
        use_existing_dir=False, directory=None, stacked_on=None,
 
1325
        stacked=False, strict=None, no_tree=False,
 
1326
        overwrite_tags=False):
 
1327
        from bzrlib.push import _show_push_branch
1353
1328
 
1354
1329
        if overwrite:
1355
1330
            overwrite = ["history", "tags"]
1376
1351
                more_warning='Uncommitted changes will not be pushed.')
1377
1352
        # Get the stacked_on branch, if any
1378
1353
        if stacked_on is not None:
1379
 
            stacked_on = location_to_url(stacked_on, 'read')
1380
1354
            stacked_on = urlutils.normalize_url(stacked_on)
1381
1355
        elif stacked:
1382
1356
            parent_url = br_from.get_parent()
1390
1364
                    # error by the feedback given to them. RBC 20080227.
1391
1365
                    stacked_on = parent_url
1392
1366
            if not stacked_on:
1393
 
                raise errors.CommandError(gettext(
 
1367
                raise errors.BzrCommandError(gettext(
1394
1368
                    "Could not determine branch to refer to."))
1395
1369
 
1396
1370
        # Get the destination location
1399
1373
            if stored_loc is None:
1400
1374
                parent_loc = br_from.get_parent()
1401
1375
                if parent_loc:
1402
 
                    raise errors.CommandError(gettext(
 
1376
                    raise errors.BzrCommandError(gettext(
1403
1377
                        "No push location known or specified. To push to the "
1404
 
                        "parent branch (at %s), use 'brz push :parent'." %
 
1378
                        "parent branch (at %s), use 'bzr push :parent'." %
1405
1379
                        urlutils.unescape_for_display(parent_loc,
1406
 
                                                      self.outf.encoding)))
 
1380
                            self.outf.encoding)))
1407
1381
                else:
1408
 
                    raise errors.CommandError(gettext(
 
1382
                    raise errors.BzrCommandError(gettext(
1409
1383
                        "No push location known or specified."))
1410
1384
            else:
1411
1385
                display_url = urlutils.unescape_for_display(stored_loc,
1412
 
                                                            self.outf.encoding)
 
1386
                        self.outf.encoding)
1413
1387
                note(gettext("Using saved push location: %s") % display_url)
1414
1388
                location = stored_loc
1415
1389
 
1416
1390
        _show_push_branch(br_from, revision_id, location, self.outf,
1417
 
                          verbose=verbose, overwrite=overwrite, remember=remember,
1418
 
                          stacked_on=stacked_on, create_prefix=create_prefix,
1419
 
                          use_existing_dir=use_existing_dir, no_tree=no_tree,
1420
 
                          lossy=lossy)
 
1391
            verbose=verbose, overwrite=overwrite, remember=remember,
 
1392
            stacked_on=stacked_on, create_prefix=create_prefix,
 
1393
            use_existing_dir=use_existing_dir, no_tree=no_tree)
1421
1394
 
1422
1395
 
1423
1396
class cmd_branch(Command):
1432
1405
 
1433
1406
    To retrieve the branch as of a particular revision, supply the --revision
1434
1407
    parameter, as in "branch foo/bar -r 5".
 
1408
 
 
1409
    The synonyms 'clone' and 'get' for this command are deprecated.
1435
1410
    """
1436
1411
 
1437
 
    aliase = ['sprout']
1438
1412
    _see_also = ['checkout']
1439
1413
    takes_args = ['from_location', 'to_location?']
1440
1414
    takes_options = ['revision',
1441
 
                     Option(
1442
 
                         'hardlink', help='Hard-link working tree files where possible.'),
1443
 
                     Option('files-from', type=str,
1444
 
                            help="Get file contents from this tree."),
1445
 
                     Option('no-tree',
1446
 
                            help="Create a branch without a working-tree."),
1447
 
                     Option('switch',
1448
 
                            help="Switch the checkout in the current directory "
1449
 
                            "to the new branch."),
1450
 
                     Option('stacked',
1451
 
                            help='Create a stacked branch referring to the source branch. '
1452
 
                            'The new branch will depend on the availability of the source '
1453
 
                            'branch for all operations.'),
1454
 
                     Option('standalone',
1455
 
                            help='Do not use a shared repository, even if available.'),
1456
 
                     Option('use-existing-dir',
1457
 
                            help='By default branch will fail if the target'
1458
 
                            ' directory exists, but does not already'
1459
 
                            ' have a control directory.  This flag will'
1460
 
                            ' allow branch to proceed.'),
1461
 
                     Option('bind',
1462
 
                            help="Bind new branch to from location."),
1463
 
                     Option('no-recurse-nested',
1464
 
                            help='Do not recursively check out nested trees.'),
1465
 
                     Option('colocated-branch', short_name='b',
1466
 
                            type=str, help='Name of colocated branch to sprout.'),
1467
 
                     ]
 
1415
        Option('hardlink', help='Hard-link working tree files where possible.'),
 
1416
        Option('files-from', type=str,
 
1417
               help="Get file contents from this tree."),
 
1418
        Option('no-tree',
 
1419
            help="Create a branch without a working-tree."),
 
1420
        Option('switch',
 
1421
            help="Switch the checkout in the current directory "
 
1422
                 "to the new branch."),
 
1423
        Option('stacked',
 
1424
            help='Create a stacked branch referring to the source branch. '
 
1425
                'The new branch will depend on the availability of the source '
 
1426
                'branch for all operations.'),
 
1427
        Option('standalone',
 
1428
               help='Do not use a shared repository, even if available.'),
 
1429
        Option('use-existing-dir',
 
1430
               help='By default branch will fail if the target'
 
1431
                    ' directory exists, but does not already'
 
1432
                    ' have a control directory.  This flag will'
 
1433
                    ' allow branch to proceed.'),
 
1434
        Option('bind',
 
1435
            help="Bind new branch to from location."),
 
1436
        ]
 
1437
    aliases = ['get', 'clone']
1468
1438
 
1469
1439
    def run(self, from_location, to_location=None, revision=None,
1470
1440
            hardlink=False, stacked=False, standalone=False, no_tree=False,
1471
1441
            use_existing_dir=False, switch=False, bind=False,
1472
 
            files_from=None, no_recurse_nested=False, colocated_branch=None):
1473
 
        from breezy import switch as _mod_switch
 
1442
            files_from=None):
 
1443
        from bzrlib import switch as _mod_switch
 
1444
        from bzrlib.tag import _merge_tags_if_possible
 
1445
        if self.invoked_as in ['get', 'clone']:
 
1446
            ui.ui_factory.show_user_warning(
 
1447
                'deprecated_command',
 
1448
                deprecated_name=self.invoked_as,
 
1449
                recommended_name='branch',
 
1450
                deprecated_in_version='2.4')
1474
1451
        accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1475
 
            from_location, name=colocated_branch)
1476
 
        if no_recurse_nested:
1477
 
            recurse = 'none'
1478
 
        else:
1479
 
            recurse = 'down'
 
1452
            from_location)
1480
1453
        if not (hardlink or files_from):
1481
1454
            # accelerator_tree is usually slower because you have to read N
1482
1455
            # files (no readahead, lots of seeks, etc), but allow the user to
1485
1458
        if files_from is not None and files_from != from_location:
1486
1459
            accelerator_tree = WorkingTree.open(files_from)
1487
1460
        revision = _get_one_revision('branch', revision)
1488
 
        self.enter_context(br_from.lock_read())
 
1461
        self.add_cleanup(br_from.lock_read().unlock)
1489
1462
        if revision is not None:
1490
1463
            revision_id = revision.as_revision_id(br_from)
1491
1464
        else:
1494
1467
            # RBC 20060209
1495
1468
            revision_id = br_from.last_revision()
1496
1469
        if to_location is None:
1497
 
            to_location = urlutils.derive_to_location(from_location)
1498
 
        to_transport = transport.get_transport(to_location, purpose='write')
 
1470
            to_location = getattr(br_from, "name", None)
 
1471
            if not to_location:
 
1472
                to_location = urlutils.derive_to_location(from_location)
 
1473
        to_transport = transport.get_transport(to_location)
1499
1474
        try:
1500
1475
            to_transport.mkdir('.')
1501
1476
        except errors.FileExists:
1504
1479
                    to_transport)
1505
1480
            except errors.NotBranchError:
1506
1481
                if not use_existing_dir:
1507
 
                    raise errors.CommandError(gettext('Target directory "%s" '
1508
 
                                                         'already exists.') % to_location)
 
1482
                    raise errors.BzrCommandError(gettext('Target directory "%s" '
 
1483
                        'already exists.') % to_location)
1509
1484
                else:
1510
1485
                    to_dir = None
1511
1486
            else:
1516
1491
                else:
1517
1492
                    raise errors.AlreadyBranchError(to_location)
1518
1493
        except errors.NoSuchFile:
1519
 
            raise errors.CommandError(gettext('Parent of "%s" does not exist.')
 
1494
            raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1520
1495
                                         % to_location)
1521
1496
        else:
1522
1497
            to_dir = None
1523
1498
        if to_dir is None:
1524
1499
            try:
1525
1500
                # preserve whatever source format we have.
1526
 
                to_dir = br_from.controldir.sprout(
1527
 
                    to_transport.base, revision_id,
1528
 
                    possible_transports=[to_transport],
1529
 
                    accelerator_tree=accelerator_tree, hardlink=hardlink,
1530
 
                    stacked=stacked, force_new_repo=standalone,
1531
 
                    create_tree_if_local=not no_tree, source_branch=br_from,
1532
 
                    recurse=recurse)
 
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)
1533
1508
                branch = to_dir.open_branch(
1534
1509
                    possible_transports=[
1535
 
                        br_from.controldir.root_transport, to_transport])
 
1510
                        br_from.bzrdir.root_transport, to_transport])
1536
1511
            except errors.NoSuchRevision:
1537
1512
                to_transport.delete_tree('.')
1538
1513
                msg = gettext("The branch {0} has no revision {1}.").format(
1539
1514
                    from_location, revision)
1540
 
                raise errors.CommandError(msg)
 
1515
                raise errors.BzrCommandError(msg)
1541
1516
        else:
1542
1517
            try:
1543
1518
                to_repo = to_dir.open_repository()
1544
1519
            except errors.NoRepositoryPresent:
1545
1520
                to_repo = to_dir.create_repository()
1546
1521
            to_repo.fetch(br_from.repository, revision_id=revision_id)
1547
 
            branch = br_from.sprout(
1548
 
                to_dir, revision_id=revision_id)
1549
 
        br_from.tags.merge_to(branch.tags)
1550
 
 
 
1522
            branch = br_from.sprout(to_dir, revision_id=revision_id)
 
1523
        _merge_tags_if_possible(br_from, branch)
1551
1524
        # If the source branch is stacked, the new branch may
1552
1525
        # be stacked whether we asked for that explicitly or not.
1553
1526
        # We therefore need a try/except here and not just 'if stacked:'
1554
1527
        try:
1555
1528
            note(gettext('Created new stacked branch referring to %s.') %
1556
 
                 branch.get_stacked_on_url())
1557
 
        except (errors.NotStacked, _mod_branch.UnstackableBranchFormat,
1558
 
                errors.UnstackableRepositoryFormat) as e:
1559
 
            revno = branch.revno()
1560
 
            if revno is not None:
1561
 
                note(ngettext('Branched %d revision.',
1562
 
                              'Branched %d revisions.',
1563
 
                              branch.revno()) % revno)
1564
 
            else:
1565
 
                note(gettext('Created new branch.'))
 
1529
                branch.get_stacked_on_url())
 
1530
        except (errors.NotStacked, errors.UnstackableBranchFormat,
 
1531
            errors.UnstackableRepositoryFormat), e:
 
1532
            note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1566
1533
        if bind:
1567
1534
            # Bind to the parent
1568
1535
            parent_branch = Branch.open(from_location)
1571
1538
        if switch:
1572
1539
            # Switch to the new branch
1573
1540
            wt, _ = WorkingTree.open_containing('.')
1574
 
            _mod_switch.switch(wt.controldir, branch)
 
1541
            _mod_switch.switch(wt.bzrdir, branch)
1575
1542
            note(gettext('Switched to branch: %s'),
1576
 
                 urlutils.unescape_for_display(branch.base, 'utf-8'))
 
1543
                urlutils.unescape_for_display(branch.base, 'utf-8'))
1577
1544
 
1578
1545
 
1579
1546
class cmd_branches(Command):
1585
1552
 
1586
1553
    takes_args = ['location?']
1587
1554
    takes_options = [
1588
 
        Option('recursive', short_name='R',
1589
 
               help='Recursively scan for branches rather than '
1590
 
               'just looking in the specified location.')]
 
1555
                  Option('recursive', short_name='R',
 
1556
                         help='Recursively scan for branches rather than '
 
1557
                              'just looking in the specified location.')]
1591
1558
 
1592
1559
    def run(self, location=".", recursive=False):
1593
1560
        if recursive:
1594
 
            t = transport.get_transport(location, purpose='read')
 
1561
            t = transport.get_transport(location)
1595
1562
            if not t.listable():
1596
 
                raise errors.CommandError(
 
1563
                raise errors.BzrCommandError(
1597
1564
                    "Can't scan this type of location.")
1598
1565
            for b in controldir.ControlDir.find_branches(t):
1599
1566
                self.outf.write("%s\n" % urlutils.unescape_for_display(
1610
1577
                if name == "":
1611
1578
                    continue
1612
1579
                active = (active_branch is not None and
1613
 
                          active_branch.user_url == branch.user_url)
 
1580
                          active_branch.base == branch.base)
1614
1581
                names[name] = active
1615
1582
            # Only mention the current branch explicitly if it's not
1616
1583
            # one of the colocated branches
1617
1584
            if not any(names.values()) and active_branch is not None:
1618
1585
                self.outf.write("* %s\n" % gettext("(default)"))
1619
 
            for name in sorted(names):
 
1586
            for name in sorted(names.keys()):
1620
1587
                active = names[name]
1621
1588
                if active:
1622
1589
                    prefix = "*"
1623
1590
                else:
1624
1591
                    prefix = " "
1625
 
                self.outf.write("%s %s\n" % (prefix, name))
 
1592
                self.outf.write("%s %s\n" % (
 
1593
                    prefix, name.encode(self.outf.encoding)))
1626
1594
 
1627
1595
 
1628
1596
class cmd_checkout(Command):
1629
1597
    __doc__ = """Create a new checkout of an existing branch.
1630
1598
 
1631
 
    If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree
1632
 
    for the branch found in '.'. This is useful if you have removed the working
1633
 
    tree or if it was never created - i.e. if you pushed the branch to its
1634
 
    current location using SFTP.
 
1599
    If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
 
1600
    the branch found in '.'. This is useful if you have removed the working tree
 
1601
    or if it was never created - i.e. if you pushed the branch to its current
 
1602
    location using SFTP.
1635
1603
 
1636
 
    If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION
1637
 
    will be used.  In other words, "checkout ../foo/bar" will attempt to create
1638
 
    ./bar.  If the BRANCH_LOCATION has no / or path separator embedded, the
1639
 
    TO_LOCATION is derived from the BRANCH_LOCATION by stripping a leading
1640
 
    scheme or drive identifier, if any. For example, "checkout lp:foo-bar" will
1641
 
    attempt to create ./foo-bar.
 
1604
    If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
 
1605
    be used.  In other words, "checkout ../foo/bar" will attempt to create ./bar.
 
1606
    If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
 
1607
    is derived from the BRANCH_LOCATION by stripping a leading scheme or drive
 
1608
    identifier, if any. For example, "checkout lp:foo-bar" will attempt to
 
1609
    create ./foo-bar.
1642
1610
 
1643
1611
    To retrieve the branch as of a particular revision, supply the --revision
1644
 
    parameter, as in "checkout foo/bar -r 5". Note that this will be
1645
 
    immediately out of date [so you cannot commit] but it may be useful (i.e.
1646
 
    to examine old code.)
 
1612
    parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
 
1613
    out of date [so you cannot commit] but it may be useful (i.e. to examine old
 
1614
    code.)
1647
1615
    """
1648
1616
 
1649
1617
    _see_also = ['checkouts', 'branch', 'working-trees', 'remove-tree']
1688
1656
        # if the source and to_location are the same,
1689
1657
        # and there is no working tree,
1690
1658
        # then reconstitute a branch
1691
 
        if osutils.abspath(to_location) == osutils.abspath(branch_location):
 
1659
        if (osutils.abspath(to_location) ==
 
1660
            osutils.abspath(branch_location)):
1692
1661
            try:
1693
 
                source.controldir.open_workingtree()
 
1662
                source.bzrdir.open_workingtree()
1694
1663
            except errors.NoWorkingTree:
1695
 
                source.controldir.create_workingtree(revision_id)
 
1664
                source.bzrdir.create_workingtree(revision_id)
1696
1665
                return
1697
1666
        source.create_checkout(to_location, revision_id, lightweight,
1698
1667
                               accelerator_tree, hardlink)
1699
1668
 
1700
1669
 
1701
 
class cmd_clone(Command):
1702
 
    __doc__ = """Clone a control directory.
1703
 
    """
1704
 
 
1705
 
    takes_args = ['from_location', 'to_location?']
1706
 
    takes_options = ['revision',
1707
 
                     Option('no-recurse-nested',
1708
 
                            help='Do not recursively check out nested trees.'),
1709
 
                     ]
1710
 
 
1711
 
    def run(self, from_location, to_location=None, revision=None, no_recurse_nested=False):
1712
 
        accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1713
 
            from_location)
1714
 
        if no_recurse_nested:
1715
 
            recurse = 'none'
1716
 
        else:
1717
 
            recurse = 'down'
1718
 
        revision = _get_one_revision('branch', revision)
1719
 
        self.enter_context(br_from.lock_read())
1720
 
        if revision is not None:
1721
 
            revision_id = revision.as_revision_id(br_from)
1722
 
        else:
1723
 
            # FIXME - wt.last_revision, fallback to branch, fall back to
1724
 
            # None or perhaps NULL_REVISION to mean copy nothing
1725
 
            # RBC 20060209
1726
 
            revision_id = br_from.last_revision()
1727
 
        if to_location is None:
1728
 
            to_location = urlutils.derive_to_location(from_location)
1729
 
        target_controldir = br_from.controldir.clone(to_location, revision_id=revision_id)
1730
 
        note(gettext('Created new control directory.'))
1731
 
 
1732
 
 
1733
1670
class cmd_renames(Command):
1734
1671
    __doc__ = """Show list of renamed files.
1735
1672
    """
1742
1679
    @display_command
1743
1680
    def run(self, dir=u'.'):
1744
1681
        tree = WorkingTree.open_containing(dir)[0]
1745
 
        self.enter_context(tree.lock_read())
 
1682
        self.add_cleanup(tree.lock_read().unlock)
1746
1683
        old_tree = tree.basis_tree()
1747
 
        self.enter_context(old_tree.lock_read())
 
1684
        self.add_cleanup(old_tree.lock_read().unlock)
1748
1685
        renames = []
1749
1686
        iterator = tree.iter_changes(old_tree, include_unchanged=True)
1750
 
        for change in iterator:
1751
 
            if change.path[0] == change.path[1]:
1752
 
                continue
1753
 
            if None in change.path:
1754
 
                continue
1755
 
            renames.append(change.path)
 
1687
        for f, paths, c, v, p, n, k, e in iterator:
 
1688
            if paths[0] == paths[1]:
 
1689
                continue
 
1690
            if None in (paths):
 
1691
                continue
 
1692
            renames.append(paths)
1756
1693
        renames.sort()
1757
1694
        for old_name, new_name in renames:
1758
1695
            self.outf.write("%s => %s\n" % (old_name, new_name))
1763
1700
 
1764
1701
    This will perform a merge of the destination revision (the tip of the
1765
1702
    branch, or the specified revision) into the working tree, and then make
1766
 
    that revision the basis revision for the working tree.
 
1703
    that revision the basis revision for the working tree.  
1767
1704
 
1768
1705
    You can use this to visit an older revision, or to update a working tree
1769
1706
    that is out of date from its branch.
1770
 
 
 
1707
    
1771
1708
    If there are any uncommitted changes in the tree, they will be carried
1772
1709
    across and remain as uncommitted changes after the update.  To discard
1773
 
    these changes, use 'brz revert'.  The uncommitted changes may conflict
 
1710
    these changes, use 'bzr revert'.  The uncommitted changes may conflict
1774
1711
    with the changes brought in by the change in basis revision.
1775
1712
 
1776
 
    If the tree's branch is bound to a master branch, brz will also update
 
1713
    If the tree's branch is bound to a master branch, bzr will also update
1777
1714
    the branch from the master.
1778
1715
 
1779
 
    You cannot update just a single file or directory, because each Breezy
 
1716
    You cannot update just a single file or directory, because each Bazaar
1780
1717
    working tree has just a single basis revision.  If you want to restore a
1781
 
    file that has been removed locally, use 'brz revert' instead of 'brz
 
1718
    file that has been removed locally, use 'bzr revert' instead of 'bzr
1782
1719
    update'.  If you want to restore a file to its state in a previous
1783
 
    revision, use 'brz revert' with a '-r' option, or use 'brz cat' to write
 
1720
    revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
1784
1721
    out the old content of that file to a new location.
1785
1722
 
1786
1723
    The 'dir' argument, if given, must be the location of the root of a
1787
 
    working tree to update.  By default, the working tree that contains the
 
1724
    working tree to update.  By default, the working tree that contains the 
1788
1725
    current working directory is used.
1789
1726
    """
1790
1727
 
1798
1735
 
1799
1736
    def run(self, dir=None, revision=None, show_base=None):
1800
1737
        if revision is not None and len(revision) != 1:
1801
 
            raise errors.CommandError(gettext(
1802
 
                "brz update --revision takes exactly one revision"))
 
1738
            raise errors.BzrCommandError(gettext(
 
1739
                "bzr update --revision takes exactly one revision"))
1803
1740
        if dir is None:
1804
1741
            tree = WorkingTree.open_containing('.')[0]
1805
1742
        else:
1806
1743
            tree, relpath = WorkingTree.open_containing(dir)
1807
1744
            if relpath:
1808
1745
                # See bug 557886.
1809
 
                raise errors.CommandError(gettext(
1810
 
                    "brz update can only update a whole tree, "
 
1746
                raise errors.BzrCommandError(gettext(
 
1747
                    "bzr update can only update a whole tree, "
1811
1748
                    "not a file or subdirectory"))
1812
1749
        branch = tree.branch
1813
1750
        possible_transports = []
1815
1752
            possible_transports=possible_transports)
1816
1753
        if master is not None:
1817
1754
            branch_location = master.base
1818
 
            self.enter_context(tree.lock_write())
 
1755
            tree.lock_write()
1819
1756
        else:
1820
1757
            branch_location = tree.branch.base
1821
 
            self.enter_context(tree.lock_tree_write())
 
1758
            tree.lock_tree_write()
 
1759
        self.add_cleanup(tree.unlock)
1822
1760
        # get rid of the final '/' and be ready for display
1823
1761
        branch_location = urlutils.unescape_for_display(
1824
1762
            branch_location.rstrip('/'),
1838
1776
        if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1839
1777
            revno = branch.revision_id_to_dotted_revno(revision_id)
1840
1778
            note(gettext("Tree is up to date at revision {0} of branch {1}"
1841
 
                         ).format('.'.join(map(str, revno)), branch_location))
 
1779
                        ).format('.'.join(map(str, revno)), branch_location))
1842
1780
            return 0
1843
1781
        view_info = _get_view_info_for_change_reporter(tree)
1844
1782
        change_reporter = delta._ChangeReporter(
1851
1789
                revision=revision_id,
1852
1790
                old_tip=old_tip,
1853
1791
                show_base=show_base)
1854
 
        except errors.NoSuchRevision as e:
1855
 
            raise errors.CommandError(gettext(
1856
 
                "branch has no revision %s\n"
1857
 
                "brz update --revision only works"
1858
 
                " for a revision in the branch history")
1859
 
                % (e.revision))
 
1792
        except errors.NoSuchRevision, e:
 
1793
            raise errors.BzrCommandError(gettext(
 
1794
                                  "branch has no revision %s\n"
 
1795
                                  "bzr update --revision only works"
 
1796
                                  " for a revision in the branch history")
 
1797
                                  % (e.revision))
1860
1798
        revno = tree.branch.revision_id_to_dotted_revno(
1861
1799
            _mod_revision.ensure_null(tree.last_revision()))
1862
1800
        note(gettext('Updated to revision {0} of branch {1}').format(
1864
1802
        parent_ids = tree.get_parent_ids()
1865
1803
        if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1866
1804
            note(gettext('Your local commits will now show as pending merges with '
1867
 
                         "'brz status', and can be committed with 'brz commit'."))
 
1805
                 "'bzr status', and can be committed with 'bzr commit'."))
1868
1806
        if conflicts != 0:
1869
1807
            return 1
1870
1808
        else:
1887
1825
 
1888
1826
      Display information on the format and related locations:
1889
1827
 
1890
 
        brz info
 
1828
        bzr info
1891
1829
 
1892
1830
      Display the above together with extended format information and
1893
1831
      basic statistics (like the number of files in the working tree and
1894
1832
      number of revisions in the branch and repository):
1895
1833
 
1896
 
        brz info -v
 
1834
        bzr info -v
1897
1835
 
1898
1836
      Display the above together with number of committers to the branch:
1899
1837
 
1900
 
        brz info -vv
 
1838
        bzr info -vv
1901
1839
    """
1902
1840
    _see_also = ['revno', 'working-trees', 'repositories']
1903
1841
    takes_args = ['location?']
1910
1848
            noise_level = get_verbosity_level()
1911
1849
        else:
1912
1850
            noise_level = 0
1913
 
        from .info import show_bzrdir_info
 
1851
        from bzrlib.info import show_bzrdir_info
1914
1852
        show_bzrdir_info(controldir.ControlDir.open_containing(location)[0],
1915
1853
                         verbose=noise_level, outfile=self.outf)
1916
1854
 
1918
1856
class cmd_remove(Command):
1919
1857
    __doc__ = """Remove files or directories.
1920
1858
 
1921
 
    This makes Breezy stop tracking changes to the specified files. Breezy will
 
1859
    This makes Bazaar stop tracking changes to the specified files. Bazaar will
1922
1860
    delete them if they can easily be recovered using revert otherwise they
1923
1861
    will be backed up (adding an extension of the form .~#~). If no options or
1924
 
    parameters are given Breezy will scan for files that are being tracked by
1925
 
    Breezy but missing in your tree and stop tracking them for you.
 
1862
    parameters are given Bazaar will scan for files that are being tracked by
 
1863
    Bazaar but missing in your tree and stop tracking them for you.
1926
1864
    """
1927
1865
    takes_args = ['file*']
1928
1866
    takes_options = ['verbose',
1929
 
                     Option(
1930
 
                         'new', help='Only remove files that have never been committed.'),
1931
 
                     RegistryOption.from_kwargs('file-deletion-strategy',
1932
 
                                                'The file deletion mode to be used.',
1933
 
                                                title='Deletion Strategy', value_switches=True, enum_switch=False,
1934
 
                                                safe='Backup changed files (default).',
1935
 
                                                keep='Delete from brz but leave the working copy.',
1936
 
                                                no_backup='Don\'t backup changed files.'),
1937
 
                     ]
 
1867
        Option('new', help='Only remove files that have never been committed.'),
 
1868
        RegistryOption.from_kwargs('file-deletion-strategy',
 
1869
            'The file deletion mode to be used.',
 
1870
            title='Deletion Strategy', value_switches=True, enum_switch=False,
 
1871
            safe='Backup changed files (default).',
 
1872
            keep='Delete from bzr but leave the working copy.',
 
1873
            no_backup='Don\'t backup changed files.'),
 
1874
        ]
1938
1875
    aliases = ['rm', 'del']
1939
1876
    encoding_type = 'replace'
1940
1877
 
1941
1878
    def run(self, file_list, verbose=False, new=False,
1942
 
            file_deletion_strategy='safe'):
 
1879
        file_deletion_strategy='safe'):
1943
1880
 
1944
1881
        tree, file_list = WorkingTree.open_containing_paths(file_list)
1945
1882
 
1946
1883
        if file_list is not None:
1947
1884
            file_list = [f for f in file_list]
1948
1885
 
1949
 
        self.enter_context(tree.lock_write())
 
1886
        self.add_cleanup(tree.lock_write().unlock)
1950
1887
        # Heuristics should probably all move into tree.remove_smart or
1951
1888
        # some such?
1952
1889
        if new:
1953
1890
            added = tree.changes_from(tree.basis_tree(),
1954
 
                                      specific_files=file_list).added
1955
 
            file_list = sorted([f.path[1] for f in added], reverse=True)
 
1891
                specific_files=file_list).added
 
1892
            file_list = sorted([f[0] for f in added], reverse=True)
1956
1893
            if len(file_list) == 0:
1957
 
                raise errors.CommandError(gettext('No matching files.'))
 
1894
                raise errors.BzrCommandError(gettext('No matching files.'))
1958
1895
        elif file_list is None:
1959
1896
            # missing files show up in iter_changes(basis) as
1960
1897
            # versioned-with-no-kind.
1961
1898
            missing = []
1962
1899
            for change in tree.iter_changes(tree.basis_tree()):
1963
1900
                # Find paths in the working tree that have no kind:
1964
 
                if change.path[1] is not None and change.kind[1] is None:
1965
 
                    missing.append(change.path[1])
 
1901
                if change[1][1] is not None and change[6][1] is None:
 
1902
                    missing.append(change[1][1])
1966
1903
            file_list = sorted(missing, reverse=True)
1967
1904
            file_deletion_strategy = 'keep'
1968
1905
        tree.remove(file_list, verbose=verbose, to_file=self.outf,
1969
 
                    keep_files=file_deletion_strategy == 'keep',
1970
 
                    force=(file_deletion_strategy == 'no-backup'))
 
1906
            keep_files=file_deletion_strategy=='keep',
 
1907
            force=(file_deletion_strategy=='no-backup'))
 
1908
 
 
1909
 
 
1910
class cmd_file_id(Command):
 
1911
    __doc__ = """Print file_id of a particular file or directory.
 
1912
 
 
1913
    The file_id is assigned when the file is first added and remains the
 
1914
    same through all revisions where the file exists, even when it is
 
1915
    moved or renamed.
 
1916
    """
 
1917
 
 
1918
    hidden = True
 
1919
    _see_also = ['inventory', 'ls']
 
1920
    takes_args = ['filename']
 
1921
 
 
1922
    @display_command
 
1923
    def run(self, filename):
 
1924
        tree, relpath = WorkingTree.open_containing(filename)
 
1925
        i = tree.path2id(relpath)
 
1926
        if i is None:
 
1927
            raise errors.NotVersionedError(filename)
 
1928
        else:
 
1929
            self.outf.write(i + '\n')
 
1930
 
 
1931
 
 
1932
class cmd_file_path(Command):
 
1933
    __doc__ = """Print path of file_ids to a file or directory.
 
1934
 
 
1935
    This prints one line for each directory down to the target,
 
1936
    starting at the branch root.
 
1937
    """
 
1938
 
 
1939
    hidden = True
 
1940
    takes_args = ['filename']
 
1941
 
 
1942
    @display_command
 
1943
    def run(self, filename):
 
1944
        tree, relpath = WorkingTree.open_containing(filename)
 
1945
        fid = tree.path2id(relpath)
 
1946
        if fid is None:
 
1947
            raise errors.NotVersionedError(filename)
 
1948
        segments = osutils.splitpath(relpath)
 
1949
        for pos in range(1, len(segments) + 1):
 
1950
            path = osutils.joinpath(segments[:pos])
 
1951
            self.outf.write("%s\n" % tree.path2id(path))
1971
1952
 
1972
1953
 
1973
1954
class cmd_reconcile(Command):
1974
 
    __doc__ = """Reconcile brz metadata in a branch.
 
1955
    __doc__ = """Reconcile bzr metadata in a branch.
1975
1956
 
1976
1957
    This can correct data mismatches that may have been caused by
1977
 
    previous ghost operations or brz upgrades. You should only
1978
 
    need to run this command if 'brz check' or a brz developer
 
1958
    previous ghost operations or bzr upgrades. You should only
 
1959
    need to run this command if 'bzr check' or a bzr developer
1979
1960
    advises you to run it.
1980
1961
 
1981
1962
    If a second branch is provided, cross-branch reconciliation is
1982
1963
    also attempted, which will check that data like the tree root
1983
 
    id which was not present in very early brz versions is represented
 
1964
    id which was not present in very early bzr versions is represented
1984
1965
    correctly in both branches.
1985
1966
 
1986
1967
    At the same time it is run it may recompress data resulting in
1999
1980
        ]
2000
1981
 
2001
1982
    def run(self, branch=".", canonicalize_chks=False):
2002
 
        from .reconcile import reconcile
 
1983
        from bzrlib.reconcile import reconcile
2003
1984
        dir = controldir.ControlDir.open(branch)
2004
1985
        reconcile(dir, canonicalize_chks=canonicalize_chks)
2005
1986
 
2015
1996
    @display_command
2016
1997
    def run(self, location="."):
2017
1998
        branch = Branch.open_containing(location)[0]
2018
 
        self.enter_context(branch.lock_read())
 
1999
        self.add_cleanup(branch.lock_read().unlock)
2019
2000
        graph = branch.repository.get_graph()
2020
2001
        history = list(graph.iter_lefthand_ancestry(branch.last_revision(),
2021
 
                                                    [_mod_revision.NULL_REVISION]))
 
2002
            [_mod_revision.NULL_REVISION]))
2022
2003
        for revid in reversed(history):
2023
2004
            self.outf.write(revid)
2024
2005
            self.outf.write('\n')
2043
2024
            b = wt.branch
2044
2025
            last_revision = wt.last_revision()
2045
2026
 
2046
 
        self.enter_context(b.repository.lock_read())
 
2027
        self.add_cleanup(b.repository.lock_read().unlock)
2047
2028
        graph = b.repository.get_graph()
2048
2029
        revisions = [revid for revid, parents in
2049
 
                     graph.iter_ancestry([last_revision])]
 
2030
            graph.iter_ancestry([last_revision])]
2050
2031
        for revision_id in reversed(revisions):
2051
2032
            if _mod_revision.is_null(revision_id):
2052
2033
                continue
2053
 
            self.outf.write(revision_id.decode('utf-8') + '\n')
 
2034
            self.outf.write(revision_id + '\n')
2054
2035
 
2055
2036
 
2056
2037
class cmd_init(Command):
2065
2046
    in the .bzr directory.
2066
2047
 
2067
2048
    If there is already a branch at the location but it has no working tree,
2068
 
    the tree can be populated with 'brz checkout'.
 
2049
    the tree can be populated with 'bzr checkout'.
2069
2050
 
2070
2051
    Recipe for importing a tree of files::
2071
2052
 
2072
2053
        cd ~/project
2073
 
        brz init
2074
 
        brz add .
2075
 
        brz status
2076
 
        brz commit -m "imported project"
 
2054
        bzr init
 
2055
        bzr add .
 
2056
        bzr status
 
2057
        bzr commit -m "imported project"
2077
2058
    """
2078
2059
 
2079
 
    _see_also = ['init-shared-repository', 'branch', 'checkout']
 
2060
    _see_also = ['init-repository', 'branch', 'checkout']
2080
2061
    takes_args = ['location?']
2081
2062
    takes_options = [
2082
2063
        Option('create-prefix',
2083
2064
               help='Create the path leading up to the branch '
2084
2065
                    'if it does not already exist.'),
2085
 
        RegistryOption('format',
2086
 
                       help='Specify a format for this branch. '
2087
 
                       'See "help formats" for a full list.',
2088
 
                       lazy_registry=('breezy.controldir', 'format_registry'),
2089
 
                       converter=lambda name: controldir.format_registry.make_controldir(
2090
 
                            name),
2091
 
                       value_switches=True,
2092
 
                       title="Branch format",
2093
 
                       ),
2094
 
        Option('append-revisions-only',
2095
 
               help='Never change revnos or the existing log.'
2096
 
               '  Append revisions to it only.'),
2097
 
        Option('no-tree',
2098
 
               'Create a branch without a working tree.')
2099
 
        ]
2100
 
 
 
2066
         RegistryOption('format',
 
2067
                help='Specify a format for this branch. '
 
2068
                'See "help formats".',
 
2069
                lazy_registry=('bzrlib.controldir', 'format_registry'),
 
2070
                converter=lambda name: controldir.format_registry.make_bzrdir(name),
 
2071
                value_switches=True,
 
2072
                title="Branch format",
 
2073
                ),
 
2074
         Option('append-revisions-only',
 
2075
                help='Never change revnos or the existing log.'
 
2076
                '  Append revisions to it only.'),
 
2077
         Option('no-tree',
 
2078
                'Create a branch without a working tree.')
 
2079
         ]
2101
2080
    def run(self, location=None, format=None, append_revisions_only=False,
2102
2081
            create_prefix=False, no_tree=False):
2103
2082
        if format is None:
2104
 
            format = controldir.format_registry.make_controldir('default')
 
2083
            format = controldir.format_registry.make_bzrdir('default')
2105
2084
        if location is None:
2106
2085
            location = u'.'
2107
2086
 
2108
 
        to_transport = transport.get_transport(location, purpose='write')
 
2087
        to_transport = transport.get_transport(location)
2109
2088
 
2110
2089
        # The path has to exist to initialize a
2111
2090
        # branch inside of it.
2116
2095
            to_transport.ensure_base()
2117
2096
        except errors.NoSuchFile:
2118
2097
            if not create_prefix:
2119
 
                raise errors.CommandError(gettext("Parent directory of %s"
2120
 
                                                     " does not exist."
2121
 
                                                     "\nYou may supply --create-prefix to create all"
2122
 
                                                     " leading parent directories.")
2123
 
                                             % location)
 
2098
                raise errors.BzrCommandError(gettext("Parent directory of %s"
 
2099
                    " does not exist."
 
2100
                    "\nYou may supply --create-prefix to create all"
 
2101
                    " leading parent directories.")
 
2102
                    % location)
2124
2103
            to_transport.create_prefix()
2125
2104
 
2126
2105
        try:
2127
 
            a_controldir = controldir.ControlDir.open_from_transport(
2128
 
                to_transport)
 
2106
            a_bzrdir = controldir.ControlDir.open_from_transport(to_transport)
2129
2107
        except errors.NotBranchError:
2130
2108
            # really a NotBzrDir error...
2131
2109
            create_branch = controldir.ControlDir.create_branch_convenience
2136
2114
            branch = create_branch(to_transport.base, format=format,
2137
2115
                                   possible_transports=[to_transport],
2138
2116
                                   force_new_tree=force_new_tree)
2139
 
            a_controldir = branch.controldir
 
2117
            a_bzrdir = branch.bzrdir
2140
2118
        else:
2141
 
            from .transport.local import LocalTransport
2142
 
            if a_controldir.has_branch():
 
2119
            from bzrlib.transport.local import LocalTransport
 
2120
            if a_bzrdir.has_branch():
2143
2121
                if (isinstance(to_transport, LocalTransport)
2144
 
                        and not a_controldir.has_workingtree()):
2145
 
                    raise errors.BranchExistsWithoutWorkingTree(location)
 
2122
                    and not a_bzrdir.has_workingtree()):
 
2123
                        raise errors.BranchExistsWithoutWorkingTree(location)
2146
2124
                raise errors.AlreadyBranchError(location)
2147
 
            branch = a_controldir.create_branch()
2148
 
            if not no_tree and not a_controldir.has_workingtree():
2149
 
                a_controldir.create_workingtree()
 
2125
            branch = a_bzrdir.create_branch()
 
2126
            if not no_tree and not a_bzrdir.has_workingtree():
 
2127
                a_bzrdir.create_workingtree()
2150
2128
        if append_revisions_only:
2151
2129
            try:
2152
2130
                branch.set_append_revisions_only(True)
2153
2131
            except errors.UpgradeRequired:
2154
 
                raise errors.CommandError(gettext('This branch format cannot be set'
2155
 
                                                     ' to append-revisions-only.  Try --default.'))
 
2132
                raise errors.BzrCommandError(gettext('This branch format cannot be set'
 
2133
                    ' to append-revisions-only.  Try --default.'))
2156
2134
        if not is_quiet():
2157
 
            from .info import describe_layout, describe_format
 
2135
            from bzrlib.info import describe_layout, describe_format
2158
2136
            try:
2159
 
                tree = a_controldir.open_workingtree(recommend_upgrade=False)
 
2137
                tree = a_bzrdir.open_workingtree(recommend_upgrade=False)
2160
2138
            except (errors.NoWorkingTree, errors.NotLocalUrl):
2161
2139
                tree = None
2162
2140
            repository = branch.repository
2163
2141
            layout = describe_layout(repository, branch, tree).lower()
2164
 
            format = describe_format(a_controldir, repository, branch, tree)
 
2142
            format = describe_format(a_bzrdir, repository, branch, tree)
2165
2143
            self.outf.write(gettext("Created a {0} (format: {1})\n").format(
2166
 
                layout, format))
 
2144
                  layout, format))
2167
2145
            if repository.is_shared():
2168
 
                # XXX: maybe this can be refactored into transport.path_or_url()
2169
 
                url = repository.controldir.root_transport.external_url()
 
2146
                #XXX: maybe this can be refactored into transport.path_or_url()
 
2147
                url = repository.bzrdir.root_transport.external_url()
2170
2148
                try:
2171
2149
                    url = urlutils.local_path_from_url(url)
2172
 
                except urlutils.InvalidURL:
 
2150
                except errors.InvalidURL:
2173
2151
                    pass
2174
2152
                self.outf.write(gettext("Using shared repository: %s\n") % url)
2175
2153
 
2176
2154
 
2177
 
class cmd_init_shared_repository(Command):
 
2155
class cmd_init_repository(Command):
2178
2156
    __doc__ = """Create a shared repository for branches to share storage space.
2179
2157
 
2180
2158
    New branches created under the repository directory will store their
2181
2159
    revisions in the repository, not in the branch directory.  For branches
2182
 
    with shared history, this reduces the amount of storage needed and
 
2160
    with shared history, this reduces the amount of storage needed and 
2183
2161
    speeds up the creation of new branches.
2184
2162
 
2185
2163
    If the --no-trees option is given then the branches in the repository
2186
 
    will not have working trees by default.  They will still exist as
2187
 
    directories on disk, but they will not have separate copies of the
 
2164
    will not have working trees by default.  They will still exist as 
 
2165
    directories on disk, but they will not have separate copies of the 
2188
2166
    files at a certain revision.  This can be useful for repositories that
2189
2167
    store branches which are interacted with through checkouts or remote
2190
2168
    branches, such as on a server.
2192
2170
    :Examples:
2193
2171
        Create a shared repository holding just branches::
2194
2172
 
2195
 
            brz init-shared-repo --no-trees repo
2196
 
            brz init repo/trunk
 
2173
            bzr init-repo --no-trees repo
 
2174
            bzr init repo/trunk
2197
2175
 
2198
2176
        Make a lightweight checkout elsewhere::
2199
2177
 
2200
 
            brz checkout --lightweight repo/trunk trunk-checkout
 
2178
            bzr checkout --lightweight repo/trunk trunk-checkout
2201
2179
            cd trunk-checkout
2202
2180
            (add files here)
2203
2181
    """
2205
2183
    _see_also = ['init', 'branch', 'checkout', 'repositories']
2206
2184
    takes_args = ["location"]
2207
2185
    takes_options = [RegistryOption('format',
2208
 
                                    help='Specify a format for this repository. See'
2209
 
                                    ' "brz help formats" for details.',
2210
 
                                    lazy_registry=(
2211
 
                                        'breezy.controldir', 'format_registry'),
2212
 
                                    converter=lambda name: controldir.format_registry.make_controldir(
2213
 
                                        name),
2214
 
                                    value_switches=True, title='Repository format'),
 
2186
                            help='Specify a format for this repository. See'
 
2187
                                 ' "bzr help formats" for details.',
 
2188
                            lazy_registry=('bzrlib.controldir', 'format_registry'),
 
2189
                            converter=lambda name: controldir.format_registry.make_bzrdir(name),
 
2190
                            value_switches=True, title='Repository format'),
2215
2191
                     Option('no-trees',
2216
 
                            help='Branches in the repository will default to'
2217
 
                            ' not having a working tree.'),
2218
 
                     ]
2219
 
    aliases = ["init-shared-repo", "init-repo"]
 
2192
                             help='Branches in the repository will default to'
 
2193
                                  ' not having a working tree.'),
 
2194
                    ]
 
2195
    aliases = ["init-repo"]
2220
2196
 
2221
2197
    def run(self, location, format=None, no_trees=False):
2222
2198
        if format is None:
2223
 
            format = controldir.format_registry.make_controldir('default')
 
2199
            format = controldir.format_registry.make_bzrdir('default')
2224
2200
 
2225
2201
        if location is None:
2226
2202
            location = '.'
2227
2203
 
2228
 
        to_transport = transport.get_transport(location, purpose='write')
2229
 
 
2230
 
        if format.fixed_components:
2231
 
            repo_format_name = None
2232
 
        else:
2233
 
            repo_format_name = format.repository_format.get_format_string()
 
2204
        to_transport = transport.get_transport(location)
2234
2205
 
2235
2206
        (repo, newdir, require_stacking, repository_policy) = (
2236
2207
            format.initialize_on_transport_ex(to_transport,
2237
 
                                              create_prefix=True, make_working_trees=not no_trees,
2238
 
                                              shared_repo=True, force_new_repo=True,
2239
 
                                              use_existing_dir=True,
2240
 
                                              repo_format_name=repo_format_name))
 
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()))
2241
2212
        if not is_quiet():
2242
 
            from .info import show_bzrdir_info
 
2213
            from bzrlib.info import show_bzrdir_info
2243
2214
            show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
2244
2215
 
2245
2216
 
2253
2224
    the first argument, if any, or the current tree if no arguments are
2254
2225
    given.
2255
2226
 
2256
 
    "brz diff -p1" is equivalent to "brz diff --prefix old/:new/", and
 
2227
    "bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
2257
2228
    produces patches suitable for "patch -p1".
2258
2229
 
2259
2230
    Note that when using the -r argument with a range of revisions, the
2260
2231
    differences are computed between the two specified revisions.  That
2261
 
    is, the command does not show the changes introduced by the first
2262
 
    revision in the range.  This differs from the interpretation of
2263
 
    revision ranges used by "brz log" which includes the first revision
 
2232
    is, the command does not show the changes introduced by the first 
 
2233
    revision in the range.  This differs from the interpretation of 
 
2234
    revision ranges used by "bzr log" which includes the first revision
2264
2235
    in the range.
2265
2236
 
2266
2237
    :Exit values:
2272
2243
    :Examples:
2273
2244
        Shows the difference in the working tree versus the last commit::
2274
2245
 
2275
 
            brz diff
 
2246
            bzr diff
2276
2247
 
2277
2248
        Difference between the working tree and revision 1::
2278
2249
 
2279
 
            brz diff -r1
 
2250
            bzr diff -r1
2280
2251
 
2281
2252
        Difference between revision 3 and revision 1::
2282
2253
 
2283
 
            brz diff -r1..3
 
2254
            bzr diff -r1..3
2284
2255
 
2285
2256
        Difference between revision 3 and revision 1 for branch xxx::
2286
2257
 
2287
 
            brz diff -r1..3 xxx
 
2258
            bzr diff -r1..3 xxx
2288
2259
 
2289
2260
        The changes introduced by revision 2 (equivalent to -r1..2)::
2290
2261
 
2291
 
            brz diff -c2
 
2262
            bzr diff -c2
2292
2263
 
2293
2264
        To see the changes introduced by revision X::
2294
 
 
2295
 
            brz diff -cX
 
2265
        
 
2266
            bzr diff -cX
2296
2267
 
2297
2268
        Note that in the case of a merge, the -c option shows the changes
2298
2269
        compared to the left hand parent. To see the changes against
2299
2270
        another parent, use::
2300
2271
 
2301
 
            brz diff -r<chosen_parent>..X
 
2272
            bzr diff -r<chosen_parent>..X
2302
2273
 
2303
2274
        The changes between the current revision and the previous revision
2304
2275
        (equivalent to -c-1 and -r-2..-1)
2305
2276
 
2306
 
            brz diff -r-2..
 
2277
            bzr diff -r-2..
2307
2278
 
2308
2279
        Show just the differences for file NEWS::
2309
2280
 
2310
 
            brz diff NEWS
 
2281
            bzr diff NEWS
2311
2282
 
2312
2283
        Show the differences in working tree xxx for file NEWS::
2313
2284
 
2314
 
            brz diff xxx/NEWS
 
2285
            bzr diff xxx/NEWS
2315
2286
 
2316
2287
        Show the differences from branch xxx to this working tree:
2317
2288
 
2318
 
            brz diff --old xxx
 
2289
            bzr diff --old xxx
2319
2290
 
2320
2291
        Show the differences between two branches for file NEWS::
2321
2292
 
2322
 
            brz diff --old xxx --new yyy NEWS
2323
 
 
2324
 
        Same as 'brz diff' but prefix paths with old/ and new/::
2325
 
 
2326
 
            brz diff --prefix old/:new/
2327
 
 
 
2293
            bzr diff --old xxx --new yyy NEWS
 
2294
 
 
2295
        Same as 'bzr diff' but prefix paths with old/ and new/::
 
2296
 
 
2297
            bzr diff --prefix old/:new/
 
2298
            
2328
2299
        Show the differences using a custom diff program with options::
2329
 
 
2330
 
            brz diff --using /usr/bin/diff --diff-options -wu
 
2300
        
 
2301
            bzr diff --using /usr/bin/diff --diff-options -wu
2331
2302
    """
2332
2303
    _see_also = ['status']
2333
2304
    takes_args = ['file*']
2339
2310
               help='Set prefixes added to old and new filenames, as '
2340
2311
                    'two values separated by a colon. (eg "old/:new/").'),
2341
2312
        Option('old',
2342
 
               help='Branch/tree to compare from.',
2343
 
               type=str,
2344
 
               ),
 
2313
            help='Branch/tree to compare from.',
 
2314
            type=unicode,
 
2315
            ),
2345
2316
        Option('new',
2346
 
               help='Branch/tree to compare to.',
2347
 
               type=str,
2348
 
               ),
 
2317
            help='Branch/tree to compare to.',
 
2318
            type=unicode,
 
2319
            ),
2349
2320
        'revision',
2350
2321
        'change',
2351
2322
        Option('using',
2352
 
               help='Use this command to compare files.',
2353
 
               type=str,
2354
 
               ),
 
2323
            help='Use this command to compare files.',
 
2324
            type=unicode,
 
2325
            ),
2355
2326
        RegistryOption('format',
2356
 
                       short_name='F',
2357
 
                       help='Diff format to use.',
2358
 
                       lazy_registry=('breezy.diff', 'format_registry'),
2359
 
                       title='Diff format'),
 
2327
            short_name='F',
 
2328
            help='Diff format to use.',
 
2329
            lazy_registry=('bzrlib.diff', 'format_registry'),
 
2330
            title='Diff format'),
2360
2331
        Option('context',
2361
 
               help='How many lines of context to show.',
2362
 
               type=int,
2363
 
               ),
2364
 
        RegistryOption.from_kwargs(
2365
 
            'color',
2366
 
            help='Color mode to use.',
2367
 
            title='Color Mode', value_switches=False, enum_switch=True,
2368
 
            never='Never colorize output.',
2369
 
            auto='Only colorize output if terminal supports it and STDOUT is a'
2370
 
            ' TTY.',
2371
 
            always='Always colorize output (default).'),
2372
 
        Option(
2373
 
            'check-style',
2374
 
            help=('Warn if trailing whitespace or spurious changes have been'
2375
 
                  '  added.'))
 
2332
            help='How many lines of context to show.',
 
2333
            type=int,
 
2334
            ),
2376
2335
        ]
2377
 
 
2378
2336
    aliases = ['di', 'dif']
2379
2337
    encoding_type = 'exact'
2380
2338
 
2381
2339
    @display_command
2382
2340
    def run(self, revision=None, file_list=None, diff_options=None,
2383
 
            prefix=None, old=None, new=None, using=None, format=None,
2384
 
            context=None, color='never'):
2385
 
        from .diff import (get_trees_and_branches_to_diff_locked,
2386
 
                           show_diff_trees)
 
2341
            prefix=None, old=None, new=None, using=None, format=None, 
 
2342
            context=None):
 
2343
        from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
 
2344
            show_diff_trees)
2387
2345
 
2388
 
        if prefix == u'0':
 
2346
        if (prefix is None) or (prefix == '0'):
2389
2347
            # diff -p0 format
2390
2348
            old_label = ''
2391
2349
            new_label = ''
2392
 
        elif prefix == u'1' or prefix is None:
 
2350
        elif prefix == '1':
2393
2351
            old_label = 'old/'
2394
2352
            new_label = 'new/'
2395
 
        elif u':' in prefix:
2396
 
            old_label, new_label = prefix.split(u":")
 
2353
        elif ':' in prefix:
 
2354
            old_label, new_label = prefix.split(":")
2397
2355
        else:
2398
 
            raise errors.CommandError(gettext(
 
2356
            raise errors.BzrCommandError(gettext(
2399
2357
                '--prefix expects two values separated by a colon'
2400
2358
                ' (eg "old/:new/")'))
2401
2359
 
2402
2360
        if revision and len(revision) > 2:
2403
 
            raise errors.CommandError(gettext('brz diff --revision takes exactly'
2404
 
                                                 ' one or two revision specifiers'))
 
2361
            raise errors.BzrCommandError(gettext('bzr diff --revision takes exactly'
 
2362
                                         ' one or two revision specifiers'))
2405
2363
 
2406
2364
        if using is not None and format is not None:
2407
 
            raise errors.CommandError(gettext(
 
2365
            raise errors.BzrCommandError(gettext(
2408
2366
                '{0} and {1} are mutually exclusive').format(
2409
2367
                '--using', '--format'))
2410
2368
 
2411
2369
        (old_tree, new_tree,
2412
2370
         old_branch, new_branch,
2413
2371
         specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
2414
 
            file_list, revision, old, new, self._exit_stack, apply_view=True)
 
2372
            file_list, revision, old, new, self.add_cleanup, apply_view=True)
2415
2373
        # GNU diff on Windows uses ANSI encoding for filenames
2416
2374
        path_encoding = osutils.get_diff_header_encoding()
2417
 
        outf = self.outf
2418
 
        if color == 'auto':
2419
 
            from .terminal import has_ansi_colors
2420
 
            if has_ansi_colors():
2421
 
                color = 'always'
2422
 
            else:
2423
 
                color = 'never'
2424
 
        if 'always' == color:
2425
 
            from .colordiff import DiffWriter
2426
 
            outf = DiffWriter(outf)
2427
 
        return show_diff_trees(old_tree, new_tree, outf,
 
2375
        return show_diff_trees(old_tree, new_tree, sys.stdout,
2428
2376
                               specific_files=specific_files,
2429
2377
                               external_diff_options=diff_options,
2430
2378
                               old_label=old_label, new_label=new_label,
2449
2397
    @display_command
2450
2398
    def run(self, show_ids=False, directory=u'.'):
2451
2399
        tree = WorkingTree.open_containing(directory)[0]
2452
 
        self.enter_context(tree.lock_read())
 
2400
        self.add_cleanup(tree.lock_read().unlock)
2453
2401
        old = tree.basis_tree()
2454
 
        self.enter_context(old.lock_read())
2455
 
        delta = tree.changes_from(old)
2456
 
        for change in delta.removed:
2457
 
            self.outf.write(change.path[0])
2458
 
            if show_ids:
2459
 
                self.outf.write(' ')
2460
 
                self.outf.write(change.file_id)
2461
 
            self.outf.write('\n')
 
2402
        self.add_cleanup(old.lock_read().unlock)
 
2403
        for path, ie in old.iter_entries_by_dir():
 
2404
            if not tree.has_id(ie.file_id):
 
2405
                self.outf.write(path)
 
2406
                if show_ids:
 
2407
                    self.outf.write(' ')
 
2408
                    self.outf.write(ie.file_id)
 
2409
                self.outf.write('\n')
2462
2410
 
2463
2411
 
2464
2412
class cmd_modified(Command):
2472
2420
    @display_command
2473
2421
    def run(self, null=False, directory=u'.'):
2474
2422
        tree = WorkingTree.open_containing(directory)[0]
2475
 
        self.enter_context(tree.lock_read())
 
2423
        self.add_cleanup(tree.lock_read().unlock)
2476
2424
        td = tree.changes_from(tree.basis_tree())
2477
2425
        self.cleanup_now()
2478
 
        for change in td.modified:
 
2426
        for path, id, kind, text_modified, meta_modified in td.modified:
2479
2427
            if null:
2480
 
                self.outf.write(change.path[1] + '\0')
 
2428
                self.outf.write(path + '\0')
2481
2429
            else:
2482
 
                self.outf.write(osutils.quotefn(change.path[1]) + '\n')
 
2430
                self.outf.write(osutils.quotefn(path) + '\n')
2483
2431
 
2484
2432
 
2485
2433
class cmd_added(Command):
2493
2441
    @display_command
2494
2442
    def run(self, null=False, directory=u'.'):
2495
2443
        wt = WorkingTree.open_containing(directory)[0]
2496
 
        self.enter_context(wt.lock_read())
 
2444
        self.add_cleanup(wt.lock_read().unlock)
2497
2445
        basis = wt.basis_tree()
2498
 
        self.enter_context(basis.lock_read())
2499
 
        for path in wt.all_versioned_paths():
2500
 
            if basis.has_filename(path):
2501
 
                continue
2502
 
            if path == u'':
2503
 
                continue
 
2446
        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)
2504
2454
            if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2505
2455
                continue
2506
2456
            if null:
2512
2462
class cmd_root(Command):
2513
2463
    __doc__ = """Show the tree root directory.
2514
2464
 
2515
 
    The root is the nearest enclosing directory with a control
 
2465
    The root is the nearest enclosing directory with a .bzr control
2516
2466
    directory."""
2517
2467
 
2518
2468
    takes_args = ['filename?']
2519
 
 
2520
2469
    @display_command
2521
2470
    def run(self, filename=None):
2522
2471
        """Print the branch root."""
2529
2478
        return int(limitstring)
2530
2479
    except ValueError:
2531
2480
        msg = gettext("The limit argument must be an integer.")
2532
 
        raise errors.CommandError(msg)
 
2481
        raise errors.BzrCommandError(msg)
2533
2482
 
2534
2483
 
2535
2484
def _parse_levels(s):
2537
2486
        return int(s)
2538
2487
    except ValueError:
2539
2488
        msg = gettext("The levels argument must be an integer.")
2540
 
        raise errors.CommandError(msg)
 
2489
        raise errors.BzrCommandError(msg)
2541
2490
 
2542
2491
 
2543
2492
class cmd_log(Command):
2544
2493
    __doc__ = """Show historical log for a branch or subset of a branch.
2545
2494
 
2546
 
    log is brz's default tool for exploring the history of a branch.
 
2495
    log is bzr's default tool for exploring the history of a branch.
2547
2496
    The branch to use is taken from the first parameter. If no parameters
2548
2497
    are given, the branch containing the working directory is logged.
2549
2498
    Here are some simple examples::
2550
2499
 
2551
 
      brz log                       log the current branch
2552
 
      brz log foo.py                log a file in its branch
2553
 
      brz log http://server/branch  log a branch on a server
 
2500
      bzr log                       log the current branch
 
2501
      bzr log foo.py                log a file in its branch
 
2502
      bzr log http://server/branch  log a branch on a server
2554
2503
 
2555
2504
    The filtering, ordering and information shown for each revision can
2556
2505
    be controlled as explained below. By default, all revisions are
2563
2512
 
2564
2513
      The log format controls how information about each revision is
2565
2514
      displayed. The standard log formats are called ``long``, ``short``
2566
 
      and ``line``. The default is long. See ``brz help log-formats``
 
2515
      and ``line``. The default is long. See ``bzr help log-formats``
2567
2516
      for more details on log formats.
2568
2517
 
2569
2518
      The following options can be used to control what information is
2600
2549
        -r..Y    display up to and including revision Y
2601
2550
        -rX..Y   display from X to Y inclusive
2602
2551
 
2603
 
      See ``brz help revisionspec`` for details on how to specify X and Y.
 
2552
      See ``bzr help revisionspec`` for details on how to specify X and Y.
2604
2553
      Some common examples are given below::
2605
2554
 
2606
2555
        -r-1                show just the tip
2636
2585
 
2637
2586
      In this case:
2638
2587
 
2639
 
      * ``brz log guide.txt`` will log the file added in revision 1
2640
 
 
2641
 
      * ``brz log tutorial.txt`` will log the new file added in revision 3
2642
 
 
2643
 
      * ``brz log -r2 -p tutorial.txt`` will show the changes made to
 
2588
      * ``bzr log guide.txt`` will log the file added in revision 1
 
2589
 
 
2590
      * ``bzr log tutorial.txt`` will log the new file added in revision 3
 
2591
 
 
2592
      * ``bzr log -r2 -p tutorial.txt`` will show the changes made to
2644
2593
        the original file in revision 2.
2645
2594
 
2646
 
      * ``brz log -r2 -p guide.txt`` will display an error message as there
 
2595
      * ``bzr log -r2 -p guide.txt`` will display an error message as there
2647
2596
        was no file called guide.txt in revision 2.
2648
2597
 
2649
2598
      Renames are always followed by log. By design, there is no need to
2662
2611
 
2663
2612
      GUI tools and IDEs are often better at exploring history than command
2664
2613
      line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2665
 
      bzr-explorer shell, or the Loggerhead web interface.  See the Bazaar
2666
 
      Plugin Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2667
 
      <http://wiki.bazaar.canonical.com/IDEIntegration>.
 
2614
      bzr-explorer shell, or the Loggerhead web interface.  See the Plugin
 
2615
      Guide <http://doc.bazaar.canonical.com/plugins/en/> and
 
2616
      <http://wiki.bazaar.canonical.com/IDEIntegration>.  
2668
2617
 
2669
 
      You may find it useful to add the aliases below to ``breezy.conf``::
 
2618
      You may find it useful to add the aliases below to ``bazaar.conf``::
2670
2619
 
2671
2620
        [ALIASES]
2672
2621
        tip = log -r-1
2673
2622
        top = log -l10 --line
2674
2623
        show = log -v -p
2675
2624
 
2676
 
      ``brz tip`` will then show the latest revision while ``brz top``
 
2625
      ``bzr tip`` will then show the latest revision while ``bzr top``
2677
2626
      will show the last 10 mainline revisions. To see the details of a
2678
 
      particular revision X,  ``brz show -rX``.
 
2627
      particular revision X,  ``bzr show -rX``.
2679
2628
 
2680
2629
      If you are interested in looking deeper into a particular merge X,
2681
 
      use ``brz log -n0 -rX``.
 
2630
      use ``bzr log -n0 -rX``.
2682
2631
 
2683
 
      ``brz log -v`` on a branch with lots of history is currently
 
2632
      ``bzr log -v`` on a branch with lots of history is currently
2684
2633
      very slow. A fix for this issue is currently under development.
2685
2634
      With or without that fix, it is recommended that a revision range
2686
2635
      be given when using the -v option.
2687
2636
 
2688
 
      brz has a generic full-text matching plugin, brz-search, that can be
 
2637
      bzr has a generic full-text matching plugin, bzr-search, that can be
2689
2638
      used to find revisions matching user names, commit messages, etc.
2690
2639
      Among other features, this plugin can find all revisions containing
2691
2640
      a list of words but not others.
2698
2647
    takes_args = ['file*']
2699
2648
    _see_also = ['log-formats', 'revisionspec']
2700
2649
    takes_options = [
2701
 
        Option('forward',
2702
 
               help='Show from oldest to newest.'),
2703
 
        'timezone',
2704
 
        custom_help('verbose',
2705
 
                    help='Show files changed in each revision.'),
2706
 
        'show-ids',
2707
 
        'revision',
2708
 
        Option('change',
2709
 
               type=breezy.option._parse_revision_str,
2710
 
               short_name='c',
2711
 
               help='Show just the specified revision.'
2712
 
               ' See also "help revisionspec".'),
2713
 
        'log-format',
2714
 
        RegistryOption('authors',
2715
 
                       'What names to list as authors - first, all or committer.',
2716
 
                       title='Authors',
2717
 
                       lazy_registry=(
2718
 
                           'breezy.log', 'author_list_registry'),
2719
 
                       ),
2720
 
        Option('levels',
2721
 
               short_name='n',
2722
 
               help='Number of levels to display - 0 for all, 1 for flat.',
2723
 
               argname='N',
2724
 
               type=_parse_levels),
2725
 
        Option('message',
2726
 
               help='Show revisions whose message matches this '
2727
 
               'regular expression.',
2728
 
               type=str,
2729
 
               hidden=True),
2730
 
        Option('limit',
2731
 
               short_name='l',
2732
 
               help='Limit the output to the first N revisions.',
2733
 
               argname='N',
2734
 
               type=_parse_limit),
2735
 
        Option('show-diff',
2736
 
               short_name='p',
2737
 
               help='Show changes made in each revision as a patch.'),
2738
 
        Option('include-merged',
2739
 
               help='Show merged revisions like --levels 0 does.'),
2740
 
        Option('include-merges', hidden=True,
2741
 
               help='Historical alias for --include-merged.'),
2742
 
        Option('omit-merges',
2743
 
               help='Do not report commits with more than one parent.'),
2744
 
        Option('exclude-common-ancestry',
2745
 
               help='Display only the revisions that are not part'
2746
 
               ' of both ancestries (require -rX..Y).'
2747
 
               ),
2748
 
        Option('signatures',
2749
 
               help='Show digital signature validity.'),
2750
 
        ListOption('match',
2751
 
                   short_name='m',
2752
 
                   help='Show revisions whose properties match this '
2753
 
                   'expression.',
2754
 
                   type=str),
2755
 
        ListOption('match-message',
2756
 
                   help='Show revisions whose message matches this '
2757
 
                   'expression.',
2758
 
                   type=str),
2759
 
        ListOption('match-committer',
 
2650
            Option('forward',
 
2651
                   help='Show from oldest to newest.'),
 
2652
            'timezone',
 
2653
            custom_help('verbose',
 
2654
                   help='Show files changed in each revision.'),
 
2655
            'show-ids',
 
2656
            'revision',
 
2657
            Option('change',
 
2658
                   type=bzrlib.option._parse_revision_str,
 
2659
                   short_name='c',
 
2660
                   help='Show just the specified revision.'
 
2661
                   ' See also "help revisionspec".'),
 
2662
            'log-format',
 
2663
            RegistryOption('authors',
 
2664
                'What names to list as authors - first, all or committer.',
 
2665
                title='Authors',
 
2666
                lazy_registry=('bzrlib.log', 'author_list_registry'),
 
2667
            ),
 
2668
            Option('levels',
 
2669
                   short_name='n',
 
2670
                   help='Number of levels to display - 0 for all, 1 for flat.',
 
2671
                   argname='N',
 
2672
                   type=_parse_levels),
 
2673
            Option('message',
 
2674
                   help='Show revisions whose message matches this '
 
2675
                        'regular expression.',
 
2676
                   type=str,
 
2677
                   hidden=True),
 
2678
            Option('limit',
 
2679
                   short_name='l',
 
2680
                   help='Limit the output to the first N revisions.',
 
2681
                   argname='N',
 
2682
                   type=_parse_limit),
 
2683
            Option('show-diff',
 
2684
                   short_name='p',
 
2685
                   help='Show changes made in each revision as a patch.'),
 
2686
            Option('include-merged',
 
2687
                   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
            Option('exclude-common-ancestry',
 
2693
                   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',
2760
2708
                   help='Show revisions whose committer matches this '
2761
2709
                   'expression.',
2762
 
                   type=str),
2763
 
        ListOption('match-author',
 
2710
                type=str),
 
2711
            ListOption('match-author',
2764
2712
                   help='Show revisions whose authors match this '
2765
2713
                   'expression.',
2766
 
                   type=str),
2767
 
        ListOption('match-bugs',
 
2714
                type=str),
 
2715
            ListOption('match-bugs',
2768
2716
                   help='Show revisions whose bugs match this '
2769
2717
                   'expression.',
2770
 
                   type=str)
2771
 
        ]
 
2718
                type=str)
 
2719
            ]
2772
2720
    encoding_type = 'replace'
2773
2721
 
2774
2722
    @display_command
2793
2741
            match_author=None,
2794
2742
            match_bugs=None,
2795
2743
            omit_merges=False,
 
2744
            include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2796
2745
            ):
2797
 
        from .log import (
 
2746
        from bzrlib.log import (
2798
2747
            Logger,
2799
2748
            make_log_request_dict,
2800
2749
            _get_info_for_log_files,
2801
2750
            )
2802
2751
        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'))
2803
2765
        if include_merged is None:
2804
2766
            include_merged = False
2805
2767
        if (exclude_common_ancestry
2806
 
                and (revision is None or len(revision) != 2)):
2807
 
            raise errors.CommandError(gettext(
 
2768
            and (revision is None or len(revision) != 2)):
 
2769
            raise errors.BzrCommandError(gettext(
2808
2770
                '--exclude-common-ancestry requires -r with two revisions'))
2809
2771
        if include_merged:
2810
2772
            if levels is None:
2811
2773
                levels = 0
2812
2774
            else:
2813
 
                raise errors.CommandError(gettext(
 
2775
                raise errors.BzrCommandError(gettext(
2814
2776
                    '{0} and {1} are mutually exclusive').format(
2815
2777
                    '--levels', '--include-merged'))
2816
2778
 
2818
2780
            if len(change) > 1:
2819
2781
                raise errors.RangeInChangeOption()
2820
2782
            if revision is not None:
2821
 
                raise errors.CommandError(gettext(
 
2783
                raise errors.BzrCommandError(gettext(
2822
2784
                    '{0} and {1} are mutually exclusive').format(
2823
2785
                    '--revision', '--change'))
2824
2786
            else:
2825
2787
                revision = change
2826
2788
 
2827
 
        files = []
 
2789
        file_ids = []
2828
2790
        filter_by_dir = False
2829
2791
        if file_list:
2830
2792
            # find the file ids to log and check for directory filtering
2831
2793
            b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2832
 
                revision, file_list, self._exit_stack)
2833
 
            for relpath, kind in file_info_list:
2834
 
                if not kind:
2835
 
                    raise errors.CommandError(gettext(
 
2794
                revision, file_list, self.add_cleanup)
 
2795
            for relpath, file_id, kind in file_info_list:
 
2796
                if file_id is None:
 
2797
                    raise errors.BzrCommandError(gettext(
2836
2798
                        "Path unknown at end or start of revision range: %s") %
2837
2799
                        relpath)
2838
2800
                # If the relpath is the top of the tree, we log everything
2839
2801
                if relpath == '':
2840
 
                    files = []
 
2802
                    file_ids = []
2841
2803
                    break
2842
2804
                else:
2843
 
                    files.append(relpath)
 
2805
                    file_ids.append(file_id)
2844
2806
                filter_by_dir = filter_by_dir or (
2845
2807
                    kind in ['directory', 'tree-reference'])
2846
2808
        else:
2853
2815
                location = '.'
2854
2816
            dir, relpath = controldir.ControlDir.open_containing(location)
2855
2817
            b = dir.open_branch()
2856
 
            self.enter_context(b.lock_read())
 
2818
            self.add_cleanup(b.lock_read().unlock)
2857
2819
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2858
2820
 
2859
2821
        if b.get_config_stack().get('validate_signatures_in_log'):
2871
2833
            delta_type = 'full'
2872
2834
        if not show_diff:
2873
2835
            diff_type = None
2874
 
        elif files:
 
2836
        elif file_ids:
2875
2837
            diff_type = 'partial'
2876
2838
        else:
2877
2839
            diff_type = 'full'
2880
2842
        if log_format is None:
2881
2843
            log_format = log.log_formatter_registry.get_default(b)
2882
2844
        # Make a non-encoding output to include the diffs - bug 328007
2883
 
        unencoded_output = ui.ui_factory.make_output_stream(
2884
 
            encoding_type='exact')
 
2845
        unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2885
2846
        lf = log_format(show_ids=show_ids, to_file=self.outf,
2886
2847
                        to_exact_file=unencoded_output,
2887
2848
                        show_timezone=timezone,
2903
2864
        # original algorithm - per-file-graph - for the "single
2904
2865
        # file that isn't a directory without showing a delta" case.
2905
2866
        partial_history = revision and b.repository._format.supports_chks
2906
 
        match_using_deltas = (len(files) != 1 or filter_by_dir
2907
 
                              or delta_type or partial_history)
 
2867
        match_using_deltas = (len(file_ids) != 1 or filter_by_dir
 
2868
            or delta_type or partial_history)
2908
2869
 
2909
2870
        match_dict = {}
2910
2871
        if match:
2919
2880
            match_dict['bugs'] = match_bugs
2920
2881
 
2921
2882
        # Build the LogRequest and execute it
2922
 
        if len(files) == 0:
2923
 
            files = None
 
2883
        if len(file_ids) == 0:
 
2884
            file_ids = None
2924
2885
        rqst = make_log_request_dict(
2925
 
            direction=direction, specific_files=files,
 
2886
            direction=direction, specific_fileids=file_ids,
2926
2887
            start_revision=rev1, end_revision=rev2, limit=limit,
2927
2888
            message_search=message, delta_type=delta_type,
2928
2889
            diff_type=diff_type, _match_using_deltas=match_using_deltas,
2950
2911
            # b is taken from revision[0].get_branch(), and
2951
2912
            # show_log will use its revision_history. Having
2952
2913
            # different branches will lead to weird behaviors.
2953
 
            raise errors.CommandError(gettext(
2954
 
                "brz %s doesn't accept two revisions in different"
 
2914
            raise errors.BzrCommandError(gettext(
 
2915
                "bzr %s doesn't accept two revisions in different"
2955
2916
                " branches.") % command_name)
2956
2917
        if start_spec.spec is None:
2957
2918
            # Avoid loading all the history.
2966
2927
        else:
2967
2928
            rev2 = end_spec.in_history(branch)
2968
2929
    else:
2969
 
        raise errors.CommandError(gettext(
2970
 
            'brz %s --revision takes one or two values.') % command_name)
 
2930
        raise errors.BzrCommandError(gettext(
 
2931
            'bzr %s --revision takes one or two values.') % command_name)
2971
2932
    return rev1, rev2
2972
2933
 
2973
2934
 
2980
2941
        rev_id2 = revision_range[1].rev_id
2981
2942
    return rev_id1, rev_id2
2982
2943
 
2983
 
 
2984
2944
def get_log_format(long=False, short=False, line=False, default='long'):
2985
2945
    log_format = default
2986
2946
    if long:
2995
2955
class cmd_touching_revisions(Command):
2996
2956
    __doc__ = """Return revision-ids which affected a particular file.
2997
2957
 
2998
 
    A more user-friendly interface is "brz log FILE".
 
2958
    A more user-friendly interface is "bzr log FILE".
2999
2959
    """
3000
2960
 
3001
2961
    hidden = True
3004
2964
    @display_command
3005
2965
    def run(self, filename):
3006
2966
        tree, relpath = WorkingTree.open_containing(filename)
3007
 
        with tree.lock_read():
3008
 
            touching_revs = log.find_touching_revisions(
3009
 
                tree.branch.repository, tree.branch.last_revision(), tree, relpath)
3010
 
            for revno, revision_id, what in reversed(list(touching_revs)):
3011
 
                self.outf.write("%6d %s\n" % (revno, what))
 
2967
        file_id = tree.path2id(relpath)
 
2968
        b = tree.branch
 
2969
        self.add_cleanup(b.lock_read().unlock)
 
2970
        touching_revs = log.find_touching_revisions(b, file_id)
 
2971
        for revno, revision_id, what in touching_revs:
 
2972
            self.outf.write("%6d %s\n" % (revno, what))
3012
2973
 
3013
2974
 
3014
2975
class cmd_ls(Command):
3018
2979
    _see_also = ['status', 'cat']
3019
2980
    takes_args = ['path?']
3020
2981
    takes_options = [
3021
 
        'verbose',
3022
 
        'revision',
3023
 
        Option('recursive', short_name='R',
3024
 
               help='Recurse into subdirectories.'),
3025
 
        Option('from-root',
3026
 
               help='Print paths relative to the root of the branch.'),
3027
 
        Option('unknown', short_name='u',
3028
 
               help='Print unknown files.'),
3029
 
        Option('versioned', help='Print versioned files.',
3030
 
               short_name='V'),
3031
 
        Option('ignored', short_name='i',
3032
 
               help='Print ignored files.'),
3033
 
        Option('kind', short_name='k',
3034
 
               help=('List entries of a particular kind: file, '
3035
 
                     'directory, symlink, tree-reference.'),
3036
 
               type=str),
3037
 
        'null',
3038
 
        'show-ids',
3039
 
        'directory',
3040
 
        ]
3041
 
 
 
2982
            'verbose',
 
2983
            'revision',
 
2984
            Option('recursive', short_name='R',
 
2985
                   help='Recurse into subdirectories.'),
 
2986
            Option('from-root',
 
2987
                   help='Print paths relative to the root of the branch.'),
 
2988
            Option('unknown', short_name='u',
 
2989
                help='Print unknown files.'),
 
2990
            Option('versioned', help='Print versioned files.',
 
2991
                   short_name='V'),
 
2992
            Option('ignored', short_name='i',
 
2993
                help='Print ignored files.'),
 
2994
            Option('kind', short_name='k',
 
2995
                   help='List entries of a particular kind: file, directory, symlink.',
 
2996
                   type=unicode),
 
2997
            'null',
 
2998
            'show-ids',
 
2999
            'directory',
 
3000
            ]
3042
3001
    @display_command
3043
3002
    def run(self, revision=None, verbose=False,
3044
3003
            recursive=False, from_root=False,
3045
3004
            unknown=False, versioned=False, ignored=False,
3046
3005
            null=False, kind=None, show_ids=False, path=None, directory=None):
3047
3006
 
3048
 
        if kind and kind not in ('file', 'directory', 'symlink', 'tree-reference'):
3049
 
            raise errors.CommandError(gettext('invalid kind specified'))
 
3007
        if kind and kind not in ('file', 'directory', 'symlink'):
 
3008
            raise errors.BzrCommandError(gettext('invalid kind specified'))
3050
3009
 
3051
3010
        if verbose and null:
3052
 
            raise errors.CommandError(
3053
 
                gettext('Cannot set both --verbose and --null'))
 
3011
            raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
3054
3012
        all = not (unknown or versioned or ignored)
3055
3013
 
3056
 
        selection = {'I': ignored, '?': unknown, 'V': versioned}
 
3014
        selection = {'I':ignored, '?':unknown, 'V':versioned}
3057
3015
 
3058
3016
        if path is None:
3059
3017
            fs_path = '.'
3060
3018
        else:
3061
3019
            if from_root:
3062
 
                raise errors.CommandError(gettext('cannot specify both --from-root'
3063
 
                                                     ' and PATH'))
 
3020
                raise errors.BzrCommandError(gettext('cannot specify both --from-root'
 
3021
                                             ' and PATH'))
3064
3022
            fs_path = path
3065
3023
        tree, branch, relpath = \
3066
3024
            _open_directory_or_containing_tree_or_branch(fs_path, directory)
3084
3042
                view_str = views.view_display_str(view_files)
3085
3043
                note(gettext("Ignoring files outside view. View is %s") % view_str)
3086
3044
 
3087
 
        self.enter_context(tree.lock_read())
3088
 
        for fp, fc, fkind, entry in tree.list_files(
3089
 
                include_root=False, from_dir=relpath, recursive=recursive):
 
3045
        self.add_cleanup(tree.lock_read().unlock)
 
3046
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
 
3047
            from_dir=relpath, recursive=recursive):
3090
3048
            # Apply additional masking
3091
3049
            if not all and not selection[fc]:
3092
3050
                continue
3099
3057
                    else:
3100
3058
                        fullpath = fp
3101
3059
                    views.check_path_in_view(tree, fullpath)
3102
 
                except views.FileOutsideView:
 
3060
                except errors.FileOutsideView:
3103
3061
                    continue
3104
3062
 
3105
3063
            # Output the entry
3110
3068
            ui.ui_factory.clear_term()
3111
3069
            if verbose:
3112
3070
                outstring = '%-8s %s' % (fc, outstring)
3113
 
                if show_ids and getattr(entry, 'file_id', None) is not None:
3114
 
                    outstring = "%-50s %s" % (outstring, entry.file_id.decode('utf-8'))
 
3071
                if show_ids and fid is not None:
 
3072
                    outstring = "%-50s %s" % (outstring, fid)
3115
3073
                self.outf.write(outstring + '\n')
3116
3074
            elif null:
3117
3075
                self.outf.write(fp + '\0')
3118
3076
                if show_ids:
3119
 
                    if getattr(entry, 'file_id', None) is not None:
3120
 
                        self.outf.write(entry.file_id.decode('utf-8'))
 
3077
                    if fid is not None:
 
3078
                        self.outf.write(fid)
3121
3079
                    self.outf.write('\0')
3122
3080
                self.outf.flush()
3123
3081
            else:
3124
3082
                if show_ids:
3125
 
                    if getattr(entry, 'file_id', None) is not None:
3126
 
                        my_id = entry.file_id.decode('utf-8')
 
3083
                    if fid is not None:
 
3084
                        my_id = fid
3127
3085
                    else:
3128
3086
                        my_id = ''
3129
3087
                    self.outf.write('%-50s %s\n' % (outstring, my_id))
3148
3106
class cmd_ignore(Command):
3149
3107
    __doc__ = """Ignore specified files or patterns.
3150
3108
 
3151
 
    See ``brz help patterns`` for details on the syntax of patterns.
 
3109
    See ``bzr help patterns`` for details on the syntax of patterns.
3152
3110
 
3153
3111
    If a .bzrignore file does not exist, the ignore command
3154
3112
    will create one and add the specified files or patterns to the newly
3155
 
    created file. The ignore command will also automatically add the
 
3113
    created file. The ignore command will also automatically add the 
3156
3114
    .bzrignore file to be versioned. Creating a .bzrignore file without
3157
3115
    the use of the ignore command will require an explicit add command.
3158
3116
 
3160
3118
    After adding, editing or deleting that file either indirectly by
3161
3119
    using this command or directly by using an editor, be sure to commit
3162
3120
    it.
3163
 
 
3164
 
    Breezy also supports a global ignore file ~/.config/breezy/ignore. On
3165
 
    Windows the global ignore file can be found in the application data
3166
 
    directory as
3167
 
    C:\\Documents and Settings\\<user>\\Application Data\\Breezy\\3.0\\ignore.
 
3121
    
 
3122
    Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
 
3123
    the global ignore file can be found in the application data directory as
 
3124
    C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
3168
3125
    Global ignores are not touched by this command. The global ignore file
3169
3126
    can be edited directly using an editor.
3170
3127
 
3171
3128
    Patterns prefixed with '!' are exceptions to ignore patterns and take
3172
3129
    precedence over regular ignores.  Such exceptions are used to specify
3173
3130
    files that should be versioned which would otherwise be ignored.
3174
 
 
 
3131
    
3175
3132
    Patterns prefixed with '!!' act as regular ignore patterns, but have
3176
3133
    precedence over the '!' exception patterns.
3177
3134
 
3178
 
    :Notes:
3179
 
 
 
3135
    :Notes: 
 
3136
        
3180
3137
    * Ignore patterns containing shell wildcards must be quoted from
3181
3138
      the shell on Unix.
3182
3139
 
3186
3143
    :Examples:
3187
3144
        Ignore the top level Makefile::
3188
3145
 
3189
 
            brz ignore ./Makefile
 
3146
            bzr ignore ./Makefile
3190
3147
 
3191
3148
        Ignore .class files in all directories...::
3192
3149
 
3193
 
            brz ignore "*.class"
 
3150
            bzr ignore "*.class"
3194
3151
 
3195
3152
        ...but do not ignore "special.class"::
3196
3153
 
3197
 
            brz ignore "!special.class"
 
3154
            bzr ignore "!special.class"
3198
3155
 
3199
3156
        Ignore files whose name begins with the "#" character::
3200
3157
 
3201
 
            brz ignore "RE:^#"
3202
 
 
3203
 
        Ignore .o files under the lib directory::
3204
 
 
3205
 
            brz ignore "lib/**/*.o"
3206
 
 
3207
 
        Ignore .o files under the lib directory::
3208
 
 
3209
 
            brz ignore "RE:lib/.*\\.o"
 
3158
            bzr ignore "RE:^#"
 
3159
 
 
3160
        Ignore .o files under the lib directory::
 
3161
 
 
3162
            bzr ignore "lib/**/*.o"
 
3163
 
 
3164
        Ignore .o files under the lib directory::
 
3165
 
 
3166
            bzr ignore "RE:lib/.*\.o"
3210
3167
 
3211
3168
        Ignore everything but the "debian" toplevel directory::
3212
3169
 
3213
 
            brz ignore "RE:(?!debian/).*"
3214
 
 
 
3170
            bzr ignore "RE:(?!debian/).*"
 
3171
        
3215
3172
        Ignore everything except the "local" toplevel directory,
3216
3173
        but always ignore autosave files ending in ~, even under local/::
3217
 
 
3218
 
            brz ignore "*"
3219
 
            brz ignore "!./local"
3220
 
            brz ignore "!!*~"
 
3174
        
 
3175
            bzr ignore "*"
 
3176
            bzr ignore "!./local"
 
3177
            bzr ignore "!!*~"
3221
3178
    """
3222
3179
 
3223
3180
    _see_also = ['status', 'ignored', 'patterns']
3224
3181
    takes_args = ['name_pattern*']
3225
3182
    takes_options = ['directory',
3226
 
                     Option('default-rules',
3227
 
                            help='Display the default ignore rules that brz uses.')
3228
 
                     ]
 
3183
        Option('default-rules',
 
3184
               help='Display the default ignore rules that bzr uses.')
 
3185
        ]
3229
3186
 
3230
3187
    def run(self, name_pattern_list=None, default_rules=None,
3231
3188
            directory=u'.'):
3232
 
        from breezy import ignores
 
3189
        from bzrlib import ignores
3233
3190
        if default_rules is not None:
3234
3191
            # dump the default rules and exit
3235
3192
            for pattern in ignores.USER_DEFAULTS:
3236
3193
                self.outf.write("%s\n" % pattern)
3237
3194
            return
3238
3195
        if not name_pattern_list:
3239
 
            raise errors.CommandError(gettext("ignore requires at least one "
3240
 
                                                 "NAME_PATTERN or --default-rules."))
 
3196
            raise errors.BzrCommandError(gettext("ignore requires at least one "
 
3197
                "NAME_PATTERN or --default-rules."))
3241
3198
        name_pattern_list = [globbing.normalize_pattern(p)
3242
3199
                             for p in name_pattern_list]
3243
3200
        bad_patterns = ''
3247
3204
                bad_patterns_count += 1
3248
3205
                bad_patterns += ('\n  %s' % p)
3249
3206
        if bad_patterns:
3250
 
            msg = (ngettext('Invalid ignore pattern found. %s',
 
3207
            msg = (ngettext('Invalid ignore pattern found. %s', 
3251
3208
                            'Invalid ignore patterns found. %s',
3252
3209
                            bad_patterns_count) % bad_patterns)
3253
3210
            ui.ui_factory.show_error(msg)
3254
 
            raise lazy_regex.InvalidPattern('')
 
3211
            raise errors.InvalidPattern('')
3255
3212
        for name_pattern in name_pattern_list:
3256
3213
            if (name_pattern[0] == '/' or
3257
 
                    (len(name_pattern) > 1 and name_pattern[1] == ':')):
3258
 
                raise errors.CommandError(gettext(
 
3214
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
 
3215
                raise errors.BzrCommandError(gettext(
3259
3216
                    "NAME_PATTERN should not be an absolute path"))
3260
3217
        tree, relpath = WorkingTree.open_containing(directory)
3261
3218
        ignores.tree_ignores_add_patterns(tree, name_pattern_list)
3262
3219
        ignored = globbing.Globster(name_pattern_list)
3263
3220
        matches = []
3264
 
        self.enter_context(tree.lock_read())
3265
 
        for filename, fc, fkind, entry in tree.list_files():
3266
 
            id = getattr(entry, 'file_id', None)
 
3221
        self.add_cleanup(tree.lock_read().unlock)
 
3222
        for entry in tree.list_files():
 
3223
            id = entry[3]
3267
3224
            if id is not None:
 
3225
                filename = entry[0]
3268
3226
                if ignored.match(filename):
3269
3227
                    matches.append(filename)
3270
3228
        if len(matches) > 0:
3271
3229
            self.outf.write(gettext("Warning: the following files are version "
3272
 
                                    "controlled and match your ignore pattern:\n%s"
3273
 
                                    "\nThese files will continue to be version controlled"
3274
 
                                    " unless you 'brz remove' them.\n") % ("\n".join(matches),))
 
3230
                  "controlled and match your ignore pattern:\n%s"
 
3231
                  "\nThese files will continue to be version controlled"
 
3232
                  " unless you 'bzr remove' them.\n") % ("\n".join(matches),))
3275
3233
 
3276
3234
 
3277
3235
class cmd_ignored(Command):
3282
3240
 
3283
3241
    Alternatively, to list just the files::
3284
3242
 
3285
 
        brz ls --ignored
 
3243
        bzr ls --ignored
3286
3244
    """
3287
3245
 
3288
3246
    encoding_type = 'replace'
3292
3250
    @display_command
3293
3251
    def run(self, directory=u'.'):
3294
3252
        tree = WorkingTree.open_containing(directory)[0]
3295
 
        self.enter_context(tree.lock_read())
3296
 
        for path, file_class, kind, entry in tree.list_files():
 
3253
        self.add_cleanup(tree.lock_read().unlock)
 
3254
        for path, file_class, kind, file_id, entry in tree.list_files():
3297
3255
            if file_class != 'I':
3298
3256
                continue
3299
 
            # XXX: Slightly inefficient since this was already calculated
 
3257
            ## XXX: Slightly inefficient since this was already calculated
3300
3258
            pat = tree.is_ignored(path)
3301
3259
            self.outf.write('%-50s %s\n' % (path, pat))
3302
3260
 
3305
3263
    __doc__ = """Lookup the revision-id from a revision-number
3306
3264
 
3307
3265
    :Examples:
3308
 
        brz lookup-revision 33
 
3266
        bzr lookup-revision 33
3309
3267
    """
3310
3268
    hidden = True
3311
3269
    takes_args = ['revno']
3316
3274
        try:
3317
3275
            revno = int(revno)
3318
3276
        except ValueError:
3319
 
            raise errors.CommandError(gettext("not a valid revision-number: %r")
 
3277
            raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
3320
3278
                                         % revno)
3321
 
        revid = WorkingTree.open_containing(
3322
 
            directory)[0].branch.get_rev_id(revno)
3323
 
        self.outf.write("%s\n" % revid.decode('utf-8'))
 
3279
        revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
 
3280
        self.outf.write("%s\n" % revid)
3324
3281
 
3325
3282
 
3326
3283
class cmd_export(Command):
3352
3309
      =================       =========================
3353
3310
    """
3354
3311
    encoding = 'exact'
3355
 
    encoding_type = 'exact'
3356
3312
    takes_args = ['dest', 'branch_or_subdir?']
3357
3313
    takes_options = ['directory',
3358
 
                     Option('format',
3359
 
                            help="Type of file to export to.",
3360
 
                            type=str),
3361
 
                     'revision',
3362
 
                     Option('filters', help='Apply content filters to export the '
3363
 
                            'convenient form.'),
3364
 
                     Option('root',
3365
 
                            type=str,
3366
 
                            help="Name of the root directory inside the exported file."),
3367
 
                     Option('per-file-timestamps',
3368
 
                            help='Set modification time of files to that of the last '
3369
 
                            'revision in which it was changed.'),
3370
 
                     Option('uncommitted',
3371
 
                            help='Export the working tree contents rather than that of the '
3372
 
                            'last revision.'),
3373
 
                     ]
3374
 
 
 
3314
        Option('format',
 
3315
               help="Type of file to export to.",
 
3316
               type=unicode),
 
3317
        'revision',
 
3318
        Option('filters', help='Apply content filters to export the '
 
3319
                'convenient form.'),
 
3320
        Option('root',
 
3321
               type=str,
 
3322
               help="Name of the root directory inside the exported file."),
 
3323
        Option('per-file-timestamps',
 
3324
               help='Set modification time of files to that of the last '
 
3325
                    '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
        ]
3375
3330
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3376
 
            root=None, filters=False, per_file_timestamps=False, uncommitted=False,
3377
 
            directory=u'.'):
3378
 
        from .export import export, guess_format, get_root_name
 
3331
        root=None, filters=False, per_file_timestamps=False, uncommitted=False,
 
3332
        directory=u'.'):
 
3333
        from bzrlib.export import export
3379
3334
 
3380
3335
        if branch_or_subdir is None:
3381
3336
            branch_or_subdir = directory
3383
3338
        (tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3384
3339
            branch_or_subdir)
3385
3340
        if tree is not None:
3386
 
            self.enter_context(tree.lock_read())
 
3341
            self.add_cleanup(tree.lock_read().unlock)
3387
3342
 
3388
3343
        if uncommitted:
3389
3344
            if tree is None:
3390
 
                raise errors.CommandError(
 
3345
                raise errors.BzrCommandError(
3391
3346
                    gettext("--uncommitted requires a working tree"))
3392
3347
            export_tree = tree
3393
3348
        else:
3394
 
            export_tree = _get_one_revision_tree(
3395
 
                'export', revision, branch=b,
3396
 
                tree=tree)
3397
 
 
3398
 
        if format is None:
3399
 
            format = guess_format(dest)
3400
 
 
3401
 
        if root is None:
3402
 
            root = get_root_name(dest)
3403
 
 
3404
 
        if not per_file_timestamps:
3405
 
            force_mtime = time.time()
3406
 
        else:
3407
 
            force_mtime = None
3408
 
 
3409
 
        if filters:
3410
 
            from breezy.filter_tree import ContentFilterTree
3411
 
            export_tree = ContentFilterTree(
3412
 
                export_tree, export_tree._content_filter_stack)
3413
 
 
 
3349
            export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3414
3350
        try:
3415
 
            export(export_tree, dest, format, root, subdir,
 
3351
            export(export_tree, dest, format, root, subdir, filtered=filters,
3416
3352
                   per_file_timestamps=per_file_timestamps)
3417
 
        except errors.NoSuchExportFormat as e:
3418
 
            raise errors.CommandError(
 
3353
        except errors.NoSuchExportFormat, e:
 
3354
            raise errors.BzrCommandError(
3419
3355
                gettext('Unsupported export format: %s') % e.format)
3420
3356
 
3421
3357
 
3430
3366
 
3431
3367
    _see_also = ['ls']
3432
3368
    takes_options = ['directory',
3433
 
                     Option('name-from-revision',
3434
 
                            help='The path name in the old tree.'),
3435
 
                     Option('filters', help='Apply content filters to display the '
3436
 
                            'convenience form.'),
3437
 
                     'revision',
3438
 
                     ]
 
3369
        Option('name-from-revision', help='The path name in the old tree.'),
 
3370
        Option('filters', help='Apply content filters to display the '
 
3371
                'convenience form.'),
 
3372
        'revision',
 
3373
        ]
3439
3374
    takes_args = ['filename']
3440
3375
    encoding_type = 'exact'
3441
3376
 
3443
3378
    def run(self, filename, revision=None, name_from_revision=False,
3444
3379
            filters=False, directory=None):
3445
3380
        if revision is not None and len(revision) != 1:
3446
 
            raise errors.CommandError(gettext("brz cat --revision takes exactly"
3447
 
                                                 " one revision specifier"))
 
3381
            raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
 
3382
                                         " one revision specifier"))
3448
3383
        tree, branch, relpath = \
3449
3384
            _open_directory_or_containing_tree_or_branch(filename, directory)
3450
 
        self.enter_context(branch.lock_read())
 
3385
        self.add_cleanup(branch.lock_read().unlock)
3451
3386
        return self._run(tree, branch, relpath, filename, revision,
3452
3387
                         name_from_revision, filters)
3453
3388
 
3454
3389
    def _run(self, tree, b, relpath, filename, revision, name_from_revision,
3455
 
             filtered):
3456
 
        import shutil
 
3390
        filtered):
3457
3391
        if tree is None:
3458
3392
            tree = b.basis_tree()
3459
3393
        rev_tree = _get_one_revision_tree('cat', revision, branch=b)
3460
 
        self.enter_context(rev_tree.lock_read())
3461
 
 
 
3394
        self.add_cleanup(rev_tree.lock_read().unlock)
 
3395
 
 
3396
        old_file_id = rev_tree.path2id(relpath)
 
3397
 
 
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.
3462
3402
        if name_from_revision:
3463
3403
            # Try in revision if requested
3464
 
            if not rev_tree.is_versioned(relpath):
3465
 
                raise errors.CommandError(gettext(
 
3404
            if old_file_id is None:
 
3405
                raise errors.BzrCommandError(gettext(
3466
3406
                    "{0!r} is not present in revision {1}").format(
3467
3407
                        filename, rev_tree.get_revision_id()))
3468
 
            rev_tree_path = relpath
 
3408
            else:
 
3409
                actual_file_id = old_file_id
3469
3410
        else:
3470
 
            try:
3471
 
                rev_tree_path = _mod_tree.find_previous_path(
3472
 
                    tree, rev_tree, relpath)
3473
 
            except errors.NoSuchFile:
3474
 
                rev_tree_path = None
3475
 
 
3476
 
            if rev_tree_path is None:
3477
 
                # Path didn't exist in working tree
3478
 
                if not rev_tree.is_versioned(relpath):
3479
 
                    raise errors.CommandError(gettext(
3480
 
                        "{0!r} is not present in revision {1}").format(
3481
 
                            filename, rev_tree.get_revision_id()))
3482
 
                else:
3483
 
                    # Fall back to the same path in the basis tree, if present.
3484
 
                    rev_tree_path = relpath
3485
 
 
 
3411
            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(
 
3419
                        filename, rev_tree.get_revision_id()))
3486
3420
        if filtered:
3487
 
            from .filter_tree import ContentFilterTree
3488
 
            filter_tree = ContentFilterTree(
3489
 
                rev_tree, rev_tree._content_filter_stack)
3490
 
            fileobj = filter_tree.get_file(rev_tree_path)
 
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)
3491
3425
        else:
3492
 
            fileobj = rev_tree.get_file(rev_tree_path)
3493
 
        shutil.copyfileobj(fileobj, self.outf)
 
3426
            content = rev_tree.get_file_text(actual_file_id)
3494
3427
        self.cleanup_now()
 
3428
        self.outf.write(content)
3495
3429
 
3496
3430
 
3497
3431
class cmd_local_time_offset(Command):
3498
3432
    __doc__ = """Show the offset in seconds from GMT to local time."""
3499
3433
    hidden = True
3500
 
 
3501
3434
    @display_command
3502
3435
    def run(self):
3503
3436
        self.outf.write("%s\n" % osutils.local_time_offset())
3504
3437
 
3505
3438
 
 
3439
 
3506
3440
class cmd_commit(Command):
3507
3441
    __doc__ = """Commit changes into a new revision.
3508
3442
 
3522
3456
      If selected files are specified, only changes to those files are
3523
3457
      committed.  If a directory is specified then the directory and
3524
3458
      everything within it is committed.
3525
 
 
 
3459
  
3526
3460
      When excludes are given, they take precedence over selected files.
3527
3461
      For example, to commit only changes within foo, but not changes
3528
3462
      within foo/bar::
3529
 
 
3530
 
        brz commit foo -x foo/bar
3531
 
 
 
3463
  
 
3464
        bzr commit foo -x foo/bar
 
3465
  
3532
3466
      A selective commit after a merge is not yet supported.
3533
3467
 
3534
3468
    :Custom authors:
3539
3473
      "John Doe <jdoe@example.com>". If there is more than one author of
3540
3474
      the change you can specify the option multiple times, once for each
3541
3475
      author.
3542
 
 
 
3476
  
3543
3477
    :Checks:
3544
3478
 
3545
3479
      A common mistake is to forget to add a new file or directory before
3546
3480
      running the commit command. The --strict option checks for unknown
3547
3481
      files and aborts the commit if any are found. More advanced pre-commit
3548
 
      checks can be implemented by defining hooks. See ``brz help hooks``
 
3482
      checks can be implemented by defining hooks. See ``bzr help hooks``
3549
3483
      for details.
3550
3484
 
3551
3485
    :Things to note:
3552
3486
 
3553
 
      If you accidentally commit the wrong changes or make a spelling
 
3487
      If you accidentially commit the wrong changes or make a spelling
3554
3488
      mistake in the commit message say, you can use the uncommit command
3555
 
      to undo it. See ``brz help uncommit`` for details.
 
3489
      to undo it. See ``bzr help uncommit`` for details.
3556
3490
 
3557
3491
      Hooks can also be configured to run after a commit. This allows you
3558
3492
      to trigger updates to external systems like bug trackers. The --fixes
3559
3493
      option can be used to record the association between a revision and
3560
 
      one or more bugs. See ``brz help bugs`` for details.
 
3494
      one or more bugs. See ``bzr help bugs`` for details.
3561
3495
    """
3562
3496
 
3563
3497
    _see_also = ['add', 'bugs', 'hooks', 'uncommit']
3564
3498
    takes_args = ['selected*']
3565
3499
    takes_options = [
3566
 
        ListOption(
3567
 
            'exclude', type=str, short_name='x',
3568
 
            help="Do not consider changes made to a given path."),
3569
 
        Option('message', type=str,
3570
 
               short_name='m',
3571
 
               help="Description of the new revision."),
3572
 
        'verbose',
3573
 
        Option('unchanged',
3574
 
               help='Commit even if nothing has changed.'),
3575
 
        Option('file', type=str,
3576
 
               short_name='F',
3577
 
               argname='msgfile',
3578
 
               help='Take commit message from this file.'),
3579
 
        Option('strict',
3580
 
               help="Refuse to commit if there are unknown "
3581
 
               "files in the working tree."),
3582
 
        Option('commit-time', type=str,
3583
 
               help="Manually set a commit time using commit date "
3584
 
               "format, e.g. '2009-10-10 08:00:00 +0100'."),
3585
 
        ListOption(
3586
 
            'bugs', type=str,
3587
 
            help="Link to a related bug. (see \"brz help bugs\")."),
3588
 
        ListOption(
3589
 
            'fixes', type=str,
3590
 
            help="Mark a bug as being fixed by this revision "
3591
 
                 "(see \"brz help bugs\")."),
3592
 
        ListOption(
3593
 
            'author', type=str,
3594
 
            help="Set the author's name, if it's different "
3595
 
                 "from the committer."),
3596
 
        Option('local',
3597
 
               help="Perform a local commit in a bound "
3598
 
                    "branch.  Local commits are not pushed to "
3599
 
                    "the master branch until a normal commit "
3600
 
                    "is performed."
3601
 
               ),
3602
 
        Option('show-diff', short_name='p',
3603
 
               help='When no message is supplied, show the diff along'
3604
 
               ' with the status summary in the message editor.'),
3605
 
        Option('lossy',
3606
 
               help='When committing to a foreign version control '
3607
 
               'system do not push data that can not be natively '
3608
 
               'represented.'), ]
 
3500
            ListOption('exclude', type=str, short_name='x',
 
3501
                help="Do not consider changes made to a given path."),
 
3502
            Option('message', type=unicode,
 
3503
                   short_name='m',
 
3504
                   help="Description of the new revision."),
 
3505
            'verbose',
 
3506
             Option('unchanged',
 
3507
                    help='Commit even if nothing has changed.'),
 
3508
             Option('file', type=str,
 
3509
                    short_name='F',
 
3510
                    argname='msgfile',
 
3511
                    help='Take commit message from this file.'),
 
3512
             Option('strict',
 
3513
                    help="Refuse to commit if there are unknown "
 
3514
                    "files in the working tree."),
 
3515
             Option('commit-time', type=str,
 
3516
                    help="Manually set a commit time using commit date "
 
3517
                    "format, e.g. '2009-10-10 08:00:00 +0100'."),
 
3518
             ListOption('fixes', type=str,
 
3519
                    help="Mark a bug as being fixed by this revision "
 
3520
                         "(see \"bzr help bugs\")."),
 
3521
             ListOption('author', type=unicode,
 
3522
                    help="Set the author's name, if it's different "
 
3523
                         "from the committer."),
 
3524
             Option('local',
 
3525
                    help="Perform a local commit in a bound "
 
3526
                         "branch.  Local commits are not pushed to "
 
3527
                         "the master branch until a normal commit "
 
3528
                         "is performed."
 
3529
                    ),
 
3530
             Option('show-diff', short_name='p',
 
3531
                    help='When no message is supplied, show the diff along'
 
3532
                    ' with the status summary in the message editor.'),
 
3533
             Option('lossy', 
 
3534
                    help='When committing to a foreign version control '
 
3535
                    'system do not push data that can not be natively '
 
3536
                    'represented.'),
 
3537
             ]
3609
3538
    aliases = ['ci', 'checkin']
3610
3539
 
3611
 
    def _iter_bug_urls(self, bugs, branch, status):
3612
 
        default_bugtracker = None
 
3540
    def _iter_bug_fix_urls(self, fixes, branch):
 
3541
        default_bugtracker  = None
3613
3542
        # Configure the properties for bug fixing attributes.
3614
 
        for bug in bugs:
3615
 
            tokens = bug.split(':')
 
3543
        for fixed_bug in fixes:
 
3544
            tokens = fixed_bug.split(':')
3616
3545
            if len(tokens) == 1:
3617
3546
                if default_bugtracker is None:
3618
3547
                    branch_config = branch.get_config_stack()
3619
3548
                    default_bugtracker = branch_config.get(
3620
3549
                        "bugtracker")
3621
3550
                if default_bugtracker is None:
3622
 
                    raise errors.CommandError(gettext(
 
3551
                    raise errors.BzrCommandError(gettext(
3623
3552
                        "No tracker specified for bug %s. Use the form "
3624
3553
                        "'tracker:id' or specify a default bug tracker "
3625
3554
                        "using the `bugtracker` option.\nSee "
3626
 
                        "\"brz help bugs\" for more information on this "
3627
 
                        "feature. Commit refused.") % bug)
 
3555
                        "\"bzr help bugs\" for more information on this "
 
3556
                        "feature. Commit refused.") % fixed_bug)
3628
3557
                tag = default_bugtracker
3629
3558
                bug_id = tokens[0]
3630
3559
            elif len(tokens) != 2:
3631
 
                raise errors.CommandError(gettext(
 
3560
                raise errors.BzrCommandError(gettext(
3632
3561
                    "Invalid bug %s. Must be in the form of 'tracker:id'. "
3633
 
                    "See \"brz help bugs\" for more information on this "
3634
 
                    "feature.\nCommit refused.") % bug)
 
3562
                    "See \"bzr help bugs\" for more information on this "
 
3563
                    "feature.\nCommit refused.") % fixed_bug)
3635
3564
            else:
3636
3565
                tag, bug_id = tokens
3637
3566
            try:
3638
 
                yield bugtracker.get_bug_url(tag, branch, bug_id), status
3639
 
            except bugtracker.UnknownBugTrackerAbbreviation:
3640
 
                raise errors.CommandError(gettext(
3641
 
                    'Unrecognized bug %s. Commit refused.') % bug)
3642
 
            except bugtracker.MalformedBugIdentifier as e:
3643
 
                raise errors.CommandError(gettext(
3644
 
                    u"%s\nCommit refused.") % (e,))
 
3567
                yield bugtracker.get_bug_url(tag, branch, bug_id)
 
3568
            except errors.UnknownBugTrackerAbbreviation:
 
3569
                raise errors.BzrCommandError(gettext(
 
3570
                    'Unrecognized bug %s. Commit refused.') % fixed_bug)
 
3571
            except errors.MalformedBugIdentifier, e:
 
3572
                raise errors.BzrCommandError(gettext(
 
3573
                    "%s\nCommit refused.") % (str(e),))
3645
3574
 
3646
3575
    def run(self, message=None, file=None, verbose=False, selected_list=None,
3647
 
            unchanged=False, strict=False, local=False, fixes=None, bugs=None,
 
3576
            unchanged=False, strict=False, local=False, fixes=None,
3648
3577
            author=None, show_diff=False, exclude=None, commit_time=None,
3649
3578
            lossy=False):
3650
 
        import itertools
3651
 
        from .commit import (
 
3579
        from bzrlib.errors import (
3652
3580
            PointlessCommit,
3653
 
            )
3654
 
        from .errors import (
3655
3581
            ConflictsInTree,
3656
3582
            StrictCommitFailed
3657
3583
        )
3658
 
        from .msgeditor import (
 
3584
        from bzrlib.msgeditor import (
3659
3585
            edit_commit_message_encoded,
3660
3586
            generate_commit_message_template,
3661
3587
            make_commit_message_template_encoded,
3666
3592
        if commit_time is not None:
3667
3593
            try:
3668
3594
                commit_stamp, offset = timestamp.parse_patch_date(commit_time)
3669
 
            except ValueError as e:
3670
 
                raise errors.CommandError(gettext(
 
3595
            except ValueError, e:
 
3596
                raise errors.BzrCommandError(gettext(
3671
3597
                    "Could not parse --commit-time: " + str(e)))
3672
3598
 
3673
3599
        properties = {}
3681
3607
 
3682
3608
        if fixes is None:
3683
3609
            fixes = []
3684
 
        if bugs is None:
3685
 
            bugs = []
3686
3610
        bug_property = bugtracker.encode_fixes_bug_urls(
3687
 
            itertools.chain(
3688
 
                self._iter_bug_urls(bugs, tree.branch, bugtracker.RELATED),
3689
 
                self._iter_bug_urls(fixes, tree.branch, bugtracker.FIXED)))
 
3611
            self._iter_bug_fix_urls(fixes, tree.branch))
3690
3612
        if bug_property:
3691
 
            properties[u'bugs'] = bug_property
 
3613
            properties['bugs'] = bug_property
3692
3614
 
3693
3615
        if local and not tree.branch.get_bound_location():
3694
3616
            raise errors.LocalRequiresBoundBranch()
3705
3627
                warning_msg = (
3706
3628
                    'The commit message is a file name: "%(f)s".\n'
3707
3629
                    '(use --file "%(f)s" to take commit message from that file)'
3708
 
                    % {'f': message})
 
3630
                    % { 'f': message })
3709
3631
                ui.ui_factory.show_warning(warning_msg)
3710
3632
            if '\r' in message:
3711
3633
                message = message.replace('\r\n', '\n')
3712
3634
                message = message.replace('\r', '\n')
3713
3635
            if file:
3714
 
                raise errors.CommandError(gettext(
 
3636
                raise errors.BzrCommandError(gettext(
3715
3637
                    "please specify either --message or --file"))
3716
3638
 
3717
3639
        def get_message(commit_obj):
3718
3640
            """Callback to get commit message"""
3719
3641
            if file:
3720
 
                with open(file, 'rb') as f:
 
3642
                f = open(file)
 
3643
                try:
3721
3644
                    my_message = f.read().decode(osutils.get_user_encoding())
 
3645
                finally:
 
3646
                    f.close()
3722
3647
            elif message is not None:
3723
3648
                my_message = message
3724
3649
            else:
3725
3650
                # No message supplied: make one up.
3726
3651
                # text is the status of the tree
3727
3652
                text = make_commit_message_template_encoded(tree,
3728
 
                                                            selected_list, diff=show_diff,
3729
 
                                                            output_encoding=osutils.get_user_encoding())
 
3653
                        selected_list, diff=show_diff,
 
3654
                        output_encoding=osutils.get_user_encoding())
3730
3655
                # start_message is the template generated from hooks
3731
3656
                # XXX: Warning - looks like hooks return unicode,
3732
3657
                # make_commit_message_template_encoded returns user encoding.
3734
3659
                # avoid this.
3735
3660
                my_message = set_commit_message(commit_obj)
3736
3661
                if my_message is None:
3737
 
                    start_message = generate_commit_message_template(
3738
 
                        commit_obj)
3739
 
                    if start_message is not None:
3740
 
                        start_message = start_message.encode(
3741
 
                            osutils.get_user_encoding())
 
3662
                    start_message = generate_commit_message_template(commit_obj)
3742
3663
                    my_message = edit_commit_message_encoded(text,
3743
 
                                                             start_message=start_message)
 
3664
                        start_message=start_message)
3744
3665
                if my_message is None:
3745
 
                    raise errors.CommandError(gettext("please specify a commit"
3746
 
                                                         " message with either --message or --file"))
 
3666
                    raise errors.BzrCommandError(gettext("please specify a commit"
 
3667
                        " message with either --message or --file"))
3747
3668
                if my_message == "":
3748
 
                    raise errors.CommandError(gettext("Empty commit message specified."
3749
 
                                                         " Please specify a commit message with either"
3750
 
                                                         " --message or --file or leave a blank message"
3751
 
                                                         " with --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 \"\"."))
3752
3673
            return my_message
3753
3674
 
3754
3675
        # The API permits a commit with a filter of [] to mean 'select nothing'
3765
3686
                        exclude=tree.safe_relpath_files(exclude),
3766
3687
                        lossy=lossy)
3767
3688
        except PointlessCommit:
3768
 
            raise errors.CommandError(gettext("No changes to commit."
3769
 
                                                 " Please 'brz add' the files you want to commit, or use"
3770
 
                                                 " --unchanged to force an empty commit."))
 
3689
            raise errors.BzrCommandError(gettext("No changes to commit."
 
3690
                " Please 'bzr add' the files you want to commit, or use"
 
3691
                " --unchanged to force an empty commit."))
3771
3692
        except ConflictsInTree:
3772
 
            raise errors.CommandError(gettext('Conflicts detected in working '
3773
 
                                                 'tree.  Use "brz conflicts" to list, "brz resolve FILE" to'
3774
 
                                                 ' resolve.'))
 
3693
            raise errors.BzrCommandError(gettext('Conflicts detected in working '
 
3694
                'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
 
3695
                ' resolve.'))
3775
3696
        except StrictCommitFailed:
3776
 
            raise errors.CommandError(gettext("Commit refused because there are"
3777
 
                                                 " unknown files in the working tree."))
3778
 
        except errors.BoundBranchOutOfDate as e:
 
3697
            raise errors.BzrCommandError(gettext("Commit refused because there are"
 
3698
                              " unknown files in the working tree."))
 
3699
        except errors.BoundBranchOutOfDate, e:
3779
3700
            e.extra_help = (gettext("\n"
3780
 
                                    'To commit to master branch, run update and then commit.\n'
3781
 
                                    'You can also pass --local to commit to continue working '
3782
 
                                    'disconnected.'))
 
3701
                'To commit to master branch, run update and then commit.\n'
 
3702
                'You can also pass --local to commit to continue working '
 
3703
                'disconnected.'))
3783
3704
            raise
3784
3705
 
3785
3706
 
3787
3708
    __doc__ = """Validate working tree structure, branch consistency and repository history.
3788
3709
 
3789
3710
    This command checks various invariants about branch and repository storage
3790
 
    to detect data corruption or brz bugs.
 
3711
    to detect data corruption or bzr bugs.
3791
3712
 
3792
3713
    The working tree and branch checks will only give output if a problem is
3793
3714
    detected. The output fields of the repository check are:
3803
3724
    unreferenced ancestors
3804
3725
        Texts that are ancestors of other texts, but
3805
3726
        are not properly referenced by the revision ancestry.  This is a
3806
 
        subtle problem that Breezy can work around.
 
3727
        subtle problem that Bazaar can work around.
3807
3728
 
3808
3729
    unique file texts
3809
3730
        This is the total number of unique file contents
3815
3736
        entries are modified, but the file contents are not.  It does not
3816
3737
        indicate a problem.
3817
3738
 
3818
 
    If no restrictions are specified, all data that is found at the given
 
3739
    If no restrictions are specified, all Bazaar data that is found at the given
3819
3740
    location will be checked.
3820
3741
 
3821
3742
    :Examples:
3822
3743
 
3823
3744
        Check the tree and branch at 'foo'::
3824
3745
 
3825
 
            brz check --tree --branch foo
 
3746
            bzr check --tree --branch foo
3826
3747
 
3827
3748
        Check only the repository at 'bar'::
3828
3749
 
3829
 
            brz check --repo bar
 
3750
            bzr check --repo bar
3830
3751
 
3831
3752
        Check everything at 'baz'::
3832
3753
 
3833
 
            brz check baz
 
3754
            bzr check baz
3834
3755
    """
3835
3756
 
3836
3757
    _see_also = ['reconcile']
3845
3766
 
3846
3767
    def run(self, path=None, verbose=False, branch=False, repo=False,
3847
3768
            tree=False):
3848
 
        from .check import check_dwim
 
3769
        from bzrlib.check import check_dwim
3849
3770
        if path is None:
3850
3771
            path = '.'
3851
3772
        if not branch and not repo and not tree:
3857
3778
    __doc__ = """Upgrade a repository, branch or working tree to a newer format.
3858
3779
 
3859
3780
    When the default format has changed after a major new release of
3860
 
    Bazaar/Breezy, you may be informed during certain operations that you
 
3781
    Bazaar, you may be informed during certain operations that you
3861
3782
    should upgrade. Upgrading to a newer format may improve performance
3862
3783
    or make new features available. It may however limit interoperability
3863
 
    with older repositories or with older versions of Bazaar or Breezy.
 
3784
    with older repositories or with older versions of Bazaar.
3864
3785
 
3865
3786
    If you wish to upgrade to a particular format rather than the
3866
3787
    current default, that can be specified using the --format option.
3882
3803
    If the conversion of a branch fails, remaining branches are still
3883
3804
    tried.
3884
3805
 
3885
 
    For more information on upgrades, see the Breezy Upgrade Guide,
3886
 
    https://www.breezy-vcs.org/doc/en/upgrade-guide/.
 
3806
    For more information on upgrades, see the Bazaar Upgrade Guide,
 
3807
    http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
3887
3808
    """
3888
3809
 
3889
3810
    _see_also = ['check', 'reconcile', 'formats']
3890
3811
    takes_args = ['url?']
3891
3812
    takes_options = [
3892
3813
        RegistryOption('format',
3893
 
                       help='Upgrade to a specific format.  See "brz help'
3894
 
                       ' formats" for details.',
3895
 
                       lazy_registry=('breezy.controldir', 'format_registry'),
3896
 
                       converter=lambda name: controldir.format_registry.make_controldir(
3897
 
                           name),
3898
 
                       value_switches=True, title='Branch format'),
 
3814
            help='Upgrade to a specific format.  See "bzr help'
 
3815
                 ' formats" for details.',
 
3816
            lazy_registry=('bzrlib.controldir', 'format_registry'),
 
3817
            converter=lambda name: controldir.format_registry.make_bzrdir(name),
 
3818
            value_switches=True, title='Branch format'),
3899
3819
        Option('clean',
3900
 
               help='Remove the backup.bzr directory if successful.'),
 
3820
            help='Remove the backup.bzr directory if successful.'),
3901
3821
        Option('dry-run',
3902
 
               help="Show what would be done, but don't actually do anything."),
 
3822
            help="Show what would be done, but don't actually do anything."),
3903
3823
    ]
3904
3824
 
3905
3825
    def run(self, url='.', format=None, clean=False, dry_run=False):
3906
 
        from .upgrade import upgrade
 
3826
        from bzrlib.upgrade import upgrade
3907
3827
        exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
3908
3828
        if exceptions:
3909
3829
            if len(exceptions) == 1:
3914
3834
 
3915
3835
 
3916
3836
class cmd_whoami(Command):
3917
 
    __doc__ = """Show or set brz user id.
 
3837
    __doc__ = """Show or set bzr user id.
3918
3838
 
3919
3839
    :Examples:
3920
3840
        Show the email of the current user::
3921
3841
 
3922
 
            brz whoami --email
 
3842
            bzr whoami --email
3923
3843
 
3924
3844
        Set the current user::
3925
3845
 
3926
 
            brz whoami "Frank Chu <fchu@example.com>"
 
3846
            bzr whoami "Frank Chu <fchu@example.com>"
3927
3847
    """
3928
 
    takes_options = ['directory',
3929
 
                     Option('email',
3930
 
                            help='Display email address only.'),
3931
 
                     Option('branch',
3932
 
                            help='Set identity for the current branch instead of '
3933
 
                            'globally.'),
3934
 
                     ]
 
3848
    takes_options = [ 'directory',
 
3849
                      Option('email',
 
3850
                             help='Display email address only.'),
 
3851
                      Option('branch',
 
3852
                             help='Set identity for the current branch instead of '
 
3853
                                  'globally.'),
 
3854
                    ]
3935
3855
    takes_args = ['name?']
3936
3856
    encoding_type = 'replace'
3937
3857
 
3955
3875
            return
3956
3876
 
3957
3877
        if email:
3958
 
            raise errors.CommandError(gettext("--email can only be used to display existing "
3959
 
                                                 "identity"))
 
3878
            raise errors.BzrCommandError(gettext("--email can only be used to display existing "
 
3879
                                         "identity"))
3960
3880
 
3961
3881
        # display a warning if an email address isn't included in the given name.
3962
3882
        try:
3963
3883
            _mod_config.extract_email_address(name)
3964
 
        except _mod_config.NoEmailInUsername:
 
3884
        except errors.NoEmailInUsername, e:
3965
3885
            warning('"%s" does not seem to contain an email address.  '
3966
3886
                    'This is allowed, but not recommended.', name)
3967
3887
 
3971
3891
                c = Branch.open_containing(u'.')[0].get_config_stack()
3972
3892
            else:
3973
3893
                b = Branch.open(directory)
3974
 
                self.enter_context(b.lock_write())
 
3894
                self.add_cleanup(b.lock_write().unlock)
3975
3895
                c = b.get_config_stack()
3976
3896
        else:
3977
3897
            c = _mod_config.GlobalStack()
3992
3912
    _see_also = ['info']
3993
3913
    takes_args = ['nickname?']
3994
3914
    takes_options = ['directory']
3995
 
 
3996
3915
    def run(self, nickname=None, directory=u'.'):
3997
3916
        branch = Branch.open_containing(directory)[0]
3998
3917
        if nickname is None:
4011
3930
    :Examples:
4012
3931
        Show the current aliases::
4013
3932
 
4014
 
            brz alias
 
3933
            bzr alias
4015
3934
 
4016
3935
        Show the alias specified for 'll'::
4017
3936
 
4018
 
            brz alias ll
 
3937
            bzr alias ll
4019
3938
 
4020
3939
        Set an alias for 'll'::
4021
3940
 
4022
 
            brz alias ll="log --line -r-10..-1"
 
3941
            bzr alias ll="log --line -r-10..-1"
4023
3942
 
4024
3943
        To remove an alias for 'll'::
4025
3944
 
4026
 
            brz alias --remove ll
 
3945
            bzr alias --remove ll
4027
3946
 
4028
3947
    """
4029
3948
    takes_args = ['name?']
4041
3960
            if equal_pos == -1:
4042
3961
                self.print_alias(name)
4043
3962
            else:
4044
 
                self.set_alias(name[:equal_pos], name[equal_pos + 1:])
 
3963
                self.set_alias(name[:equal_pos], name[equal_pos+1:])
4045
3964
 
4046
3965
    def remove_alias(self, alias_name):
4047
3966
        if alias_name is None:
4048
 
            raise errors.CommandError(gettext(
4049
 
                'brz alias --remove expects an alias to remove.'))
 
3967
            raise errors.BzrCommandError(gettext(
 
3968
                'bzr alias --remove expects an alias to remove.'))
4050
3969
        # If alias is not found, print something like:
4051
3970
        # unalias: foo: not found
4052
3971
        c = _mod_config.GlobalConfig()
4056
3975
    def print_aliases(self):
4057
3976
        """Print out the defined aliases in a similar format to bash."""
4058
3977
        aliases = _mod_config.GlobalConfig().get_aliases()
4059
 
        for key, value in sorted(aliases.items()):
4060
 
            self.outf.write('brz alias %s="%s"\n' % (key, value))
 
3978
        for key, value in sorted(aliases.iteritems()):
 
3979
            self.outf.write('bzr alias %s="%s"\n' % (key, value))
4061
3980
 
4062
3981
    @display_command
4063
3982
    def print_alias(self, alias_name):
4064
 
        from .commands import get_alias
 
3983
        from bzrlib.commands import get_alias
4065
3984
        alias = get_alias(alias_name)
4066
3985
        if alias is None:
4067
 
            self.outf.write("brz alias: %s: not found\n" % alias_name)
 
3986
            self.outf.write("bzr alias: %s: not found\n" % alias_name)
4068
3987
        else:
4069
3988
            self.outf.write(
4070
 
                'brz alias %s="%s"\n' % (alias_name, ' '.join(alias)))
 
3989
                'bzr alias %s="%s"\n' % (alias_name, ' '.join(alias)))
4071
3990
 
4072
3991
    def set_alias(self, alias_name, alias_command):
4073
3992
        """Save the alias in the global config."""
4109
4028
    Tests that need working space on disk use a common temporary directory,
4110
4029
    typically inside $TMPDIR or /tmp.
4111
4030
 
4112
 
    If you set BRZ_TEST_PDB=1 when running selftest, failing tests will drop
 
4031
    If you set BZR_TEST_PDB=1 when running selftest, failing tests will drop
4113
4032
    into a pdb postmortem session.
4114
4033
 
4115
4034
    The --coverage=DIRNAME global option produces a report with covered code
4118
4037
    :Examples:
4119
4038
        Run only tests relating to 'ignore'::
4120
4039
 
4121
 
            brz selftest ignore
 
4040
            bzr selftest ignore
4122
4041
 
4123
4042
        Disable plugins and list tests as they're run::
4124
4043
 
4125
 
            brz --no-plugins selftest -v
 
4044
            bzr --no-plugins selftest -v
4126
4045
    """
4127
4046
    # NB: this is used from the class without creating an instance, which is
4128
4047
    # why it does not have a self parameter.
4129
 
 
4130
4048
    def get_transport_type(typestring):
4131
4049
        """Parse and return a transport specifier."""
4132
4050
        if typestring == "sftp":
4133
 
            from .tests import stub_sftp
 
4051
            from bzrlib.tests import stub_sftp
4134
4052
            return stub_sftp.SFTPAbsoluteServer
4135
4053
        elif typestring == "memory":
4136
 
            from .tests import test_server
 
4054
            from bzrlib.tests import test_server
4137
4055
            return memory.MemoryServer
4138
4056
        elif typestring == "fakenfs":
4139
 
            from .tests import test_server
 
4057
            from bzrlib.tests import test_server
4140
4058
            return test_server.FakeNFSServer
4141
4059
        msg = "No known transport type %s. Supported types are: sftp\n" %\
4142
4060
            (typestring)
4143
 
        raise errors.CommandError(msg)
 
4061
        raise errors.BzrCommandError(msg)
4144
4062
 
4145
4063
    hidden = True
4146
4064
    takes_args = ['testspecs*']
4147
4065
    takes_options = ['verbose',
4148
4066
                     Option('one',
4149
 
                            help='Stop when one test fails.',
4150
 
                            short_name='1',
4151
 
                            ),
 
4067
                             help='Stop when one test fails.',
 
4068
                             short_name='1',
 
4069
                             ),
4152
4070
                     Option('transport',
4153
4071
                            help='Use a different transport by default '
4154
4072
                                 'throughout the test suite.',
4168
4086
                     Option('list-only',
4169
4087
                            help='List the tests instead of running them.'),
4170
4088
                     RegistryOption('parallel',
4171
 
                                    help="Run the test suite in parallel.",
4172
 
                                    lazy_registry=(
4173
 
                                        'breezy.tests', 'parallel_registry'),
4174
 
                                    value_switches=False,
4175
 
                                    ),
 
4089
                        help="Run the test suite in parallel.",
 
4090
                        lazy_registry=('bzrlib.tests', 'parallel_registry'),
 
4091
                        value_switches=False,
 
4092
                        ),
4176
4093
                     Option('randomize', type=str, argname="SEED",
4177
4094
                            help='Randomize the order of tests using the given'
4178
4095
                                 ' seed or "now" for the current time.'),
4180
4097
                                short_name='x',
4181
4098
                                help='Exclude tests that match this regular'
4182
4099
                                ' expression.'),
4183
 
                     Option('subunit1',
4184
 
                            help='Output test progress via subunit v1.'),
4185
 
                     Option('subunit2',
4186
 
                            help='Output test progress via subunit v2.'),
 
4100
                     Option('subunit',
 
4101
                        help='Output test progress via subunit.'),
4187
4102
                     Option('strict', help='Fail on missing dependencies or '
4188
4103
                            'known failures.'),
4189
4104
                     Option('load-list', type=str, argname='TESTLISTFILE',
4192
4107
                                help='Turn on a selftest debug flag.'),
4193
4108
                     ListOption('starting-with', type=str, argname='TESTID',
4194
4109
                                param_name='starting_with', short_name='s',
4195
 
                                help='Load only the tests starting with TESTID.'),
 
4110
                                help=
 
4111
                                'Load only the tests starting with TESTID.'),
4196
4112
                     Option('sync',
4197
4113
                            help="By default we disable fsync and fdatasync"
4198
4114
                                 " while running the test suite.")
4208
4124
            lsprof_timed=None,
4209
4125
            first=False, list_only=False,
4210
4126
            randomize=None, exclude=None, strict=False,
4211
 
            load_list=None, debugflag=None, starting_with=None, subunit1=False,
4212
 
            subunit2=False, parallel=None, lsprof_tests=False, sync=False):
 
4127
            load_list=None, debugflag=None, starting_with=None, subunit=False,
 
4128
            parallel=None, lsprof_tests=False,
 
4129
            sync=False):
4213
4130
 
4214
4131
        # During selftest, disallow proxying, as it can cause severe
4215
4132
        # performance penalties and is only needed for thread
4217
4134
        # too heavily. The call should be as early as possible, as
4218
4135
        # error reporting for past duplicate imports won't have useful
4219
4136
        # backtraces.
4220
 
        if sys.version_info[0] < 3:
4221
 
            # TODO(pad.lv/1696545): Allow proxying on Python 3, since
4222
 
            # disallowing it currently leads to failures in many places.
4223
 
            lazy_import.disallow_proxying()
 
4137
        lazy_import.disallow_proxying()
4224
4138
 
4225
 
        try:
4226
 
            from . import tests
4227
 
        except ImportError as e:
4228
 
            raise errors.CommandError("tests not available. Install the "
4229
 
                                         "breezy tests to run the breezy testsuite.")
 
4139
        from bzrlib import tests
4230
4140
 
4231
4141
        if testspecs_list is not None:
4232
4142
            pattern = '|'.join(testspecs_list)
4233
4143
        else:
4234
4144
            pattern = ".*"
4235
 
        if subunit1:
 
4145
        if subunit:
4236
4146
            try:
4237
 
                from .tests import SubUnitBzrRunnerv1
 
4147
                from bzrlib.tests import SubUnitBzrRunner
4238
4148
            except ImportError:
4239
 
                raise errors.CommandError(gettext(
4240
 
                    "subunit not available. subunit needs to be installed "
4241
 
                    "to use --subunit."))
4242
 
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunnerv1
 
4149
                raise errors.BzrCommandError(gettext("subunit not available. subunit "
 
4150
                    "needs to be installed to use --subunit."))
 
4151
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
4243
4152
            # On Windows, disable automatic conversion of '\n' to '\r\n' in
4244
 
            # stdout, which would corrupt the subunit stream.
 
4153
            # stdout, which would corrupt the subunit stream. 
4245
4154
            # FIXME: This has been fixed in subunit trunk (>0.0.5) so the
4246
4155
            # following code can be deleted when it's sufficiently deployed
4247
4156
            # -- vila/mgz 20100514
4248
4157
            if (sys.platform == "win32"
4249
 
                    and getattr(sys.stdout, 'fileno', None) is not None):
 
4158
                and getattr(sys.stdout, 'fileno', None) is not None):
4250
4159
                import msvcrt
4251
4160
                msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
4252
 
        if subunit2:
4253
 
            try:
4254
 
                from .tests import SubUnitBzrRunnerv2
4255
 
            except ImportError:
4256
 
                raise errors.CommandError(gettext(
4257
 
                    "subunit not available. subunit "
4258
 
                    "needs to be installed to use --subunit2."))
4259
 
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunnerv2
4260
 
 
4261
4161
        if parallel:
4262
4162
            self.additional_selftest_args.setdefault(
4263
4163
                'suite_decorators', []).append(parallel)
4264
4164
        if benchmark:
4265
 
            raise errors.CommandError(gettext(
4266
 
                "--benchmark is no longer supported from brz 2.2; "
 
4165
            raise errors.BzrCommandError(gettext(
 
4166
                "--benchmark is no longer supported from bzr 2.2; "
4267
4167
                "use bzr-usertest instead"))
4268
4168
        test_suite_factory = None
4269
4169
        if not exclude:
4273
4173
        if not sync:
4274
4174
            self._disable_fsync()
4275
4175
        selftest_kwargs = {"verbose": verbose,
4276
 
                           "pattern": pattern,
4277
 
                           "stop_on_failure": one,
4278
 
                           "transport": transport,
4279
 
                           "test_suite_factory": test_suite_factory,
4280
 
                           "lsprof_timed": lsprof_timed,
4281
 
                           "lsprof_tests": lsprof_tests,
4282
 
                           "matching_tests_first": first,
4283
 
                           "list_only": list_only,
4284
 
                           "random_seed": randomize,
4285
 
                           "exclude_pattern": exclude_pattern,
4286
 
                           "strict": strict,
4287
 
                           "load_list": load_list,
4288
 
                           "debug_flags": debugflag,
4289
 
                           "starting_with": starting_with
4290
 
                           }
 
4176
                          "pattern": pattern,
 
4177
                          "stop_on_failure": one,
 
4178
                          "transport": transport,
 
4179
                          "test_suite_factory": test_suite_factory,
 
4180
                          "lsprof_timed": lsprof_timed,
 
4181
                          "lsprof_tests": lsprof_tests,
 
4182
                          "matching_tests_first": first,
 
4183
                          "list_only": list_only,
 
4184
                          "random_seed": randomize,
 
4185
                          "exclude_pattern": exclude_pattern,
 
4186
                          "strict": strict,
 
4187
                          "load_list": load_list,
 
4188
                          "debug_flags": debugflag,
 
4189
                          "starting_with": starting_with
 
4190
                          }
4291
4191
        selftest_kwargs.update(self.additional_selftest_args)
4292
4192
 
4293
4193
        # Make deprecation warnings visible, unless -Werror is set
4310
4210
 
4311
4211
 
4312
4212
class cmd_version(Command):
4313
 
    __doc__ = """Show version of brz."""
 
4213
    __doc__ = """Show version of bzr."""
4314
4214
 
4315
4215
    encoding_type = 'replace'
4316
4216
    takes_options = [
4319
4219
 
4320
4220
    @display_command
4321
4221
    def run(self, short=False):
4322
 
        from .version import show_version
 
4222
        from bzrlib.version import show_version
4323
4223
        if short:
4324
 
            self.outf.write(breezy.version_string + '\n')
 
4224
            self.outf.write(bzrlib.version_string + '\n')
4325
4225
        else:
4326
4226
            show_version(to_file=self.outf)
4327
4227
 
4345
4245
 
4346
4246
    @display_command
4347
4247
    def run(self, branch, other):
4348
 
        from .revision import ensure_null
 
4248
        from bzrlib.revision import ensure_null
4349
4249
 
4350
4250
        branch1 = Branch.open_containing(branch)[0]
4351
4251
        branch2 = Branch.open_containing(other)[0]
4352
 
        self.enter_context(branch1.lock_read())
4353
 
        self.enter_context(branch2.lock_read())
 
4252
        self.add_cleanup(branch1.lock_read().unlock)
 
4253
        self.add_cleanup(branch2.lock_read().unlock)
4354
4254
        last1 = ensure_null(branch1.last_revision())
4355
4255
        last2 = ensure_null(branch2.last_revision())
4356
4256
 
4357
4257
        graph = branch1.repository.get_graph(branch2.repository)
4358
4258
        base_rev_id = graph.find_unique_lca(last1, last2)
4359
4259
 
4360
 
        self.outf.write(gettext('merge base is revision %s\n') %
4361
 
                        base_rev_id.decode('utf-8'))
 
4260
        self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
4362
4261
 
4363
4262
 
4364
4263
class cmd_merge(Command):
4366
4265
 
4367
4266
    The source of the merge can be specified either in the form of a branch,
4368
4267
    or in the form of a path to a file containing a merge directive generated
4369
 
    with brz send. If neither is specified, the default is the upstream branch
 
4268
    with bzr send. If neither is specified, the default is the upstream branch
4370
4269
    or the branch most recently merged using --remember.  The source of the
4371
4270
    merge may also be specified in the form of a path to a file in another
4372
4271
    branch:  in this case, only the modifications to that file are merged into
4373
4272
    the current working tree.
4374
4273
 
4375
 
    When merging from a branch, by default brz will try to merge in all new
 
4274
    When merging from a branch, by default bzr will try to merge in all new
4376
4275
    work from the other branch, automatically determining an appropriate base
4377
4276
    revision.  If this fails, you may need to give an explicit base.
4378
4277
 
4379
 
    To pick a different ending revision, pass "--revision OTHER".  brz will
 
4278
    To pick a different ending revision, pass "--revision OTHER".  bzr will
4380
4279
    try to merge in all new work up to and including revision OTHER.
4381
4280
 
4382
4281
    If you specify two values, "--revision BASE..OTHER", only revisions BASE
4383
4282
    through OTHER, excluding BASE but including OTHER, will be merged.  If this
4384
4283
    causes some revisions to be skipped, i.e. if the destination branch does
4385
4284
    not already contain revision BASE, such a merge is commonly referred to as
4386
 
    a "cherrypick". Unlike a normal merge, Breezy does not currently track
 
4285
    a "cherrypick". Unlike a normal merge, Bazaar does not currently track
4387
4286
    cherrypicks. The changes look like a normal commit, and the history of the
4388
4287
    changes from the other branch is not stored in the commit.
4389
4288
 
4394
4293
    it will mark a conflict.  A conflict means that you need to fix something,
4395
4294
    before you can commit.
4396
4295
 
4397
 
    Use brz resolve when you have fixed a problem.  See also brz conflicts.
 
4296
    Use bzr resolve when you have fixed a problem.  See also bzr conflicts.
4398
4297
 
4399
4298
    If there is no default branch set, the first merge will set it (use
4400
4299
    --no-remember to avoid setting it). After that, you can omit the branch
4402
4301
    only be saved if the remote location can be accessed.
4403
4302
 
4404
4303
    The results of the merge are placed into the destination working
4405
 
    directory, where they can be reviewed (with brz diff), tested, and then
 
4304
    directory, where they can be reviewed (with bzr diff), tested, and then
4406
4305
    committed to record the result of the merge.
4407
4306
 
4408
4307
    merge refuses to run if there are any uncommitted changes, unless
4409
 
    --force is given.  If --force is given, then the changes from the source
 
4308
    --force is given.  If --force is given, then the changes from the source 
4410
4309
    will be merged with the current working tree, including any uncommitted
4411
4310
    changes in the tree.  The --force option can also be used to create a
4412
4311
    merge revision which has more than two parents.
4419
4318
    you to apply each diff hunk and file change, similar to "shelve".
4420
4319
 
4421
4320
    :Examples:
4422
 
        To merge all new revisions from brz.dev::
4423
 
 
4424
 
            brz merge ../brz.dev
4425
 
 
4426
 
        To merge changes up to and including revision 82 from brz.dev::
4427
 
 
4428
 
            brz merge -r 82 ../brz.dev
 
4321
        To merge all new revisions from bzr.dev::
 
4322
 
 
4323
            bzr merge ../bzr.dev
 
4324
 
 
4325
        To merge changes up to and including revision 82 from bzr.dev::
 
4326
 
 
4327
            bzr merge -r 82 ../bzr.dev
4429
4328
 
4430
4329
        To merge the changes introduced by 82, without previous changes::
4431
4330
 
4432
 
            brz merge -r 81..82 ../brz.dev
 
4331
            bzr merge -r 81..82 ../bzr.dev
4433
4332
 
4434
4333
        To apply a merge directive contained in /tmp/merge::
4435
4334
 
4436
 
            brz merge /tmp/merge
 
4335
            bzr merge /tmp/merge
4437
4336
 
4438
4337
        To create a merge revision with three parents from two branches
4439
4338
        feature1a and feature1b:
4440
4339
 
4441
 
            brz merge ../feature1a
4442
 
            brz merge ../feature1b --force
4443
 
            brz commit -m 'revision with three parents'
 
4340
            bzr merge ../feature1a
 
4341
            bzr merge ../feature1b --force
 
4342
            bzr commit -m 'revision with three parents'
4444
4343
    """
4445
4344
 
4446
4345
    encoding_type = 'exact'
4459
4358
        Option('uncommitted', help='Apply uncommitted changes'
4460
4359
               ' from a working copy, instead of branch changes.'),
4461
4360
        Option('pull', help='If the destination is already'
4462
 
               ' completely merged into the source, pull from the'
4463
 
               ' source rather than merging.  When this happens,'
4464
 
               ' you do not need to commit the result.'),
 
4361
                ' completely merged into the source, pull from the'
 
4362
                ' source rather than merging.  When this happens,'
 
4363
                ' you do not need to commit the result.'),
4465
4364
        custom_help('directory',
4466
 
                    help='Branch to merge into, '
 
4365
               help='Branch to merge into, '
4467
4366
                    'rather than the one containing the working directory.'),
4468
4367
        Option('preview', help='Instead of merging, show a diff of the'
4469
4368
               ' merge.'),
4470
4369
        Option('interactive', help='Select changes interactively.',
4471
 
               short_name='i')
 
4370
            short_name='i')
4472
4371
    ]
4473
4372
 
4474
4373
    def run(self, location=None, revision=None, force=False,
4481
4380
        if merge_type is None:
4482
4381
            merge_type = _mod_merge.Merge3Merger
4483
4382
 
4484
 
        if directory is None:
4485
 
            directory = u'.'
 
4383
        if directory is None: directory = u'.'
4486
4384
        possible_transports = []
4487
4385
        merger = None
4488
4386
        allow_pending = True
4489
4387
        verified = 'inapplicable'
4490
4388
 
4491
4389
        tree = WorkingTree.open_containing(directory)[0]
4492
 
        if tree.branch.last_revision() == _mod_revision.NULL_REVISION:
4493
 
            raise errors.CommandError(gettext('Merging into empty branches not currently supported, '
4494
 
                                                 'https://bugs.launchpad.net/bzr/+bug/308562'))
 
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
 
 
4394
        try:
 
4395
            basis_tree = tree.revision_tree(tree.last_revision())
 
4396
        except errors.NoSuchRevision:
 
4397
            basis_tree = tree.basis_tree()
4495
4398
 
4496
4399
        # die as quickly as possible if there are uncommitted changes
4497
4400
        if not force:
4502
4405
        change_reporter = delta._ChangeReporter(
4503
4406
            unversioned_filter=tree.is_ignored, view_info=view_info)
4504
4407
        pb = ui.ui_factory.nested_progress_bar()
4505
 
        self.enter_context(pb)
4506
 
        self.enter_context(tree.lock_write())
 
4408
        self.add_cleanup(pb.finished)
 
4409
        self.add_cleanup(tree.lock_write().unlock)
4507
4410
        if location is not None:
4508
4411
            try:
4509
 
                mergeable = _mod_mergeable.read_mergeable_from_url(
4510
 
                    location, possible_transports=possible_transports)
 
4412
                mergeable = bundle.read_mergeable_from_url(location,
 
4413
                    possible_transports=possible_transports)
4511
4414
            except errors.NotABundle:
4512
4415
                mergeable = None
4513
4416
            else:
4514
4417
                if uncommitted:
4515
 
                    raise errors.CommandError(gettext('Cannot use --uncommitted'
4516
 
                                                         ' with bundles or merge directives.'))
 
4418
                    raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
 
4419
                        ' with bundles or merge directives.'))
4517
4420
 
4518
4421
                if revision is not None:
4519
 
                    raise errors.CommandError(gettext(
 
4422
                    raise errors.BzrCommandError(gettext(
4520
4423
                        'Cannot use -r with merge directives or bundles'))
4521
4424
                merger, verified = _mod_merge.Merger.from_mergeable(tree,
4522
 
                                                                    mergeable)
 
4425
                   mergeable, None)
4523
4426
 
4524
4427
        if merger is None and uncommitted:
4525
4428
            if revision is not None and len(revision) > 0:
4526
 
                raise errors.CommandError(gettext('Cannot use --uncommitted and'
4527
 
                                                     ' --revision at the same time.'))
 
4429
                raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
 
4430
                    ' --revision at the same time.'))
4528
4431
            merger = self.get_merger_from_uncommitted(tree, location, None)
4529
4432
            allow_pending = False
4530
4433
 
4531
4434
        if merger is None:
4532
4435
            merger, allow_pending = self._get_merger_from_branch(tree,
4533
 
                                                                 location, revision, remember, possible_transports, None)
 
4436
                location, revision, remember, possible_transports, None)
4534
4437
 
4535
4438
        merger.merge_type = merge_type
4536
4439
        merger.reprocess = reprocess
4537
4440
        merger.show_base = show_base
4538
4441
        self.sanity_check_merger(merger)
4539
4442
        if (merger.base_rev_id == merger.other_rev_id and
4540
 
                merger.other_rev_id is not None):
 
4443
            merger.other_rev_id is not None):
4541
4444
            # check if location is a nonexistent file (and not a branch) to
4542
4445
            # disambiguate the 'Nothing to do'
4543
4446
            if merger.interesting_files:
4544
4447
                if not merger.other_tree.has_filename(
4545
 
                        merger.interesting_files[0]):
 
4448
                    merger.interesting_files[0]):
4546
4449
                    note(gettext("merger: ") + str(merger))
4547
4450
                    raise errors.PathsDoNotExist([location])
4548
4451
            note(gettext('Nothing to do.'))
4549
4452
            return 0
4550
4453
        if pull and not preview:
4551
4454
            if merger.interesting_files is not None:
4552
 
                raise errors.CommandError(
4553
 
                    gettext('Cannot pull individual files'))
 
4455
                raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4554
4456
            if (merger.base_rev_id == tree.last_revision()):
4555
4457
                result = tree.pull(merger.other_branch, False,
4556
4458
                                   merger.other_rev_id)
4557
4459
                result.report(self.outf)
4558
4460
                return 0
4559
4461
        if merger.this_basis is None:
4560
 
            raise errors.CommandError(gettext(
 
4462
            raise errors.BzrCommandError(gettext(
4561
4463
                "This branch has no commits."
4562
 
                " (perhaps you would prefer 'brz pull')"))
 
4464
                " (perhaps you would prefer 'bzr pull')"))
4563
4465
        if preview:
4564
4466
            return self._do_preview(merger)
4565
4467
        elif interactive:
4571
4473
    def _get_preview(self, merger):
4572
4474
        tree_merger = merger.make_merger()
4573
4475
        tt = tree_merger.make_preview_transform()
4574
 
        self.enter_context(tt)
 
4476
        self.add_cleanup(tt.finalize)
4575
4477
        result_tree = tt.get_preview_tree()
4576
4478
        return result_tree
4577
4479
 
4578
4480
    def _do_preview(self, merger):
4579
 
        from .diff import show_diff_trees
 
4481
        from bzrlib.diff import show_diff_trees
4580
4482
        result_tree = self._get_preview(merger)
4581
4483
        path_encoding = osutils.get_diff_header_encoding()
4582
4484
        show_diff_trees(merger.this_tree, result_tree, self.outf,
4602
4504
        Shelver to selectively remove the differences between the working tree
4603
4505
        and the preview tree.
4604
4506
        """
4605
 
        from . import shelf_ui
 
4507
        from bzrlib import shelf_ui
4606
4508
        result_tree = self._get_preview(merger)
4607
 
        writer = breezy.option.diff_writer_registry.get()
 
4509
        writer = bzrlib.option.diff_writer_registry.get()
4608
4510
        shelver = shelf_ui.Shelver(merger.this_tree, result_tree, destroy=True,
4609
4511
                                   reporter=shelf_ui.ApplyReporter(),
4610
 
                                   diff_writer=writer(self.outf))
 
4512
                                   diff_writer=writer(sys.stdout))
4611
4513
        try:
4612
4514
            shelver.run()
4613
4515
        finally:
4615
4517
 
4616
4518
    def sanity_check_merger(self, merger):
4617
4519
        if (merger.show_base and
4618
 
                merger.merge_type is not _mod_merge.Merge3Merger):
4619
 
            raise errors.CommandError(gettext("Show-base is not supported for this"
4620
 
                                                 " merge type. %s") % merger.merge_type)
 
4520
            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)
4621
4523
        if merger.reprocess is None:
4622
4524
            if merger.show_base:
4623
4525
                merger.reprocess = False
4625
4527
                # Use reprocess if the merger supports it
4626
4528
                merger.reprocess = merger.merge_type.supports_reprocess
4627
4529
        if merger.reprocess and not merger.merge_type.supports_reprocess:
4628
 
            raise errors.CommandError(gettext("Conflict reduction is not supported"
4629
 
                                                 " for merge type %s.") %
 
4530
            raise errors.BzrCommandError(gettext("Conflict reduction is not supported"
 
4531
                                         " for merge type %s.") %
4630
4532
                                         merger.merge_type)
4631
4533
        if merger.reprocess and merger.show_base:
4632
 
            raise errors.CommandError(gettext("Cannot do conflict reduction and"
4633
 
                                                 " show base."))
4634
 
 
4635
 
        if (merger.merge_type.requires_file_merge_plan and
4636
 
            (not getattr(merger.this_tree, 'plan_file_merge', None) or
4637
 
             not getattr(merger.other_tree, 'plan_file_merge', None) or
4638
 
             (merger.base_tree is not None and
4639
 
                 not getattr(merger.base_tree, 'plan_file_merge', None)))):
4640
 
            raise errors.CommandError(
4641
 
                gettext('Plan file merge unsupported: '
4642
 
                        'Merge type incompatible with tree formats.'))
 
4534
            raise errors.BzrCommandError(gettext("Cannot do conflict reduction and"
 
4535
                                         " show base."))
4643
4536
 
4644
4537
    def _get_merger_from_branch(self, tree, location, revision, remember,
4645
4538
                                possible_transports, pb):
4646
4539
        """Produce a merger from a location, assuming it refers to a branch."""
 
4540
        from bzrlib.tag import _merge_tags_if_possible
4647
4541
        # find the branch locations
4648
4542
        other_loc, user_location = self._select_branch_location(tree, location,
4649
 
                                                                revision, -1)
 
4543
            revision, -1)
4650
4544
        if revision is not None and len(revision) == 2:
4651
4545
            base_loc, _unused = self._select_branch_location(tree,
4652
 
                                                             location, revision, 0)
 
4546
                location, revision, 0)
4653
4547
        else:
4654
4548
            base_loc = other_loc
4655
4549
        # Open the branches
4656
4550
        other_branch, other_path = Branch.open_containing(other_loc,
4657
 
                                                          possible_transports)
 
4551
            possible_transports)
4658
4552
        if base_loc == other_loc:
4659
4553
            base_branch = other_branch
4660
4554
        else:
4661
4555
            base_branch, base_path = Branch.open_containing(base_loc,
4662
 
                                                            possible_transports)
 
4556
                possible_transports)
4663
4557
        # Find the revision ids
4664
4558
        other_revision_id = None
4665
4559
        base_revision_id = None
4677
4571
        # - user ask to remember or there is no previous location set to merge
4678
4572
        #   from and user didn't ask to *not* remember
4679
4573
        if (user_location is not None
4680
 
            and ((remember or
4681
 
                 (remember is None and
4682
 
                  tree.branch.get_submit_branch() is None)))):
 
4574
            and ((remember
 
4575
                  or (remember is None
 
4576
                      and tree.branch.get_submit_branch() is None)))):
4683
4577
            tree.branch.set_submit_branch(other_branch.base)
4684
4578
        # Merge tags (but don't set them in the master branch yet, the user
4685
4579
        # might revert this merge).  Commit will propagate them.
4686
 
        other_branch.tags.merge_to(tree.branch.tags, ignore_master=True)
4687
 
        merger = _mod_merge.Merger.from_revision_ids(tree,
4688
 
                                                     other_revision_id, base_revision_id, other_branch, base_branch)
 
4580
        _merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
 
4581
        merger = _mod_merge.Merger.from_revision_ids(pb, tree,
 
4582
            other_revision_id, base_revision_id, other_branch, base_branch)
4689
4583
        if other_path != '':
4690
4584
            allow_pending = False
4691
4585
            merger.interesting_files = [other_path]
4726
4620
            will be the user-entered location.
4727
4621
        """
4728
4622
        if (revision is not None and index is not None
4729
 
                and revision[index] is not None):
 
4623
            and revision[index] is not None):
4730
4624
            branch = revision[index].get_branch()
4731
4625
            if branch is not None:
4732
4626
                return branch, branch
4748
4642
            stored_location_type = "parent"
4749
4643
        mutter("%s", stored_location)
4750
4644
        if stored_location is None:
4751
 
            raise errors.CommandError(
4752
 
                gettext("No location specified or remembered"))
 
4645
            raise errors.BzrCommandError(gettext("No location specified or remembered"))
4753
4646
        display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4754
4647
        note(gettext("{0} remembered {1} location {2}").format(verb_string,
4755
 
                                                               stored_location_type, display_url))
 
4648
                stored_location_type, display_url))
4756
4649
        return stored_location
4757
4650
 
4758
4651
 
4771
4664
        Re-do the merge of all conflicted files, and show the base text in
4772
4665
        conflict regions, in addition to the usual THIS and OTHER texts::
4773
4666
 
4774
 
            brz remerge --show-base
 
4667
            bzr remerge --show-base
4775
4668
 
4776
4669
        Re-do the merge of "foobar", using the weave merge algorithm, with
4777
4670
        additional processing to reduce the size of conflict regions::
4778
4671
 
4779
 
            brz remerge --merge-type weave --reprocess foobar
 
4672
            bzr remerge --merge-type weave --reprocess foobar
4780
4673
    """
4781
4674
    takes_args = ['file*']
4782
4675
    takes_options = [
4783
 
        'merge-type',
4784
 
        'reprocess',
4785
 
        Option('show-base',
4786
 
               help="Show base revision text in conflicts."),
4787
 
        ]
 
4676
            'merge-type',
 
4677
            'reprocess',
 
4678
            Option('show-base',
 
4679
                   help="Show base revision text in conflicts."),
 
4680
            ]
4788
4681
 
4789
4682
    def run(self, file_list=None, merge_type=None, show_base=False,
4790
4683
            reprocess=False):
4791
 
        from .conflicts import restore
 
4684
        from bzrlib.conflicts import restore
4792
4685
        if merge_type is None:
4793
4686
            merge_type = _mod_merge.Merge3Merger
4794
4687
        tree, file_list = WorkingTree.open_containing_paths(file_list)
4795
 
        self.enter_context(tree.lock_write())
 
4688
        self.add_cleanup(tree.lock_write().unlock)
4796
4689
        parents = tree.get_parent_ids()
4797
4690
        if len(parents) != 2:
4798
 
            raise errors.CommandError(
4799
 
                gettext("Sorry, remerge only works after normal"
4800
 
                        " merges.  Not cherrypicking or multi-merges."))
4801
 
        interesting_files = None
 
4691
            raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
 
4692
                                         " merges.  Not cherrypicking or"
 
4693
                                         " multi-merges."))
 
4694
        repository = tree.branch.repository
 
4695
        interesting_ids = None
4802
4696
        new_conflicts = []
4803
4697
        conflicts = tree.conflicts()
4804
4698
        if file_list is not None:
4805
 
            interesting_files = set()
 
4699
            interesting_ids = set()
4806
4700
            for filename in file_list:
4807
 
                if not tree.is_versioned(filename):
 
4701
                file_id = tree.path2id(filename)
 
4702
                if file_id is None:
4808
4703
                    raise errors.NotVersionedError(filename)
4809
 
                interesting_files.add(filename)
4810
 
                if tree.kind(filename) != "directory":
 
4704
                interesting_ids.add(file_id)
 
4705
                if tree.kind(file_id) != "directory":
4811
4706
                    continue
4812
4707
 
4813
 
                for path, ie in tree.iter_entries_by_dir(
4814
 
                        specific_files=[filename]):
4815
 
                    interesting_files.add(path)
 
4708
                # FIXME: Support nested trees
 
4709
                for name, ie in tree.root_inventory.iter_entries(file_id):
 
4710
                    interesting_ids.add(ie.file_id)
4816
4711
            new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4817
4712
        else:
4818
4713
            # Remerge only supports resolving contents conflicts
4819
4714
            allowed_conflicts = ('text conflict', 'contents conflict')
4820
4715
            restore_files = [c.path for c in conflicts
4821
4716
                             if c.typestring in allowed_conflicts]
4822
 
        _mod_merge.transform_tree(tree, tree.basis_tree(), interesting_files)
 
4717
        _mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4823
4718
        tree.set_conflicts(ConflictList(new_conflicts))
4824
4719
        if file_list is not None:
4825
4720
            restore_files = file_list
4835
4730
        # have not yet been seen.
4836
4731
        tree.set_parent_ids(parents[:1])
4837
4732
        try:
4838
 
            merger = _mod_merge.Merger.from_revision_ids(tree, parents[1])
4839
 
            merger.interesting_files = interesting_files
 
4733
            merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
 
4734
            merger.interesting_ids = interesting_ids
4840
4735
            merger.merge_type = merge_type
4841
4736
            merger.show_base = show_base
4842
4737
            merger.reprocess = reprocess
4869
4764
    update command.
4870
4765
 
4871
4766
    Uncommitted changes to files that are reverted will be discarded.
4872
 
    However, by default, any files that have been manually changed will be
 
4767
    Howver, by default, any files that have been manually changed will be
4873
4768
    backed up first.  (Files changed only by merge are not backed up.)  Backup
4874
4769
    files have '.~#~' appended to their name, where # is a number.
4875
4770
 
4887
4782
    not yet committed. These revisions will be included as additional parents
4888
4783
    of the next commit.  Normally, using revert clears that list as well as
4889
4784
    reverting the files.  If any files are specified, revert leaves the list
4890
 
    of uncommitted merges alone and reverts only the files.  Use ``brz revert
 
4785
    of uncommitted merges alone and reverts only the files.  Use ``bzr revert
4891
4786
    .`` in the tree root to revert all files but keep the recorded merges,
4892
 
    and ``brz revert --forget-merges`` to clear the pending merge list without
 
4787
    and ``bzr revert --forget-merges`` to clear the pending merge list without
4893
4788
    reverting any files.
4894
4789
 
4895
 
    Using "brz revert --forget-merges", it is possible to apply all of the
 
4790
    Using "bzr revert --forget-merges", it is possible to apply all of the
4896
4791
    changes from a branch in a single revision.  To do this, perform the merge
4897
4792
    as desired.  Then doing revert with the "--forget-merges" option will keep
4898
4793
    the content of the tree as it was, but it will clear the list of pending
4915
4810
    def run(self, revision=None, no_backup=False, file_list=None,
4916
4811
            forget_merges=None):
4917
4812
        tree, file_list = WorkingTree.open_containing_paths(file_list)
4918
 
        self.enter_context(tree.lock_tree_write())
 
4813
        self.add_cleanup(tree.lock_tree_write().unlock)
4919
4814
        if forget_merges:
4920
4815
            tree.set_parent_ids(tree.get_parent_ids()[:1])
4921
4816
        else:
4925
4820
    def _revert_tree_to_revision(tree, revision, file_list, no_backup):
4926
4821
        rev_tree = _get_one_revision_tree('revert', revision, tree=tree)
4927
4822
        tree.revert(file_list, rev_tree, not no_backup, None,
4928
 
                    report_changes=True)
 
4823
            report_changes=True)
4929
4824
 
4930
4825
 
4931
4826
class cmd_assert_fail(Command):
4944
4839
 
4945
4840
    _see_also = ['topics']
4946
4841
    takes_options = [
4947
 
        Option('long', 'Show help on all commands.'),
4948
 
        ]
 
4842
            Option('long', 'Show help on all commands.'),
 
4843
            ]
4949
4844
    takes_args = ['topic?']
4950
4845
    aliases = ['?', '--help', '-?', '-h']
4951
4846
 
4952
4847
    @display_command
4953
4848
    def run(self, topic=None, long=False):
4954
 
        import breezy.help
 
4849
        import bzrlib.help
4955
4850
        if topic is None and long:
4956
4851
            topic = "commands"
4957
 
        breezy.help.help(topic)
 
4852
        bzrlib.help.help(topic)
4958
4853
 
4959
4854
 
4960
4855
class cmd_shell_complete(Command):
4961
4856
    __doc__ = """Show appropriate completions for context.
4962
4857
 
4963
 
    For a list of all available commands, say 'brz shell-complete'.
 
4858
    For a list of all available commands, say 'bzr shell-complete'.
4964
4859
    """
4965
4860
    takes_args = ['context?']
4966
4861
    aliases = ['s-c']
4968
4863
 
4969
4864
    @display_command
4970
4865
    def run(self, context=None):
4971
 
        from . import shellcomplete
 
4866
        from bzrlib import shellcomplete
4972
4867
        shellcomplete.shellcomplete(context)
4973
4868
 
4974
4869
 
4980
4875
    To filter on a range of revisions, you can use the command -r begin..end
4981
4876
    -r revision requests a specific revision, -r ..end or -r begin.. are
4982
4877
    also valid.
4983
 
 
 
4878
            
4984
4879
    :Exit values:
4985
4880
        1 - some missing revisions
4986
4881
        0 - no missing revisions
4990
4885
        Determine the missing revisions between this and the branch at the
4991
4886
        remembered pull location::
4992
4887
 
4993
 
            brz missing
 
4888
            bzr missing
4994
4889
 
4995
4890
        Determine the missing revisions between this and another branch::
4996
4891
 
4997
 
            brz missing http://server/branch
 
4892
            bzr missing http://server/branch
4998
4893
 
4999
4894
        Determine the missing revisions up to a specific revision on the other
5000
4895
        branch::
5001
4896
 
5002
 
            brz missing -r ..-10
 
4897
            bzr missing -r ..-10
5003
4898
 
5004
4899
        Determine the missing revisions up to a specific revision on this
5005
4900
        branch::
5006
4901
 
5007
 
            brz missing --my-revision ..-10
 
4902
            bzr missing --my-revision ..-10
5008
4903
    """
5009
4904
 
5010
4905
    _see_also = ['merge', 'pull']
5014
4909
        Option('reverse', 'Reverse the order of revisions.'),
5015
4910
        Option('mine-only',
5016
4911
               'Display changes in the local branch only.'),
5017
 
        Option('this', 'Same as --mine-only.'),
 
4912
        Option('this' , 'Same as --mine-only.'),
5018
4913
        Option('theirs-only',
5019
4914
               'Display changes in the remote branch only.'),
5020
4915
        Option('other', 'Same as --theirs-only.'),
5022
4917
        'show-ids',
5023
4918
        'verbose',
5024
4919
        custom_help('revision',
5025
 
                    help='Filter on other branch revisions (inclusive). '
5026
 
                    'See "help revisionspec" for details.'),
 
4920
             help='Filter on other branch revisions (inclusive). '
 
4921
                'See "help revisionspec" for details.'),
5027
4922
        Option('my-revision',
5028
 
               type=_parse_revision_str,
5029
 
               help='Filter on local branch revisions (inclusive). '
5030
 
               'See "help revisionspec" for details.'),
 
4923
            type=_parse_revision_str,
 
4924
            help='Filter on local branch revisions (inclusive). '
 
4925
                'See "help revisionspec" for details.'),
5031
4926
        Option('include-merged',
5032
4927
               'Show all revisions in addition to the mainline ones.'),
5033
4928
        Option('include-merges', hidden=True,
5041
4936
            log_format=None, long=False, short=False, line=False,
5042
4937
            show_ids=False, verbose=False, this=False, other=False,
5043
4938
            include_merged=None, revision=None, my_revision=None,
5044
 
            directory=u'.'):
5045
 
        from breezy.missing import find_unmerged, iter_log_revisions
5046
 
 
 
4939
            directory=u'.',
 
4940
            include_merges=symbol_versioning.DEPRECATED_PARAMETER):
 
4941
        from bzrlib.missing import find_unmerged, iter_log_revisions
5047
4942
        def message(s):
5048
4943
            if not is_quiet():
5049
4944
                self.outf.write(s)
5050
4945
 
 
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'))
5051
4959
        if include_merged is None:
5052
4960
            include_merged = False
5053
4961
        if this:
5064
4972
            restrict = 'remote'
5065
4973
 
5066
4974
        local_branch = Branch.open_containing(directory)[0]
5067
 
        self.enter_context(local_branch.lock_read())
 
4975
        self.add_cleanup(local_branch.lock_read().unlock)
5068
4976
 
5069
4977
        parent = local_branch.get_parent()
5070
4978
        if other_branch is None:
5071
4979
            other_branch = parent
5072
4980
            if other_branch is None:
5073
 
                raise errors.CommandError(gettext("No peer location known"
5074
 
                                                     " or specified."))
 
4981
                raise errors.BzrCommandError(gettext("No peer location known"
 
4982
                                             " or specified."))
5075
4983
            display_url = urlutils.unescape_for_display(parent,
5076
4984
                                                        self.outf.encoding)
5077
4985
            message(gettext("Using saved parent location: {0}\n").format(
5081
4989
        if remote_branch.base == local_branch.base:
5082
4990
            remote_branch = local_branch
5083
4991
        else:
5084
 
            self.enter_context(remote_branch.lock_read())
 
4992
            self.add_cleanup(remote_branch.lock_read().unlock)
5085
4993
 
5086
4994
        local_revid_range = _revision_range_to_revid_range(
5087
4995
            _get_revision_range(my_revision, local_branch,
5088
 
                                self.name()))
 
4996
                self.name()))
5089
4997
 
5090
4998
        remote_revid_range = _revision_range_to_revid_range(
5091
4999
            _get_revision_range(revision,
5092
 
                                remote_branch, self.name()))
 
5000
                remote_branch, self.name()))
5093
5001
 
5094
5002
        local_extra, remote_extra = find_unmerged(
5095
5003
            local_branch, remote_branch, restrict,
5108
5016
        status_code = 0
5109
5017
        if local_extra and not theirs_only:
5110
5018
            message(ngettext("You have %d extra revision:\n",
5111
 
                             "You have %d extra revisions:\n",
 
5019
                             "You have %d extra revisions:\n", 
5112
5020
                             len(local_extra)) %
5113
 
                    len(local_extra))
 
5021
                len(local_extra))
5114
5022
            rev_tag_dict = {}
5115
5023
            if local_branch.supports_tags():
5116
5024
                rev_tag_dict = local_branch.tags.get_reverse_tag_dict()
5117
5025
            for revision in iter_log_revisions(local_extra,
5118
 
                                               local_branch.repository,
5119
 
                                               verbose,
5120
 
                                               rev_tag_dict):
 
5026
                                local_branch.repository,
 
5027
                                verbose,
 
5028
                                rev_tag_dict):
5121
5029
                lf.log_revision(revision)
5122
5030
            printed_local = True
5123
5031
            status_code = 1
5130
5038
            message(ngettext("You are missing %d revision:\n",
5131
5039
                             "You are missing %d revisions:\n",
5132
5040
                             len(remote_extra)) %
5133
 
                    len(remote_extra))
 
5041
                len(remote_extra))
5134
5042
            if remote_branch.supports_tags():
5135
5043
                rev_tag_dict = remote_branch.tags.get_reverse_tag_dict()
5136
5044
            for revision in iter_log_revisions(remote_extra,
5137
 
                                               remote_branch.repository,
5138
 
                                               verbose,
5139
 
                                               rev_tag_dict):
 
5045
                                remote_branch.repository,
 
5046
                                verbose,
 
5047
                                rev_tag_dict):
5140
5048
                lf.log_revision(revision)
5141
5049
            status_code = 1
5142
5050
 
5153
5061
            message(gettext("Branches are up to date.\n"))
5154
5062
        self.cleanup_now()
5155
5063
        if not status_code and parent is None and other_branch is not None:
5156
 
            self.enter_context(local_branch.lock_write())
 
5064
            self.add_cleanup(local_branch.lock_write().unlock)
5157
5065
            # handle race conditions - a parent might be set while we run.
5158
5066
            if local_branch.get_parent() is None:
5159
5067
                local_branch.set_parent(remote_branch.base)
5182
5090
    _see_also = ['repositories']
5183
5091
    takes_args = ['branch_or_repo?']
5184
5092
    takes_options = [
5185
 
        Option('clean-obsolete-packs',
5186
 
               'Delete obsolete packs to save disk space.'),
 
5093
        Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
5187
5094
        ]
5188
5095
 
5189
5096
    def run(self, branch_or_repo='.', clean_obsolete_packs=False):
5204
5111
 
5205
5112
    --verbose shows the path where each plugin is located.
5206
5113
 
5207
 
    A plugin is an external component for Breezy that extends the
5208
 
    revision control system, by adding or replacing code in Breezy.
 
5114
    A plugin is an external component for Bazaar that extends the
 
5115
    revision control system, by adding or replacing code in Bazaar.
5209
5116
    Plugins can do a variety of things, including overriding commands,
5210
5117
    adding new commands, providing additional network transports and
5211
5118
    customizing log output.
5219
5126
 
5220
5127
    @display_command
5221
5128
    def run(self, verbose=False):
5222
 
        from . import plugin
 
5129
        from bzrlib import plugin
5223
5130
        # Don't give writelines a generator as some codecs don't like that
5224
5131
        self.outf.writelines(
5225
5132
            list(plugin.describe_plugins(show_paths=verbose)))
5228
5135
class cmd_testament(Command):
5229
5136
    __doc__ = """Show testament (signing-form) of a revision."""
5230
5137
    takes_options = [
5231
 
        'revision',
5232
 
        Option('long', help='Produce long-format testament.'),
5233
 
        Option('strict',
5234
 
               help='Produce a strict-format testament.')]
 
5138
            'revision',
 
5139
            Option('long', help='Produce long-format testament.'),
 
5140
            Option('strict',
 
5141
                   help='Produce a strict-format testament.')]
5235
5142
    takes_args = ['branch?']
5236
5143
    encoding_type = 'exact'
5237
 
 
5238
5144
    @display_command
5239
5145
    def run(self, branch=u'.', revision=None, long=False, strict=False):
5240
 
        from .bzr.testament import Testament, StrictTestament
 
5146
        from bzrlib.testament import Testament, StrictTestament
5241
5147
        if strict is True:
5242
5148
            testament_class = StrictTestament
5243
5149
        else:
5246
5152
            b = Branch.open_containing(branch)[0]
5247
5153
        else:
5248
5154
            b = Branch.open(branch)
5249
 
        self.enter_context(b.lock_read())
 
5155
        self.add_cleanup(b.lock_read().unlock)
5250
5156
        if revision is None:
5251
5157
            rev_id = b.last_revision()
5252
5158
        else:
5283
5189
    @display_command
5284
5190
    def run(self, filename, all=False, long=False, revision=None,
5285
5191
            show_ids=False, directory=None):
5286
 
        from .annotate import (
 
5192
        from bzrlib.annotate import (
5287
5193
            annotate_file_tree,
5288
5194
            )
5289
5195
        wt, branch, relpath = \
5290
5196
            _open_directory_or_containing_tree_or_branch(filename, directory)
5291
5197
        if wt is not None:
5292
 
            self.enter_context(wt.lock_read())
 
5198
            self.add_cleanup(wt.lock_read().unlock)
5293
5199
        else:
5294
 
            self.enter_context(branch.lock_read())
 
5200
            self.add_cleanup(branch.lock_read().unlock)
5295
5201
        tree = _get_one_revision_tree('annotate', revision, branch=branch)
5296
 
        self.enter_context(tree.lock_read())
5297
 
        if wt is not None and revision is None:
5298
 
            if not wt.is_versioned(relpath):
5299
 
                raise errors.NotVersionedError(relpath)
 
5202
        self.add_cleanup(tree.lock_read().unlock)
 
5203
        if wt is not None and revision is None:
 
5204
            file_id = wt.path2id(relpath)
 
5205
        else:
 
5206
            file_id = tree.path2id(relpath)
 
5207
        if file_id is None:
 
5208
            raise errors.NotVersionedError(filename)
 
5209
        if wt is not None and revision is None:
5300
5210
            # If there is a tree and we're not annotating historical
5301
5211
            # versions, annotate the working tree's content.
5302
 
            annotate_file_tree(wt, relpath, self.outf, long, all,
5303
 
                               show_ids=show_ids)
 
5212
            annotate_file_tree(wt, file_id, self.outf, long, all,
 
5213
                show_ids=show_ids)
5304
5214
        else:
5305
 
            if not tree.is_versioned(relpath):
5306
 
                raise errors.NotVersionedError(relpath)
5307
 
            annotate_file_tree(tree, relpath, self.outf, long, all,
5308
 
                               show_ids=show_ids, branch=branch)
 
5215
            annotate_file_tree(tree, file_id, self.outf, long, all,
 
5216
                show_ids=show_ids, branch=branch)
5309
5217
 
5310
5218
 
5311
5219
class cmd_re_sign(Command):
5312
5220
    __doc__ = """Create a digital signature for an existing revision."""
5313
5221
    # TODO be able to replace existing ones.
5314
5222
 
5315
 
    hidden = True  # is this right ?
 
5223
    hidden = True # is this right ?
5316
5224
    takes_args = ['revision_id*']
5317
5225
    takes_options = ['directory', 'revision']
5318
5226
 
5319
5227
    def run(self, revision_id_list=None, revision=None, directory=u'.'):
5320
5228
        if revision_id_list is not None and revision is not None:
5321
 
            raise errors.CommandError(
5322
 
                gettext('You can only supply one of revision_id or --revision'))
 
5229
            raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
5323
5230
        if revision_id_list is None and revision is None:
5324
 
            raise errors.CommandError(
5325
 
                gettext('You must supply either --revision or a revision_id'))
 
5231
            raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
5326
5232
        b = WorkingTree.open_containing(directory)[0].branch
5327
 
        self.enter_context(b.lock_write())
 
5233
        self.add_cleanup(b.lock_write().unlock)
5328
5234
        return self._run(b, revision_id_list, revision)
5329
5235
 
5330
5236
    def _run(self, b, revision_id_list, revision):
5331
 
        from .repository import WriteGroup
 
5237
        import bzrlib.gpg as gpg
5332
5238
        gpg_strategy = gpg.GPGStrategy(b.get_config_stack())
5333
5239
        if revision_id_list is not None:
5334
 
            with WriteGroup(b.repository):
 
5240
            b.repository.start_write_group()
 
5241
            try:
5335
5242
                for revision_id in revision_id_list:
5336
 
                    revision_id = cache_utf8.encode(revision_id)
5337
5243
                    b.repository.sign_revision(revision_id, gpg_strategy)
 
5244
            except:
 
5245
                b.repository.abort_write_group()
 
5246
                raise
 
5247
            else:
 
5248
                b.repository.commit_write_group()
5338
5249
        elif revision is not None:
5339
5250
            if len(revision) == 1:
5340
5251
                revno, rev_id = revision[0].in_history(b)
5341
 
                with WriteGroup(b.repository):
 
5252
                b.repository.start_write_group()
 
5253
                try:
5342
5254
                    b.repository.sign_revision(rev_id, gpg_strategy)
 
5255
                except:
 
5256
                    b.repository.abort_write_group()
 
5257
                    raise
 
5258
                else:
 
5259
                    b.repository.commit_write_group()
5343
5260
            elif len(revision) == 2:
5344
5261
                # are they both on rh- if so we can walk between them
5345
5262
                # might be nice to have a range helper for arbitrary
5349
5266
                if to_revid is None:
5350
5267
                    to_revno = b.revno()
5351
5268
                if from_revno is None or to_revno is None:
5352
 
                    raise errors.CommandError(
5353
 
                        gettext('Cannot sign a range of non-revision-history revisions'))
5354
 
                with WriteGroup(b.repository):
 
5269
                    raise errors.BzrCommandError(gettext('Cannot sign a range of non-revision-history revisions'))
 
5270
                b.repository.start_write_group()
 
5271
                try:
5355
5272
                    for revno in range(from_revno, to_revno + 1):
5356
5273
                        b.repository.sign_revision(b.get_rev_id(revno),
5357
5274
                                                   gpg_strategy)
 
5275
                except:
 
5276
                    b.repository.abort_write_group()
 
5277
                    raise
 
5278
                else:
 
5279
                    b.repository.commit_write_group()
5358
5280
            else:
5359
 
                raise errors.CommandError(
5360
 
                    gettext('Please supply either one revision, or a range.'))
 
5281
                raise errors.BzrCommandError(gettext('Please supply either one revision, or a range.'))
5361
5282
 
5362
5283
 
5363
5284
class cmd_bind(Command):
5382
5303
            try:
5383
5304
                location = b.get_old_bound_location()
5384
5305
            except errors.UpgradeRequired:
5385
 
                raise errors.CommandError(
5386
 
                    gettext('No location supplied.  '
5387
 
                            'This format does not remember old locations.'))
 
5306
                raise errors.BzrCommandError(gettext('No location supplied.  '
 
5307
                    'This format does not remember old locations.'))
5388
5308
            else:
5389
5309
                if location is None:
5390
5310
                    if b.get_bound_location() is not None:
5391
 
                        raise errors.CommandError(
 
5311
                        raise errors.BzrCommandError(
5392
5312
                            gettext('Branch is already bound'))
5393
5313
                    else:
5394
 
                        raise errors.CommandError(
 
5314
                        raise errors.BzrCommandError(
5395
5315
                            gettext('No location supplied'
5396
5316
                                    ' and no previous location known'))
5397
5317
        b_other = Branch.open(location)
5398
5318
        try:
5399
5319
            b.bind(b_other)
5400
5320
        except errors.DivergedBranches:
5401
 
            raise errors.CommandError(
5402
 
                gettext('These branches have diverged.'
5403
 
                        ' Try merging, and then bind again.'))
 
5321
            raise errors.BzrCommandError(gettext('These branches have diverged.'
 
5322
                                         ' Try merging, and then bind again.'))
5404
5323
        if b.get_config().has_explicit_nickname():
5405
5324
            b.nick = b_other.nick
5406
5325
 
5419
5338
    def run(self, directory=u'.'):
5420
5339
        b, relpath = Branch.open_containing(directory)
5421
5340
        if not b.unbind():
5422
 
            raise errors.CommandError(gettext('Local branch is not bound'))
 
5341
            raise errors.BzrCommandError(gettext('Local branch is not bound'))
5423
5342
 
5424
5343
 
5425
5344
class cmd_uncommit(Command):
5430
5349
    remove anything.
5431
5350
 
5432
5351
    If --revision is specified, uncommit revisions to leave the branch at the
5433
 
    specified revision.  For example, "brz uncommit -r 15" will leave the
 
5352
    specified revision.  For example, "bzr uncommit -r 15" will leave the
5434
5353
    branch at revision 15.
5435
5354
 
5436
5355
    Uncommit leaves the working tree ready for a new commit.  The only change
5444
5363
    # information in shared branches as well.
5445
5364
    _see_also = ['commit']
5446
5365
    takes_options = ['verbose', 'revision',
5447
 
                     Option('dry-run', help='Don\'t actually make changes.'),
5448
 
                     Option('force', help='Say yes to all questions.'),
5449
 
                     Option('keep-tags',
5450
 
                            help='Keep tags that point to removed revisions.'),
5451
 
                     Option('local',
5452
 
                            help="Only remove the commits from the local "
5453
 
                            "branch when in a checkout."
5454
 
                            ),
5455
 
                     ]
 
5366
                    Option('dry-run', help='Don\'t actually make changes.'),
 
5367
                    Option('force', help='Say yes to all questions.'),
 
5368
                    Option('keep-tags',
 
5369
                           help='Keep tags that point to removed revisions.'),
 
5370
                    Option('local',
 
5371
                           help="Only remove the commits from the local branch"
 
5372
                                " when in a checkout."
 
5373
                           ),
 
5374
                    ]
5456
5375
    takes_args = ['location?']
5457
5376
    aliases = []
5458
5377
    encoding_type = 'replace'
5470
5389
            b = control.open_branch()
5471
5390
 
5472
5391
        if tree is not None:
5473
 
            self.enter_context(tree.lock_write())
 
5392
            self.add_cleanup(tree.lock_write().unlock)
5474
5393
        else:
5475
 
            self.enter_context(b.lock_write())
 
5394
            self.add_cleanup(b.lock_write().unlock)
5476
5395
        return self._run(b, tree, dry_run, verbose, revision, force,
5477
 
                         local, keep_tags, location)
 
5396
                         local, keep_tags)
5478
5397
 
5479
5398
    def _run(self, b, tree, dry_run, verbose, revision, force, local,
5480
 
             keep_tags, location):
5481
 
        from .log import log_formatter, show_log
5482
 
        from .uncommit import uncommit
 
5399
             keep_tags):
 
5400
        from bzrlib.log import log_formatter, show_log
 
5401
        from bzrlib.uncommit import uncommit
5483
5402
 
5484
5403
        last_revno, last_rev_id = b.last_revision_info()
5485
5404
 
5488
5407
            revno = last_revno
5489
5408
            rev_id = last_rev_id
5490
5409
        else:
5491
 
            # 'brz uncommit -r 10' actually means uncommit
 
5410
            # 'bzr uncommit -r 10' actually means uncommit
5492
5411
            # so that the final tree is at revno 10.
5493
 
            # but breezy.uncommit.uncommit() actually uncommits
 
5412
            # but bzrlib.uncommit.uncommit() actually uncommits
5494
5413
            # the revisions that are supplied.
5495
5414
            # So we need to offset it by one
5496
5415
            revno = revision[0].in_history(b).revno + 1
5514
5433
 
5515
5434
        if dry_run:
5516
5435
            self.outf.write(gettext('Dry-run, pretending to remove'
5517
 
                                    ' the above revisions.\n'))
 
5436
                            ' the above revisions.\n'))
5518
5437
        else:
5519
 
            self.outf.write(
5520
 
                gettext('The above revision(s) will be removed.\n'))
 
5438
            self.outf.write(gettext('The above revision(s) will be removed.\n'))
5521
5439
 
5522
5440
        if not force:
5523
5441
            if not ui.ui_factory.confirm_action(
5524
5442
                    gettext(u'Uncommit these revisions'),
5525
 
                    'breezy.builtins.uncommit',
 
5443
                    'bzrlib.builtins.uncommit',
5526
5444
                    {}):
5527
5445
                self.outf.write(gettext('Canceled\n'))
5528
5446
                return 0
5531
5449
               last_rev_id, rev_id)
5532
5450
        uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5533
5451
                 revno=revno, local=local, keep_tags=keep_tags)
5534
 
        if location != '.':
5535
 
            self.outf.write(
5536
 
                gettext('You can restore the old tip by running:\n'
5537
 
                        '  brz pull -d %s %s -r revid:%s\n')
5538
 
                % (location, location, last_rev_id.decode('utf-8')))
5539
 
        else:
5540
 
            self.outf.write(
5541
 
                gettext('You can restore the old tip by running:\n'
5542
 
                        '  brz pull . -r revid:%s\n')
5543
 
                % last_rev_id.decode('utf-8'))
 
5452
        self.outf.write(gettext('You can restore the old tip by running:\n'
 
5453
             '  bzr pull . -r revid:%s\n') % last_rev_id)
5544
5454
 
5545
5455
 
5546
5456
class cmd_break_lock(Command):
5552
5462
    CAUTION: Locks should only be broken when you are sure that the process
5553
5463
    holding the lock has been stopped.
5554
5464
 
5555
 
    You can get information on what locks are open via the 'brz info
 
5465
    You can get information on what locks are open via the 'bzr info
5556
5466
    [location]' command.
5557
5467
 
5558
5468
    :Examples:
5559
 
        brz break-lock
5560
 
        brz break-lock brz+ssh://example.com/brz/foo
5561
 
        brz break-lock --conf ~/.config/breezy
 
5469
        bzr break-lock
 
5470
        bzr break-lock bzr+ssh://example.com/bzr/foo
 
5471
        bzr break-lock --conf ~/.bazaar
5562
5472
    """
5563
5473
 
5564
5474
    takes_args = ['location?']
5566
5476
        Option('config',
5567
5477
               help='LOCATION is the directory where the config lock is.'),
5568
5478
        Option('force',
5569
 
               help='Do not ask for confirmation before breaking the lock.'),
 
5479
            help='Do not ask for confirmation before breaking the lock.'),
5570
5480
        ]
5571
5481
 
5572
5482
    def run(self, location=None, config=False, force=False):
5574
5484
            location = u'.'
5575
5485
        if force:
5576
5486
            ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
5577
 
                                                               None,
5578
 
                                                               {'breezy.lockdir.break': True})
 
5487
                None,
 
5488
                {'bzrlib.lockdir.break': True})
5579
5489
        if config:
5580
5490
            conf = _mod_config.LockableConfig(file_name=location)
5581
5491
            conf.break_lock()
5588
5498
 
5589
5499
 
5590
5500
class cmd_wait_until_signalled(Command):
5591
 
    __doc__ = """Test helper for test_start_and_stop_brz_subprocess_send_signal.
 
5501
    __doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
5592
5502
 
5593
5503
    This just prints a line to signal when it is ready, then blocks on stdin.
5594
5504
    """
5596
5506
    hidden = True
5597
5507
 
5598
5508
    def run(self):
5599
 
        self.outf.write("running\n")
5600
 
        self.outf.flush()
 
5509
        sys.stdout.write("running\n")
 
5510
        sys.stdout.flush()
5601
5511
        sys.stdin.readline()
5602
5512
 
5603
5513
 
5604
5514
class cmd_serve(Command):
5605
 
    __doc__ = """Run the brz server."""
 
5515
    __doc__ = """Run the bzr server."""
5606
5516
 
5607
5517
    aliases = ['server']
5608
5518
 
5610
5520
        Option('inet',
5611
5521
               help='Serve on stdin/out for use from inetd or sshd.'),
5612
5522
        RegistryOption('protocol',
5613
 
                       help="Protocol to serve.",
5614
 
                       lazy_registry=('breezy.transport',
5615
 
                                      'transport_server_registry'),
5616
 
                       value_switches=True),
 
5523
               help="Protocol to serve.",
 
5524
               lazy_registry=('bzrlib.transport', 'transport_server_registry'),
 
5525
               value_switches=True),
5617
5526
        Option('listen',
5618
 
               help='Listen for connections on nominated address.',
5619
 
               type=str),
 
5527
               help='Listen for connections on nominated address.', type=str),
5620
5528
        Option('port',
5621
5529
               help='Listen for connections on nominated port.  Passing 0 as '
5622
5530
                    'the port number will result in a dynamically allocated '
5623
5531
                    'port.  The default port depends on the protocol.',
5624
5532
               type=int),
5625
5533
        custom_help('directory',
5626
 
                    help='Serve contents of this directory.'),
 
5534
               help='Serve contents of this directory.'),
5627
5535
        Option('allow-writes',
5628
5536
               help='By default the server is a readonly server.  Supplying '
5629
5537
                    '--allow-writes enables write access to the contents of '
5630
 
                    'the served directory and below.  Note that ``brz serve`` '
 
5538
                    'the served directory and below.  Note that ``bzr serve`` '
5631
5539
                    'does not perform authentication, so unless some form of '
5632
5540
                    'external authentication is arranged supplying this '
5633
5541
                    'option leads to global uncontrolled write access to your '
5634
5542
                    'file system.'
5635
 
               ),
 
5543
                ),
5636
5544
        Option('client-timeout', type=float,
5637
5545
               help='Override the default idle client timeout (5min).'),
5638
5546
        ]
5639
5547
 
5640
5548
    def run(self, listen=None, port=None, inet=False, directory=None,
5641
5549
            allow_writes=False, protocol=None, client_timeout=None):
5642
 
        from . import location, transport
 
5550
        from bzrlib import transport
5643
5551
        if directory is None:
5644
 
            directory = osutils.getcwd()
 
5552
            directory = os.getcwd()
5645
5553
        if protocol is None:
5646
5554
            protocol = transport.transport_server_registry.get()
5647
 
        url = location.location_to_url(directory)
 
5555
        url = transport.location_to_url(directory)
5648
5556
        if not allow_writes:
5649
5557
            url = 'readonly+' + url
5650
5558
        t = transport.get_transport_from_url(url)
5657
5565
    This command requires the target tree to be in a rich-root format.
5658
5566
 
5659
5567
    The TREE argument should be an independent tree, inside another tree, but
5660
 
    not part of it.  (Such trees can be produced by "brz split", but also by
5661
 
    running "brz branch" with the target inside a tree.)
 
5568
    not part of it.  (Such trees can be produced by "bzr split", but also by
 
5569
    running "bzr branch" with the target inside a tree.)
5662
5570
 
5663
5571
    The result is a combined tree, with the subtree no longer an independent
5664
5572
    part.  This is marked as a merge of the subtree into the containing tree,
5668
5576
    _see_also = ['split']
5669
5577
    takes_args = ['tree']
5670
5578
    takes_options = [
5671
 
        Option('reference', help='Join by reference.', hidden=True),
5672
 
        ]
 
5579
            Option('reference', help='Join by reference.', hidden=True),
 
5580
            ]
5673
5581
 
5674
5582
    def run(self, tree, reference=False):
5675
 
        from breezy.mutabletree import BadReferenceTarget
5676
5583
        sub_tree = WorkingTree.open(tree)
5677
5584
        parent_dir = osutils.dirname(sub_tree.basedir)
5678
5585
        containing_tree = WorkingTree.open_containing(parent_dir)[0]
5679
5586
        repo = containing_tree.branch.repository
5680
5587
        if not repo.supports_rich_root():
5681
 
            raise errors.CommandError(gettext(
 
5588
            raise errors.BzrCommandError(gettext(
5682
5589
                "Can't join trees because %s doesn't support rich root data.\n"
5683
 
                "You can use brz upgrade on the repository.")
 
5590
                "You can use bzr upgrade on the repository.")
5684
5591
                % (repo,))
5685
5592
        if reference:
5686
5593
            try:
5687
5594
                containing_tree.add_reference(sub_tree)
5688
 
            except BadReferenceTarget as e:
 
5595
            except errors.BadReferenceTarget, e:
5689
5596
                # XXX: Would be better to just raise a nicely printable
5690
5597
                # exception from the real origin.  Also below.  mbp 20070306
5691
 
                raise errors.CommandError(
5692
 
                    gettext("Cannot join {0}.  {1}").format(tree, e.reason))
 
5598
                raise errors.BzrCommandError(
 
5599
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5693
5600
        else:
5694
5601
            try:
5695
5602
                containing_tree.subsume(sub_tree)
5696
 
            except errors.BadSubsumeSource as e:
5697
 
                raise errors.CommandError(
5698
 
                    gettext("Cannot join {0}.  {1}").format(tree, e.reason))
 
5603
            except errors.BadSubsumeSource, e:
 
5604
                raise errors.BzrCommandError(
 
5605
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5699
5606
 
5700
5607
 
5701
5608
class cmd_split(Command):
5715
5622
 
5716
5623
    def run(self, tree):
5717
5624
        containing_tree, subdir = WorkingTree.open_containing(tree)
5718
 
        if not containing_tree.is_versioned(subdir):
 
5625
        sub_id = containing_tree.path2id(subdir)
 
5626
        if sub_id is None:
5719
5627
            raise errors.NotVersionedError(subdir)
5720
5628
        try:
5721
 
            containing_tree.extract(subdir)
 
5629
            containing_tree.extract(sub_id)
5722
5630
        except errors.RootNotRich:
5723
5631
            raise errors.RichRootUpgradeRequired(containing_tree.branch.base)
5724
5632
 
5748
5656
 
5749
5657
    takes_options = [
5750
5658
        'directory',
5751
 
        RegistryOption.from_kwargs(
5752
 
            'patch-type',
 
5659
        RegistryOption.from_kwargs('patch-type',
5753
5660
            'The type of patch to include in the directive.',
5754
5661
            title='Patch type',
5755
5662
            value_switches=True,
5759
5666
            plain='No patch, just directive.'),
5760
5667
        Option('sign', help='GPG-sign the directive.'), 'revision',
5761
5668
        Option('mail-to', type=str,
5762
 
               help='Instead of printing the directive, email to this '
5763
 
               'address.'),
 
5669
            help='Instead of printing the directive, email to this address.'),
5764
5670
        Option('message', type=str, short_name='m',
5765
 
               help='Message to use when committing this merge.')
 
5671
            help='Message to use when committing this merge.')
5766
5672
        ]
5767
5673
 
5768
5674
    encoding_type = 'exact'
5770
5676
    def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
5771
5677
            sign=False, revision=None, mail_to=None, message=None,
5772
5678
            directory=u'.'):
5773
 
        from .revision import ensure_null, NULL_REVISION
 
5679
        from bzrlib.revision import ensure_null, NULL_REVISION
5774
5680
        include_patch, include_bundle = {
5775
5681
            'plain': (False, False),
5776
5682
            'diff': (True, False),
5786
5692
        if submit_branch is None:
5787
5693
            submit_branch = branch.get_parent()
5788
5694
        if submit_branch is None:
5789
 
            raise errors.CommandError(
5790
 
                gettext('No submit branch specified or known'))
 
5695
            raise errors.BzrCommandError(gettext('No submit branch specified or known'))
5791
5696
 
5792
5697
        stored_public_branch = branch.get_public_branch()
5793
5698
        if public_branch is None:
5796
5701
            # FIXME: Should be done only if we succeed ? -- vila 2012-01-03
5797
5702
            branch.set_public_branch(public_branch)
5798
5703
        if not include_bundle and public_branch is None:
5799
 
            raise errors.CommandError(
5800
 
                gettext('No public branch specified or known'))
 
5704
            raise errors.BzrCommandError(gettext('No public branch specified or'
 
5705
                                         ' known'))
5801
5706
        base_revision_id = None
5802
5707
        if revision is not None:
5803
5708
            if len(revision) > 2:
5804
 
                raise errors.CommandError(
5805
 
                    gettext('brz merge-directive takes '
5806
 
                            'at most two one revision identifiers'))
 
5709
                raise errors.BzrCommandError(gettext('bzr merge-directive takes '
 
5710
                    'at most two one revision identifiers'))
5807
5711
            revision_id = revision[-1].as_revision_id(branch)
5808
5712
            if len(revision) == 2:
5809
5713
                base_revision_id = revision[0].as_revision_id(branch)
5811
5715
            revision_id = branch.last_revision()
5812
5716
        revision_id = ensure_null(revision_id)
5813
5717
        if revision_id == NULL_REVISION:
5814
 
            raise errors.CommandError(gettext('No revisions to bundle.'))
 
5718
            raise errors.BzrCommandError(gettext('No revisions to bundle.'))
5815
5719
        directive = merge_directive.MergeDirective2.from_objects(
5816
5720
            branch.repository, revision_id, time.time(),
5817
5721
            osutils.local_time_offset(), submit_branch,
5842
5746
      directly from the merge directive, without retrieving data from a
5843
5747
      branch.
5844
5748
 
5845
 
    `brz send` creates a compact data set that, when applied using brz
5846
 
    merge, has the same effect as merging from the source branch.
5847
 
 
 
5749
    `bzr send` creates a compact data set that, when applied using bzr
 
5750
    merge, has the same effect as merging from the source branch.  
 
5751
    
5848
5752
    By default the merge directive is self-contained and can be applied to any
5849
5753
    branch containing submit_branch in its ancestory without needing access to
5850
5754
    the source branch.
5851
 
 
5852
 
    If --no-bundle is specified, then Breezy doesn't send the contents of the
 
5755
    
 
5756
    If --no-bundle is specified, then Bazaar doesn't send the contents of the
5853
5757
    revisions, but only a structured request to merge from the
5854
5758
    public_location.  In that case the public_branch is needed and it must be
5855
5759
    up-to-date and accessible to the recipient.  The public_branch is always
5867
5771
    omit the location to use the default.  To change the default, use
5868
5772
    --remember. The value will only be saved if the location can be accessed.
5869
5773
 
5870
 
    In order to calculate those changes, brz must analyse the submit branch.
 
5774
    In order to calculate those changes, bzr must analyse the submit branch.
5871
5775
    Therefore it is most efficient for the submit branch to be a local mirror.
5872
5776
    If a public location is known for the submit_branch, that location is used
5873
5777
    in the merge directive.
5880
5784
    If the preferred client can't be found (or used), your editor will be used.
5881
5785
 
5882
5786
    To use a specific mail program, set the mail_client configuration option.
5883
 
    Supported values for specific clients are "claws", "evolution", "kmail",
5884
 
    "mail.app" (MacOS X's Mail.app), "mutt", and "thunderbird"; generic options
5885
 
    are "default", "editor", "emacsclient", "mapi", and "xdg-email".  Plugins
5886
 
    may also add supported clients.
 
5787
    (For Thunderbird 1.5, this works around some bugs.)  Supported values for
 
5788
    specific clients are "claws", "evolution", "kmail", "mail.app" (MacOS X's
 
5789
    Mail.app), "mutt", and "thunderbird"; generic options are "default",
 
5790
    "editor", "emacsclient", "mapi", and "xdg-email".  Plugins may also add
 
5791
    supported clients.
5887
5792
 
5888
5793
    If mail is being sent, a to address is required.  This can be supplied
5889
5794
    either on the commandline, by setting the submit_to configuration
5890
5795
    option in the branch itself or the child_submit_to configuration option
5891
5796
    in the submit branch.
5892
5797
 
5893
 
    The merge directives created by brz send may be applied using brz merge or
5894
 
    brz pull by specifying a file containing a merge directive as the location.
5895
 
 
5896
 
    brz send makes extensive use of public locations to map local locations into
5897
 
    URLs that can be used by other people.  See `brz help configuration` to
5898
 
    set them, and use `brz info` to display them.
 
5798
    Two formats are currently supported: "4" uses revision bundle format 4 and
 
5799
    merge directive format 2.  It is significantly faster and smaller than
 
5800
    older formats.  It is compatible with Bazaar 0.19 and later.  It is the
 
5801
    default.  "0.9" uses revision bundle format 0.9 and merge directive
 
5802
    format 1.  It is compatible with Bazaar 0.12 - 0.18.
 
5803
 
 
5804
    The merge directives created by bzr send may be applied using bzr merge or
 
5805
    bzr pull by specifying a file containing a merge directive as the location.
 
5806
 
 
5807
    bzr send makes extensive use of public locations to map local locations into
 
5808
    URLs that can be used by other people.  See `bzr help configuration` to
 
5809
    set them, and use `bzr info` to display them.
5899
5810
    """
5900
5811
 
5901
5812
    encoding_type = 'exact'
5915
5826
               help='Branch to generate the submission from, '
5916
5827
               'rather than the one containing the working directory.',
5917
5828
               short_name='f',
5918
 
               type=str),
 
5829
               type=unicode),
5919
5830
        Option('output', short_name='o',
5920
5831
               help='Write merge directive to this file or directory; '
5921
5832
                    'use - for stdout.',
5922
 
               type=str),
 
5833
               type=unicode),
5923
5834
        Option('strict',
5924
5835
               help='Refuse to send if there are uncommitted changes in'
5925
5836
               ' the working tree, --no-strict disables the check.'),
5926
5837
        Option('mail-to', help='Mail the request to this address.',
5927
 
               type=str),
 
5838
               type=unicode),
5928
5839
        'revision',
5929
5840
        'message',
5930
 
        Option('body', help='Body for the email.', type=str),
 
5841
        Option('body', help='Body for the email.', type=unicode),
5931
5842
        RegistryOption('format',
5932
5843
                       help='Use the specified output format.',
5933
 
                       lazy_registry=('breezy.send', 'format_registry')),
 
5844
                       lazy_registry=('bzrlib.send', 'format_registry')),
5934
5845
        ]
5935
5846
 
5936
5847
    def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5937
5848
            no_patch=False, revision=None, remember=None, output=None,
5938
5849
            format=None, mail_to=None, message=None, body=None,
5939
5850
            strict=None, **kwargs):
5940
 
        from .send import send
 
5851
        from bzrlib.send import send
5941
5852
        return send(submit_branch, revision, public_branch, remember,
5942
5853
                    format, no_bundle, no_patch, output,
5943
5854
                    kwargs.get('from', '.'), mail_to, message, body,
5970
5881
    branch is used in the merge instructions.  This means that a local mirror
5971
5882
    can be used as your actual submit branch, once you have set public_branch
5972
5883
    for that mirror.
 
5884
 
 
5885
    Two formats are currently supported: "4" uses revision bundle format 4 and
 
5886
    merge directive format 2.  It is significantly faster and smaller than
 
5887
    older formats.  It is compatible with Bazaar 0.19 and later.  It is the
 
5888
    default.  "0.9" uses revision bundle format 0.9 and merge directive
 
5889
    format 1.  It is compatible with Bazaar 0.12 - 0.18.
5973
5890
    """
5974
5891
 
5975
5892
    takes_options = [
5983
5900
               help='Branch to generate the submission from, '
5984
5901
               'rather than the one containing the working directory.',
5985
5902
               short_name='f',
5986
 
               type=str),
 
5903
               type=unicode),
5987
5904
        Option('output', short_name='o', help='Write directive to this file.',
5988
 
               type=str),
 
5905
               type=unicode),
5989
5906
        Option('strict',
5990
5907
               help='Refuse to bundle revisions if there are uncommitted'
5991
5908
               ' changes in the working tree, --no-strict disables the check.'),
5992
5909
        'revision',
5993
5910
        RegistryOption('format',
5994
5911
                       help='Use the specified output format.',
5995
 
                       lazy_registry=('breezy.send', 'format_registry')),
 
5912
                       lazy_registry=('bzrlib.send', 'format_registry')),
5996
5913
        ]
5997
5914
    aliases = ['bundle']
5998
5915
 
6005
5922
            format=None, strict=None, **kwargs):
6006
5923
        if output is None:
6007
5924
            output = '-'
6008
 
        from .send import send
 
5925
        from bzrlib.send import send
6009
5926
        return send(submit_branch, revision, public_branch, remember,
6010
 
                    format, no_bundle, no_patch, output,
6011
 
                    kwargs.get('from', '.'), None, None, None,
6012
 
                    self.outf, strict=strict)
 
5927
                         format, no_bundle, no_patch, output,
 
5928
                         kwargs.get('from', '.'), None, None, None,
 
5929
                         self.outf, strict=strict)
6013
5930
 
6014
5931
 
6015
5932
class cmd_tag(Command):
6025
5942
    It is an error to give a tag name that already exists unless you pass
6026
5943
    --force, in which case the tag is moved to point to the new revision.
6027
5944
 
6028
 
    To rename a tag (change the name but keep it on the same revsion), run ``brz
6029
 
    tag new-name -r tag:old-name`` and then ``brz tag --delete oldname``.
 
5945
    To rename a tag (change the name but keep it on the same revsion), run ``bzr
 
5946
    tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
6030
5947
 
6031
 
    If no tag name is specified it will be determined through the
 
5948
    If no tag name is specified it will be determined through the 
6032
5949
    'automatic_tag_name' hook. This can e.g. be used to automatically tag
6033
 
    upstream releases by reading configure.ac. See ``brz help hooks`` for
 
5950
    upstream releases by reading configure.ac. See ``bzr help hooks`` for
6034
5951
    details.
6035
5952
    """
6036
5953
 
6038
5955
    takes_args = ['tag_name?']
6039
5956
    takes_options = [
6040
5957
        Option('delete',
6041
 
               help='Delete this tag rather than placing it.',
6042
 
               ),
 
5958
            help='Delete this tag rather than placing it.',
 
5959
            ),
6043
5960
        custom_help('directory',
6044
 
                    help='Branch in which to place the tag.'),
 
5961
            help='Branch in which to place the tag.'),
6045
5962
        Option('force',
6046
 
               help='Replace existing tags.',
6047
 
               ),
 
5963
            help='Replace existing tags.',
 
5964
            ),
6048
5965
        'revision',
6049
5966
        ]
6050
5967
 
6055
5972
            revision=None,
6056
5973
            ):
6057
5974
        branch, relpath = Branch.open_containing(directory)
6058
 
        self.enter_context(branch.lock_write())
 
5975
        self.add_cleanup(branch.lock_write().unlock)
6059
5976
        if delete:
6060
5977
            if tag_name is None:
6061
 
                raise errors.CommandError(
6062
 
                    gettext("No tag specified to delete."))
 
5978
                raise errors.BzrCommandError(gettext("No tag specified to delete."))
6063
5979
            branch.tags.delete_tag(tag_name)
6064
5980
            note(gettext('Deleted tag %s.') % tag_name)
6065
5981
        else:
6066
5982
            if revision:
6067
5983
                if len(revision) != 1:
6068
 
                    raise errors.CommandError(gettext(
 
5984
                    raise errors.BzrCommandError(gettext(
6069
5985
                        "Tags can only be placed on a single revision, "
6070
5986
                        "not on a range"))
6071
5987
                revision_id = revision[0].as_revision_id(branch)
6074
5990
            if tag_name is None:
6075
5991
                tag_name = branch.automatic_tag_name(revision_id)
6076
5992
                if tag_name is None:
6077
 
                    raise errors.CommandError(gettext(
 
5993
                    raise errors.BzrCommandError(gettext(
6078
5994
                        "Please specify a tag name."))
6079
5995
            try:
6080
5996
                existing_target = branch.tags.lookup_tag(tag_name)
6101
6017
    _see_also = ['tag']
6102
6018
    takes_options = [
6103
6019
        custom_help('directory',
6104
 
                    help='Branch whose tags should be displayed.'),
 
6020
            help='Branch whose tags should be displayed.'),
6105
6021
        RegistryOption('sort',
6106
 
                       'Sort tags by different criteria.', title='Sorting',
6107
 
                       lazy_registry=('breezy.tag', 'tag_sort_methods')
6108
 
                       ),
 
6022
            'Sort tags by different criteria.', title='Sorting',
 
6023
            lazy_registry=('bzrlib.tag', 'tag_sort_methods')
 
6024
            ),
6109
6025
        'show-ids',
6110
6026
        'revision',
6111
6027
    ]
6112
6028
 
6113
6029
    @display_command
6114
6030
    def run(self, directory='.', sort=None, show_ids=False, revision=None):
6115
 
        from .tag import tag_sort_methods
 
6031
        from bzrlib.tag import tag_sort_methods
6116
6032
        branch, relpath = Branch.open_containing(directory)
6117
6033
 
6118
 
        tags = list(branch.tags.get_tag_dict().items())
 
6034
        tags = branch.tags.get_tag_dict().items()
6119
6035
        if not tags:
6120
6036
            return
6121
6037
 
6122
 
        self.enter_context(branch.lock_read())
 
6038
        self.add_cleanup(branch.lock_read().unlock)
6123
6039
        if revision:
6124
6040
            # Restrict to the specified range
6125
6041
            tags = self._tags_for_range(branch, revision)
6140
6056
                    # which are not in this branch. Fail gracefully ...
6141
6057
                    revno = '?'
6142
6058
                tags[index] = (tag, revno)
6143
 
        else:
6144
 
            tags = [(tag, revid.decode('utf-8')) for (tag, revid) in tags]
6145
6059
        self.cleanup_now()
6146
6060
        for tag, revspec in tags:
6147
6061
            self.outf.write('%-20s %s\n' % (tag, revspec))
6148
6062
 
6149
6063
    def _tags_for_range(self, branch, revision):
 
6064
        range_valid = True
6150
6065
        rev1, rev2 = _get_revision_range(revision, branch, self.name())
6151
6066
        revid1, revid2 = rev1.rev_id, rev2.rev_id
6152
6067
        # _get_revision_range will always set revid2 if it's not specified.
6164
6079
        tagged_revids = branch.tags.get_reverse_tag_dict()
6165
6080
        found = []
6166
6081
        for r in branch.iter_merge_sorted_revisions(
6167
 
                start_revision_id=revid2, stop_revision_id=revid1,
6168
 
                stop_rule='include'):
 
6082
            start_revision_id=revid2, stop_revision_id=revid1,
 
6083
            stop_rule='include'):
6169
6084
            revid_tags = tagged_revids.get(r[0], None)
6170
6085
            if revid_tags:
6171
6086
                found.extend([(tag, r[0]) for tag in revid_tags])
6173
6088
 
6174
6089
 
6175
6090
class cmd_reconfigure(Command):
6176
 
    __doc__ = """Reconfigure the type of a brz directory.
 
6091
    __doc__ = """Reconfigure the type of a bzr directory.
6177
6092
 
6178
6093
    A target configuration must be specified.
6179
6094
 
6198
6113
            tree='Reconfigure to be an unbound branch with a working tree.',
6199
6114
            checkout='Reconfigure to be a bound branch with a working tree.',
6200
6115
            lightweight_checkout='Reconfigure to be a lightweight'
6201
 
            ' checkout (with no local history).',
 
6116
                ' checkout (with no local history).',
6202
6117
            ),
6203
6118
        RegistryOption.from_kwargs(
6204
6119
            'repository_type',
6206
6121
            help='Location fo the repository.',
6207
6122
            value_switches=True, enum_switch=False,
6208
6123
            standalone='Reconfigure to be a standalone branch '
6209
 
            '(i.e. stop using shared repository).',
 
6124
                '(i.e. stop using shared repository).',
6210
6125
            use_shared='Reconfigure to use a shared repository.',
6211
6126
            ),
6212
6127
        RegistryOption.from_kwargs(
6215
6130
            help='Whether new branches in the repository have trees.',
6216
6131
            value_switches=True, enum_switch=False,
6217
6132
            with_trees='Reconfigure repository to create '
6218
 
            'working trees on branches by default.',
 
6133
                'working trees on branches by default.',
6219
6134
            with_no_trees='Reconfigure repository to not create '
6220
 
            'working trees on branches by default.'
 
6135
                'working trees on branches by default.'
6221
6136
            ),
6222
6137
        Option('bind-to', help='Branch to bind checkout to.', type=str),
6223
6138
        Option('force',
6224
 
               help='Perform reconfiguration even if local changes'
6225
 
               ' will be lost.'),
 
6139
            help='Perform reconfiguration even if local changes'
 
6140
            ' will be lost.'),
6226
6141
        Option('stacked-on',
6227
 
               help='Reconfigure a branch to be stacked on another branch.',
6228
 
               type=str,
6229
 
               ),
 
6142
            help='Reconfigure a branch to be stacked on another branch.',
 
6143
            type=unicode,
 
6144
            ),
6230
6145
        Option('unstacked',
6231
 
               help='Reconfigure a branch to be unstacked.  This '
6232
 
               'may require copying substantial data into it.',
6233
 
               ),
 
6146
            help='Reconfigure a branch to be unstacked.  This '
 
6147
                'may require copying substantial data into it.',
 
6148
            ),
6234
6149
        ]
6235
6150
 
6236
6151
    def run(self, location=None, bind_to=None, force=False,
6238
6153
            stacked_on=None, unstacked=None):
6239
6154
        directory = controldir.ControlDir.open(location)
6240
6155
        if stacked_on and unstacked:
6241
 
            raise errors.CommandError(
6242
 
                gettext("Can't use both --stacked-on and --unstacked"))
 
6156
            raise errors.BzrCommandError(gettext("Can't use both --stacked-on and --unstacked"))
6243
6157
        elif stacked_on is not None:
6244
6158
            reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
6245
6159
        elif unstacked:
6249
6163
        # to ban it.
6250
6164
        if (tree_type is None and
6251
6165
            repository_type is None and
6252
 
                repository_trees is None):
 
6166
            repository_trees is None):
6253
6167
            if stacked_on or unstacked:
6254
6168
                return
6255
6169
            else:
6256
 
                raise errors.CommandError(gettext('No target configuration '
6257
 
                                                     'specified'))
 
6170
                raise errors.BzrCommandError(gettext('No target configuration '
 
6171
                    'specified'))
6258
6172
        reconfiguration = None
6259
6173
        if tree_type == 'branch':
6260
6174
            reconfiguration = reconfigure.Reconfigure.to_branch(directory)
6313
6227
    takes_args = ['to_location?']
6314
6228
    takes_options = ['directory',
6315
6229
                     Option('force',
6316
 
                            help='Switch even if local commits will be lost.'),
 
6230
                        help='Switch even if local commits will be lost.'),
6317
6231
                     'revision',
6318
6232
                     Option('create-branch', short_name='b',
6319
 
                            help='Create the target branch from this one before'
6320
 
                            ' switching to it.'),
 
6233
                        help='Create the target branch from this one before'
 
6234
                             ' switching to it.'),
6321
6235
                     Option('store',
6322
 
                            help='Store and restore uncommitted changes in the'
6323
 
                            ' branch.'),
6324
 
                     ]
 
6236
                        help='Store and restore uncommitted changes in the'
 
6237
                             ' branch.'),
 
6238
                    ]
6325
6239
 
6326
6240
    def run(self, to_location=None, force=False, create_branch=False,
6327
6241
            revision=None, directory=u'.', store=False):
6328
 
        from . import switch
 
6242
        from bzrlib import switch
6329
6243
        tree_location = directory
6330
6244
        revision = _get_one_revision('switch', revision)
6331
 
        control_dir = controldir.ControlDir.open_containing(tree_location)[0]
6332
 
        possible_transports = [control_dir.root_transport]
 
6245
        possible_transports = []
 
6246
        control_dir = controldir.ControlDir.open_containing(tree_location,
 
6247
            possible_transports=possible_transports)[0]
6333
6248
        if to_location is None:
6334
6249
            if revision is None:
6335
 
                raise errors.CommandError(gettext('You must supply either a'
6336
 
                                                     ' revision or a location'))
 
6250
                raise errors.BzrCommandError(gettext('You must supply either a'
 
6251
                                             ' revision or a location'))
6337
6252
            to_location = tree_location
6338
6253
        try:
6339
6254
            branch = control_dir.open_branch(
6342
6257
        except errors.NotBranchError:
6343
6258
            branch = None
6344
6259
            had_explicit_nick = False
6345
 
        else:
6346
 
            possible_transports.append(branch.user_transport)
6347
6260
        if create_branch:
6348
6261
            if branch is None:
6349
 
                raise errors.CommandError(
 
6262
                raise errors.BzrCommandError(
6350
6263
                    gettext('cannot create branch without source branch'))
6351
 
            to_location = lookup_new_sibling_branch(
6352
 
                control_dir, to_location,
6353
 
                possible_transports=possible_transports)
6354
 
            if revision is not None:
6355
 
                revision = revision.as_revision_id(branch)
6356
 
            to_branch = branch.controldir.sprout(
6357
 
                to_location,
6358
 
                possible_transports=possible_transports,
6359
 
                revision_id=revision,
6360
 
                source_branch=branch).open_branch()
 
6264
            to_location = lookup_new_sibling_branch(control_dir, to_location,
 
6265
                 possible_transports=possible_transports)
 
6266
            to_branch = branch.bzrdir.sprout(to_location,
 
6267
                 possible_transports=possible_transports,
 
6268
                 source_branch=branch).open_branch()
6361
6269
        else:
6362
6270
            try:
6363
 
                to_branch = Branch.open(
6364
 
                    to_location, possible_transports=possible_transports)
 
6271
                to_branch = Branch.open(to_location,
 
6272
                    possible_transports=possible_transports)
6365
6273
            except errors.NotBranchError:
6366
 
                to_branch = open_sibling_branch(
6367
 
                    control_dir, to_location,
 
6274
                to_branch = open_sibling_branch(control_dir, to_location,
6368
6275
                    possible_transports=possible_transports)
6369
 
            if revision is not None:
6370
 
                revision = revision.as_revision_id(to_branch)
6371
 
        possible_transports.append(to_branch.user_transport)
6372
 
        try:
6373
 
            switch.switch(control_dir, to_branch, force, revision_id=revision,
6374
 
                          store_uncommitted=store,
6375
 
                          possible_transports=possible_transports)
6376
 
        except controldir.BranchReferenceLoop:
6377
 
            raise errors.CommandError(
6378
 
                gettext('switching would create a branch reference loop. '
6379
 
                        'Use the "bzr up" command to switch to a '
6380
 
                        'different revision.'))
 
6276
        if revision is not None:
 
6277
            revision = revision.as_revision_id(to_branch)
 
6278
        switch.switch(control_dir, to_branch, force, revision_id=revision,
 
6279
                      store_uncommitted=store)
6381
6280
        if had_explicit_nick:
6382
 
            branch = control_dir.open_branch()  # get the new branch!
 
6281
            branch = control_dir.open_branch() #get the new branch!
6383
6282
            branch.nick = to_branch.nick
6384
 
        if to_branch.name:
6385
 
            if to_branch.controldir.control_url != control_dir.control_url:
6386
 
                note(gettext('Switched to branch %s at %s'),
6387
 
                     to_branch.name, urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6388
 
            else:
6389
 
                note(gettext('Switched to branch %s'), to_branch.name)
6390
 
        else:
6391
 
            note(gettext('Switched to branch at %s'),
6392
 
                 urlutils.unescape_for_display(to_branch.base, 'utf-8'))
 
6283
        note(gettext('Switched to branch: %s'),
 
6284
            urlutils.unescape_for_display(to_branch.base, 'utf-8'))
 
6285
 
6393
6286
 
6394
6287
 
6395
6288
class cmd_view(Command):
6415
6308
    :Examples:
6416
6309
      To define the current view::
6417
6310
 
6418
 
        brz view file1 dir1 ...
 
6311
        bzr view file1 dir1 ...
6419
6312
 
6420
6313
      To list the current view::
6421
6314
 
6422
 
        brz view
 
6315
        bzr view
6423
6316
 
6424
6317
      To delete the current view::
6425
6318
 
6426
 
        brz view --delete
 
6319
        bzr view --delete
6427
6320
 
6428
6321
      To disable the current view without deleting it::
6429
6322
 
6430
 
        brz view --switch off
 
6323
        bzr view --switch off
6431
6324
 
6432
6325
      To define a named view and switch to it::
6433
6326
 
6434
 
        brz view --name view-name file1 dir1 ...
 
6327
        bzr view --name view-name file1 dir1 ...
6435
6328
 
6436
6329
      To list a named view::
6437
6330
 
6438
 
        brz view --name view-name
 
6331
        bzr view --name view-name
6439
6332
 
6440
6333
      To delete a named view::
6441
6334
 
6442
 
        brz view --name view-name --delete
 
6335
        bzr view --name view-name --delete
6443
6336
 
6444
6337
      To switch to a named view::
6445
6338
 
6446
 
        brz view --switch view-name
 
6339
        bzr view --switch view-name
6447
6340
 
6448
6341
      To list all views defined::
6449
6342
 
6450
 
        brz view --all
 
6343
        bzr view --all
6451
6344
 
6452
6345
      To delete all views::
6453
6346
 
6454
 
        brz view --delete --all
 
6347
        bzr view --delete --all
6455
6348
    """
6456
6349
 
6457
6350
    _see_also = []
6458
6351
    takes_args = ['file*']
6459
6352
    takes_options = [
6460
6353
        Option('all',
6461
 
               help='Apply list or delete action to all views.',
6462
 
               ),
 
6354
            help='Apply list or delete action to all views.',
 
6355
            ),
6463
6356
        Option('delete',
6464
 
               help='Delete the view.',
6465
 
               ),
 
6357
            help='Delete the view.',
 
6358
            ),
6466
6359
        Option('name',
6467
 
               help='Name of the view to define, list or delete.',
6468
 
               type=str,
6469
 
               ),
 
6360
            help='Name of the view to define, list or delete.',
 
6361
            type=unicode,
 
6362
            ),
6470
6363
        Option('switch',
6471
 
               help='Name of the view to switch to.',
6472
 
               type=str,
6473
 
               ),
 
6364
            help='Name of the view to switch to.',
 
6365
            type=unicode,
 
6366
            ),
6474
6367
        ]
6475
6368
 
6476
6369
    def run(self, file_list,
6480
6373
            switch=None,
6481
6374
            ):
6482
6375
        tree, file_list = WorkingTree.open_containing_paths(file_list,
6483
 
                                                            apply_view=False)
 
6376
            apply_view=False)
6484
6377
        current_view, view_dict = tree.views.get_view_info()
6485
6378
        if name is None:
6486
6379
            name = current_view
6487
6380
        if delete:
6488
6381
            if file_list:
6489
 
                raise errors.CommandError(gettext(
 
6382
                raise errors.BzrCommandError(gettext(
6490
6383
                    "Both --delete and a file list specified"))
6491
6384
            elif switch:
6492
 
                raise errors.CommandError(gettext(
 
6385
                raise errors.BzrCommandError(gettext(
6493
6386
                    "Both --delete and --switch specified"))
6494
6387
            elif all:
6495
6388
                tree.views.set_view_info(None, {})
6496
6389
                self.outf.write(gettext("Deleted all views.\n"))
6497
6390
            elif name is None:
6498
 
                raise errors.CommandError(
6499
 
                    gettext("No current view to delete"))
 
6391
                raise errors.BzrCommandError(gettext("No current view to delete"))
6500
6392
            else:
6501
6393
                tree.views.delete_view(name)
6502
6394
                self.outf.write(gettext("Deleted '%s' view.\n") % name)
6503
6395
        elif switch:
6504
6396
            if file_list:
6505
 
                raise errors.CommandError(gettext(
 
6397
                raise errors.BzrCommandError(gettext(
6506
6398
                    "Both --switch and a file list specified"))
6507
6399
            elif all:
6508
 
                raise errors.CommandError(gettext(
 
6400
                raise errors.BzrCommandError(gettext(
6509
6401
                    "Both --switch and --all specified"))
6510
6402
            elif switch == 'off':
6511
6403
                if current_view is None:
6512
 
                    raise errors.CommandError(
6513
 
                        gettext("No current view to disable"))
 
6404
                    raise errors.BzrCommandError(gettext("No current view to disable"))
6514
6405
                tree.views.set_view_info(None, view_dict)
6515
 
                self.outf.write(gettext("Disabled '%s' view.\n") %
6516
 
                                (current_view))
 
6406
                self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
6517
6407
            else:
6518
6408
                tree.views.set_view_info(switch, view_dict)
6519
6409
                view_str = views.view_display_str(tree.views.lookup_view())
6520
 
                self.outf.write(
6521
 
                    gettext("Using '{0}' view: {1}\n").format(switch, view_str))
 
6410
                self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
6522
6411
        elif all:
6523
6412
            if view_dict:
6524
6413
                self.outf.write(gettext('Views defined:\n'))
6536
6425
                # No name given and no current view set
6537
6426
                name = 'my'
6538
6427
            elif name == 'off':
6539
 
                raise errors.CommandError(gettext(
 
6428
                raise errors.BzrCommandError(gettext(
6540
6429
                    "Cannot change the 'off' pseudo view"))
6541
6430
            tree.views.set_view(name, sorted(file_list))
6542
6431
            view_str = views.view_display_str(tree.views.lookup_view())
6543
 
            self.outf.write(
6544
 
                gettext("Using '{0}' view: {1}\n").format(name, view_str))
 
6432
            self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
6545
6433
        else:
6546
6434
            # list the files
6547
6435
            if name is None:
6549
6437
                self.outf.write(gettext('No current view.\n'))
6550
6438
            else:
6551
6439
                view_str = views.view_display_str(tree.views.lookup_view(name))
6552
 
                self.outf.write(
6553
 
                    gettext("'{0}' view is: {1}\n").format(name, view_str))
 
6440
                self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
6554
6441
 
6555
6442
 
6556
6443
class cmd_hooks(Command):
6576
6463
class cmd_remove_branch(Command):
6577
6464
    __doc__ = """Remove a branch.
6578
6465
 
6579
 
    This will remove the branch from the specified location but
 
6466
    This will remove the branch from the specified location but 
6580
6467
    will keep any working tree or repository in place.
6581
6468
 
6582
6469
    :Examples:
6583
6470
 
6584
6471
      Remove the branch at repo/trunk::
6585
6472
 
6586
 
        brz remove-branch repo/trunk
 
6473
        bzr remove-branch repo/trunk
6587
6474
 
6588
6475
    """
6589
6476
 
6590
6477
    takes_args = ["location?"]
6591
6478
 
6592
6479
    takes_options = ['directory',
6593
 
                     Option('force', help='Remove branch even if it is the active branch.')]
 
6480
        Option('force', help='Remove branch even if it is the active branch.')]
6594
6481
 
6595
6482
    aliases = ["rmbranch"]
6596
6483
 
6597
6484
    def run(self, directory=None, location=None, force=False):
6598
6485
        br = open_nearby_branch(near=directory, location=location)
6599
 
        if not force and br.controldir.has_workingtree():
 
6486
        if not force and br.bzrdir.has_workingtree():
6600
6487
            try:
6601
 
                active_branch = br.controldir.open_branch(name="")
 
6488
                active_branch = br.bzrdir.open_branch(name="")
6602
6489
            except errors.NotBranchError:
6603
6490
                active_branch = None
6604
6491
            if (active_branch is not None and
6605
 
                    br.control_url == active_branch.control_url):
6606
 
                raise errors.CommandError(
 
6492
                br.control_url == active_branch.control_url):
 
6493
                raise errors.BzrCommandError(
6607
6494
                    gettext("Branch is active. Use --force to remove it."))
6608
 
        br.controldir.destroy_branch(br.name)
 
6495
        br.bzrdir.destroy_branch(br.name)
6609
6496
 
6610
6497
 
6611
6498
class cmd_shelve(Command):
6636
6523
    editor program to decide what the file remaining in the working copy
6637
6524
    should look like.  To do this, add the configuration option
6638
6525
 
6639
 
        change_editor = PROGRAM {new_path} {old_path}
 
6526
        change_editor = PROGRAM @new_path @old_path
6640
6527
 
6641
 
    where {new_path} is replaced with the path of the new version of the
6642
 
    file and {old_path} is replaced with the path of the old version of
6643
 
    the file.  The PROGRAM should save the new file with the desired
 
6528
    where @new_path is replaced with the path of the new version of the 
 
6529
    file and @old_path is replaced with the path of the old version of 
 
6530
    the file.  The PROGRAM should save the new file with the desired 
6644
6531
    contents of the file in the working tree.
6645
 
 
 
6532
        
6646
6533
    """
6647
6534
 
6648
6535
    takes_args = ['file*']
6653
6540
        Option('all', help='Shelve all changes.'),
6654
6541
        'message',
6655
6542
        RegistryOption('writer', 'Method to use for writing diffs.',
6656
 
                       breezy.option.diff_writer_registry,
 
6543
                       bzrlib.option.diff_writer_registry,
6657
6544
                       value_switches=True, enum_switch=False),
6658
6545
 
6659
6546
        Option('list', help='List shelved changes.'),
6666
6553
            writer=None, list=False, destroy=False, directory=None):
6667
6554
        if list:
6668
6555
            return self.run_for_list(directory=directory)
6669
 
        from .shelf_ui import Shelver
 
6556
        from bzrlib.shelf_ui import Shelver
6670
6557
        if writer is None:
6671
 
            writer = breezy.option.diff_writer_registry.get()
 
6558
            writer = bzrlib.option.diff_writer_registry.get()
6672
6559
        try:
6673
 
            shelver = Shelver.from_args(writer(self.outf), revision, all,
6674
 
                                        file_list, message, destroy=destroy, directory=directory)
 
6560
            shelver = Shelver.from_args(writer(sys.stdout), revision, all,
 
6561
                file_list, message, destroy=destroy, directory=directory)
6675
6562
            try:
6676
6563
                shelver.run()
6677
6564
            finally:
6683
6570
        if directory is None:
6684
6571
            directory = u'.'
6685
6572
        tree = WorkingTree.open_containing(directory)[0]
6686
 
        self.enter_context(tree.lock_read())
 
6573
        self.add_cleanup(tree.lock_read().unlock)
6687
6574
        manager = tree.get_shelf_manager()
6688
6575
        shelves = manager.active_shelves()
6689
6576
        if len(shelves) == 0:
6690
6577
            note(gettext('No shelved changes.'))
6691
6578
            return 0
6692
6579
        for shelf_id in reversed(shelves):
6693
 
            message = manager.get_metadata(shelf_id).get(b'message')
 
6580
            message = manager.get_metadata(shelf_id).get('message')
6694
6581
            if message is None:
6695
6582
                message = '<no message>'
6696
6583
            self.outf.write('%3d: %s\n' % (shelf_id, message))
6722
6609
    _see_also = ['shelve']
6723
6610
 
6724
6611
    def run(self, shelf_id=None, action='apply', directory=u'.'):
6725
 
        from .shelf_ui import Unshelver
 
6612
        from bzrlib.shelf_ui import Unshelver
6726
6613
        unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
6727
6614
        try:
6728
6615
            unshelver.run()
6736
6623
    By default, only unknown files, not ignored files, are deleted.  Versioned
6737
6624
    files are never deleted.
6738
6625
 
6739
 
    Another class is 'detritus', which includes files emitted by brz during
 
6626
    Another class is 'detritus', which includes files emitted by bzr during
6740
6627
    normal operations and selftests.  (The value of these files decreases with
6741
6628
    time.)
6742
6629
 
6750
6637
                     Option('detritus', help='Delete conflict files, merge and revert'
6751
6638
                            ' backups, and failed selftest dirs.'),
6752
6639
                     Option('unknown',
6753
 
                            help='Delete files unknown to brz (default).'),
 
6640
                            help='Delete files unknown to bzr (default).'),
6754
6641
                     Option('dry-run', help='Show files to delete instead of'
6755
6642
                            ' deleting them.'),
6756
6643
                     Option('force', help='Do not prompt before deleting.')]
6757
 
 
6758
6644
    def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6759
6645
            force=False, directory=u'.'):
6760
 
        from .clean_tree import clean_tree
 
6646
        from bzrlib.clean_tree import clean_tree
6761
6647
        if not (unknown or ignored or detritus):
6762
6648
            unknown = True
6763
6649
        if dry_run:
6777
6663
    hidden = True
6778
6664
 
6779
6665
    takes_args = ['path?', 'location?']
6780
 
    takes_options = [
6781
 
        'directory',
6782
 
        Option('force-unversioned',
6783
 
               help='Set reference even if path is not versioned.'),
6784
 
        ]
6785
6666
 
6786
 
    def run(self, path=None, directory='.', location=None, force_unversioned=False):
6787
 
        tree, branch, relpath = (
6788
 
            controldir.ControlDir.open_containing_tree_or_branch(directory))
 
6667
    def run(self, path=None, location=None):
 
6668
        branchdir = '.'
 
6669
        if path is not None:
 
6670
            branchdir = path
 
6671
        tree, branch, relpath =(
 
6672
            controldir.ControlDir.open_containing_tree_or_branch(branchdir))
 
6673
        if path is not None:
 
6674
            path = relpath
6789
6675
        if tree is None:
6790
6676
            tree = branch.basis_tree()
6791
6677
        if path is None:
6792
 
            with tree.lock_read():
6793
 
                info = [
6794
 
                    (path, tree.get_reference_info(path, branch))
6795
 
                    for path in tree.iter_references()]
6796
 
                self._display_reference_info(tree, branch, info)
 
6678
            info = branch._get_all_reference_info().iteritems()
 
6679
            self._display_reference_info(tree, branch, info)
6797
6680
        else:
6798
 
            if not tree.is_versioned(path) and not force_unversioned:
 
6681
            file_id = tree.path2id(path)
 
6682
            if file_id is None:
6799
6683
                raise errors.NotVersionedError(path)
6800
6684
            if location is None:
6801
 
                info = [(path, tree.get_reference_info(path, branch))]
 
6685
                info = [(file_id, branch.get_reference_info(file_id))]
6802
6686
                self._display_reference_info(tree, branch, info)
6803
6687
            else:
6804
 
                tree.set_reference_info(path, location)
 
6688
                branch.set_reference_info(file_id, path, location)
6805
6689
 
6806
6690
    def _display_reference_info(self, tree, branch, info):
6807
6691
        ref_list = []
6808
 
        for path, location in info:
 
6692
        for file_id, (path, location) in info:
 
6693
            try:
 
6694
                path = tree.id2path(file_id)
 
6695
            except errors.NoSuchId:
 
6696
                pass
6809
6697
            ref_list.append((path, location))
6810
6698
        for path, location in sorted(ref_list):
6811
6699
            self.outf.write('%s %s\n' % (path, location))
6815
6703
    __doc__ = """Export command helps and error messages in po format."""
6816
6704
 
6817
6705
    hidden = True
6818
 
    takes_options = [Option('plugin',
6819
 
                            help='Export help text from named command '
 
6706
    takes_options = [Option('plugin', 
 
6707
                            help='Export help text from named command '\
6820
6708
                                 '(defaults to all built in commands).',
6821
6709
                            type=str),
6822
6710
                     Option('include-duplicates',
6823
6711
                            help='Output multiple copies of the same msgid '
6824
6712
                                 'string if it appears more than once.'),
6825
 
                     ]
 
6713
                            ]
6826
6714
 
6827
6715
    def run(self, plugin=None, include_duplicates=False):
6828
 
        from .export_pot import export_pot
 
6716
        from bzrlib.export_pot import export_pot
6829
6717
        export_pot(self.outf, plugin, include_duplicates)
6830
6718
 
6831
6719
 
6832
 
class cmd_import(Command):
6833
 
    __doc__ = """Import sources from a directory, tarball or zip file
6834
 
 
6835
 
    This command will import a directory, tarball or zip file into a bzr
6836
 
    tree, replacing any versioned files already present.  If a directory is
6837
 
    specified, it is used as the target.  If the directory does not exist, or
6838
 
    is not versioned, it is created.
6839
 
 
6840
 
    Tarballs may be gzip or bzip2 compressed.  This is autodetected.
6841
 
 
6842
 
    If the tarball or zip has a single root directory, that directory is
6843
 
    stripped when extracting the tarball.  This is not done for directories.
6844
 
    """
6845
 
 
6846
 
    takes_args = ['source', 'tree?']
6847
 
 
6848
 
    def run(self, source, tree=None):
6849
 
        from .upstream_import import do_import
6850
 
        do_import(source, tree)
6851
 
 
6852
 
 
6853
 
class cmd_link_tree(Command):
6854
 
    __doc__ = """Hardlink matching files to another tree.
6855
 
 
6856
 
    Only files with identical content and execute bit will be linked.
6857
 
    """
6858
 
 
6859
 
    takes_args = ['location']
6860
 
 
6861
 
    def run(self, location):
6862
 
        from .transform import link_tree
6863
 
        target_tree = WorkingTree.open_containing(".")[0]
6864
 
        source_tree = WorkingTree.open(location)
6865
 
        with target_tree.lock_write(), source_tree.lock_read():
6866
 
            link_tree(target_tree, source_tree)
6867
 
 
6868
 
 
6869
 
class cmd_fetch_ghosts(Command):
6870
 
    __doc__ = """Attempt to retrieve ghosts from another branch.
6871
 
 
6872
 
    If the other branch is not supplied, the last-pulled branch is used.
6873
 
    """
6874
 
 
6875
 
    hidden = True
6876
 
    aliases = ['fetch-missing']
6877
 
    takes_args = ['branch?']
6878
 
    takes_options = [Option('no-fix', help="Skip additional synchonization.")]
6879
 
 
6880
 
    def run(self, branch=None, no_fix=False):
6881
 
        from .fetch_ghosts import GhostFetcher
6882
 
        installed, failed = GhostFetcher.from_cmdline(branch).run()
6883
 
        if len(installed) > 0:
6884
 
            self.outf.write("Installed:\n")
6885
 
            for rev in installed:
6886
 
                self.outf.write(rev.decode('utf-8') + "\n")
6887
 
        if len(failed) > 0:
6888
 
            self.outf.write("Still missing:\n")
6889
 
            for rev in failed:
6890
 
                self.outf.write(rev.decode('utf-8') + "\n")
6891
 
        if not no_fix and len(installed) > 0:
6892
 
            cmd_reconcile().run(".")
6893
 
 
6894
 
 
6895
 
class cmd_grep(Command):
6896
 
    """Print lines matching PATTERN for specified files and revisions.
6897
 
 
6898
 
    This command searches the specified files and revisions for a given
6899
 
    pattern.  The pattern is specified as a Python regular expressions[1].
6900
 
 
6901
 
    If the file name is not specified, the revisions starting with the
6902
 
    current directory are searched recursively. If the revision number is
6903
 
    not specified, the working copy is searched. To search the last committed
6904
 
    revision, use the '-r -1' or '-r last:1' option.
6905
 
 
6906
 
    Unversioned files are not searched unless explicitly specified on the
6907
 
    command line. Unversioned directores are not searched.
6908
 
 
6909
 
    When searching a pattern, the output is shown in the 'filepath:string'
6910
 
    format. If a revision is explicitly searched, the output is shown as
6911
 
    'filepath~N:string', where N is the revision number.
6912
 
 
6913
 
    --include and --exclude options can be used to search only (or exclude
6914
 
    from search) files with base name matches the specified Unix style GLOB
6915
 
    pattern.  The GLOB pattern an use *, ?, and [...] as wildcards, and \\
6916
 
    to quote wildcard or backslash character literally. Note that the glob
6917
 
    pattern is not a regular expression.
6918
 
 
6919
 
    [1] http://docs.python.org/library/re.html#regular-expression-syntax
6920
 
    """
6921
 
 
6922
 
    encoding_type = 'replace'
6923
 
    takes_args = ['pattern', 'path*']
6924
 
    takes_options = [
6925
 
        'verbose',
6926
 
        'revision',
6927
 
        Option('color', type=str, argname='when',
6928
 
               help='Show match in color. WHEN is never, always or auto.'),
6929
 
        Option('diff', short_name='p',
6930
 
               help='Grep for pattern in changeset for each revision.'),
6931
 
        ListOption('exclude', type=str, argname='glob', short_name='X',
6932
 
                   help="Skip files whose base name matches GLOB."),
6933
 
        ListOption('include', type=str, argname='glob', short_name='I',
6934
 
                   help="Search only files whose base name matches GLOB."),
6935
 
        Option('files-with-matches', short_name='l',
6936
 
               help='Print only the name of each input file in '
6937
 
               'which PATTERN is found.'),
6938
 
        Option('files-without-match', short_name='L',
6939
 
               help='Print only the name of each input file in '
6940
 
               'which PATTERN is not found.'),
6941
 
        Option('fixed-string', short_name='F',
6942
 
               help='Interpret PATTERN is a single fixed string (not regex).'),
6943
 
        Option('from-root',
6944
 
               help='Search for pattern starting from the root of the branch. '
6945
 
               '(implies --recursive)'),
6946
 
        Option('ignore-case', short_name='i',
6947
 
               help='Ignore case distinctions while matching.'),
6948
 
        Option('levels',
6949
 
               help='Number of levels to display - 0 for all, 1 for collapsed '
6950
 
               '(1 is default).',
6951
 
               argname='N',
6952
 
               type=_parse_levels),
6953
 
        Option('line-number', short_name='n',
6954
 
               help='Show 1-based line number.'),
6955
 
        Option('no-recursive',
6956
 
               help="Don't recurse into subdirectories. (default is --recursive)"),
6957
 
        Option('null', short_name='Z',
6958
 
               help='Write an ASCII NUL (\\0) separator '
6959
 
               'between output lines rather than a newline.'),
6960
 
        ]
6961
 
 
6962
 
    @display_command
6963
 
    def run(self, verbose=False, ignore_case=False, no_recursive=False,
6964
 
            from_root=False, null=False, levels=None, line_number=False,
6965
 
            path_list=None, revision=None, pattern=None, include=None,
6966
 
            exclude=None, fixed_string=False, files_with_matches=False,
6967
 
            files_without_match=False, color=None, diff=False):
6968
 
        from breezy import _termcolor
6969
 
        from . import grep
6970
 
        import re
6971
 
        if path_list is None:
6972
 
            path_list = ['.']
6973
 
        else:
6974
 
            if from_root:
6975
 
                raise errors.CommandError(
6976
 
                    'cannot specify both --from-root and PATH.')
6977
 
 
6978
 
        if files_with_matches and files_without_match:
6979
 
            raise errors.CommandError(
6980
 
                'cannot specify both '
6981
 
                '-l/--files-with-matches and -L/--files-without-matches.')
6982
 
 
6983
 
        global_config = _mod_config.GlobalConfig()
6984
 
 
6985
 
        if color is None:
6986
 
            color = global_config.get_user_option('grep_color')
6987
 
 
6988
 
        if color is None:
6989
 
            color = 'never'
6990
 
 
6991
 
        if color not in ['always', 'never', 'auto']:
6992
 
            raise errors.CommandError('Valid values for --color are '
6993
 
                                         '"always", "never" or "auto".')
6994
 
 
6995
 
        if levels is None:
6996
 
            levels = 1
6997
 
 
6998
 
        print_revno = False
6999
 
        if revision is not None or levels == 0:
7000
 
            # print revision numbers as we may be showing multiple revisions
7001
 
            print_revno = True
7002
 
 
7003
 
        eol_marker = '\n'
7004
 
        if null:
7005
 
            eol_marker = '\0'
7006
 
 
7007
 
        if not ignore_case and grep.is_fixed_string(pattern):
7008
 
            # if the pattern isalnum, implicitly use to -F for faster grep
7009
 
            fixed_string = True
7010
 
        elif ignore_case and fixed_string:
7011
 
            # GZ 2010-06-02: Fall back to regexp rather than lowercasing
7012
 
            #                pattern and text which will cause pain later
7013
 
            fixed_string = False
7014
 
            pattern = re.escape(pattern)
7015
 
 
7016
 
        patternc = None
7017
 
        re_flags = re.MULTILINE
7018
 
        if ignore_case:
7019
 
            re_flags |= re.IGNORECASE
7020
 
 
7021
 
        if not fixed_string:
7022
 
            patternc = grep.compile_pattern(
7023
 
                pattern.encode(grep._user_encoding), re_flags)
7024
 
 
7025
 
        if color == 'always':
7026
 
            show_color = True
7027
 
        elif color == 'never':
7028
 
            show_color = False
7029
 
        elif color == 'auto':
7030
 
            show_color = _termcolor.allow_color()
7031
 
 
7032
 
        opts = grep.GrepOptions()
7033
 
 
7034
 
        opts.verbose = verbose
7035
 
        opts.ignore_case = ignore_case
7036
 
        opts.no_recursive = no_recursive
7037
 
        opts.from_root = from_root
7038
 
        opts.null = null
7039
 
        opts.levels = levels
7040
 
        opts.line_number = line_number
7041
 
        opts.path_list = path_list
7042
 
        opts.revision = revision
7043
 
        opts.pattern = pattern
7044
 
        opts.include = include
7045
 
        opts.exclude = exclude
7046
 
        opts.fixed_string = fixed_string
7047
 
        opts.files_with_matches = files_with_matches
7048
 
        opts.files_without_match = files_without_match
7049
 
        opts.color = color
7050
 
        opts.diff = False
7051
 
 
7052
 
        opts.eol_marker = eol_marker
7053
 
        opts.print_revno = print_revno
7054
 
        opts.patternc = patternc
7055
 
        opts.recursive = not no_recursive
7056
 
        opts.fixed_string = fixed_string
7057
 
        opts.outf = self.outf
7058
 
        opts.show_color = show_color
7059
 
 
7060
 
        if diff:
7061
 
            # options not used:
7062
 
            # files_with_matches, files_without_match
7063
 
            # levels(?), line_number, from_root
7064
 
            # include, exclude
7065
 
            # These are silently ignored.
7066
 
            grep.grep_diff(opts)
7067
 
        elif revision is None:
7068
 
            grep.workingtree_grep(opts)
7069
 
        else:
7070
 
            grep.versioned_grep(opts)
7071
 
 
7072
 
 
7073
 
class cmd_patch(Command):
7074
 
    """Apply a named patch to the current tree.
7075
 
 
7076
 
    """
7077
 
 
7078
 
    takes_args = ['filename?']
7079
 
    takes_options = [Option('strip', type=int, short_name='p',
7080
 
                            help=("Strip the smallest prefix containing num "
7081
 
                                  "leading slashes from filenames.")),
7082
 
                     Option('silent', help='Suppress chatter.')]
7083
 
 
7084
 
    def run(self, filename=None, strip=None, silent=False):
7085
 
        from .patch import patch_tree
7086
 
        wt = WorkingTree.open_containing('.')[0]
7087
 
        if strip is None:
7088
 
            strip = 1
7089
 
        my_file = None
7090
 
        if filename is None:
7091
 
            my_file = getattr(sys.stdin, 'buffer', sys.stdin)
7092
 
        else:
7093
 
            my_file = open(filename, 'rb')
7094
 
        patches = [my_file.read()]
7095
 
        return patch_tree(wt, patches, strip, quiet=is_quiet(), out=self.outf)
7096
 
 
7097
 
 
7098
 
class cmd_resolve_location(Command):
7099
 
    __doc__ = """Expand a location to a full URL.
7100
 
 
7101
 
    :Examples:
7102
 
        Look up a Launchpad URL.
7103
 
 
7104
 
            brz resolve-location lp:brz
7105
 
    """
7106
 
    takes_args = ['location']
7107
 
    hidden = True
7108
 
 
7109
 
    def run(self, location):
7110
 
        from .location import location_to_url
7111
 
        url = location_to_url(location)
7112
 
        display_url = urlutils.unescape_for_display(url, self.outf.encoding)
7113
 
        self.outf.write('%s\n' % display_url)
7114
 
 
7115
 
 
7116
6720
def _register_lazy_builtins():
7117
6721
    # register lazy builtins from other modules; called at startup and should
7118
6722
    # be only called once.
7119
6723
    for (name, aliases, module_name) in [
7120
 
            ('cmd_bisect', [], 'breezy.bisect'),
7121
 
            ('cmd_bundle_info', [], 'breezy.bzr.bundle.commands'),
7122
 
            ('cmd_config', [], 'breezy.config'),
7123
 
            ('cmd_dump_btree', [], 'breezy.bzr.debug_commands'),
7124
 
            ('cmd_file_id', [], 'breezy.bzr.debug_commands'),
7125
 
            ('cmd_file_path', [], 'breezy.bzr.debug_commands'),
7126
 
            ('cmd_version_info', [], 'breezy.cmd_version_info'),
7127
 
            ('cmd_resolve', ['resolved'], 'breezy.conflicts'),
7128
 
            ('cmd_conflicts', [], 'breezy.conflicts'),
7129
 
            ('cmd_ping', [], 'breezy.bzr.smart.ping'),
7130
 
            ('cmd_sign_my_commits', [], 'breezy.commit_signature_commands'),
7131
 
            ('cmd_verify_signatures', [], 'breezy.commit_signature_commands'),
7132
 
            ('cmd_test_script', [], 'breezy.cmd_test_script'),
7133
 
            ]:
 
6724
        ('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
 
6725
        ('cmd_config', [], 'bzrlib.config'),
 
6726
        ('cmd_dpush', [], 'bzrlib.foreign'),
 
6727
        ('cmd_version_info', [], 'bzrlib.cmd_version_info'),
 
6728
        ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
 
6729
        ('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'),
 
6733
        ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
 
6734
        ]:
7134
6735
        builtin_command_registry.register_lazy(name, aliases, module_name)