~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Andrew Bennetts
  • Date: 2010-03-11 04:33:41 UTC
  • mfrom: (4797.33.4 2.1)
  • mto: This revision was merged to the branch mainline in revision 5082.
  • Revision ID: andrew.bennetts@canonical.com-20100311043341-rzdik83fnactjsxs
Merge lp:bzr/2.1, including fixes for #496813, #526211, #526353.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
20
20
 
21
21
from bzrlib.lazy_import import lazy_import
22
22
lazy_import(globals(), """
 
23
import codecs
23
24
import cStringIO
24
25
import sys
25
26
import time
32
33
    bzrdir,
33
34
    directory_service,
34
35
    delta,
35
 
    config as _mod_config,
 
36
    config,
36
37
    errors,
37
38
    globbing,
38
39
    hooks,
44
45
    rename_map,
45
46
    revision as _mod_revision,
46
47
    static_tuple,
 
48
    symbol_versioning,
47
49
    timestamp,
48
50
    transport,
49
51
    ui,
50
52
    urlutils,
51
53
    views,
52
 
    gpg,
53
54
    )
54
55
from bzrlib.branch import Branch
55
56
from bzrlib.conflicts import ConflictList
59
60
from bzrlib.workingtree import WorkingTree
60
61
""")
61
62
 
62
 
from bzrlib.commands import (
63
 
    Command,
64
 
    builtin_command_registry,
65
 
    display_command,
66
 
    )
 
63
from bzrlib.commands import Command, display_command
67
64
from bzrlib.option import (
68
65
    ListOption,
69
66
    Option,
72
69
    _parse_revision_str,
73
70
    )
74
71
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
75
 
from bzrlib import (
76
 
    symbol_versioning,
77
 
    )
78
 
 
79
 
 
80
 
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
 
72
 
 
73
 
81
74
def tree_files(file_list, default_branch=u'.', canonicalize=True,
82
75
    apply_view=True):
83
 
    return internal_tree_files(file_list, default_branch, canonicalize,
84
 
        apply_view)
 
76
    try:
 
77
        return internal_tree_files(file_list, default_branch, canonicalize,
 
78
            apply_view)
 
79
    except errors.FileInWrongBranch, e:
 
80
        raise errors.BzrCommandError("%s is not in the same branch as %s" %
 
81
                                     (e.path, file_list[0]))
85
82
 
86
83
 
87
84
def tree_files_for_add(file_list):
151
148
 
152
149
# XXX: Bad function name; should possibly also be a class method of
153
150
# WorkingTree rather than a function.
154
 
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
155
151
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
156
152
    apply_view=True):
157
153
    """Convert command-line paths to a WorkingTree and relative paths.
158
154
 
159
 
    Deprecated: use WorkingTree.open_containing_paths instead.
160
 
 
161
155
    This is typically used for command-line processors that take one or
162
156
    more filenames, and infer the workingtree that contains them.
163
157
 
173
167
 
174
168
    :return: workingtree, [relative_paths]
175
169
    """
176
 
    return WorkingTree.open_containing_paths(
177
 
        file_list, default_directory='.',
178
 
        canonicalize=True,
179
 
        apply_view=True)
 
170
    if file_list is None or len(file_list) == 0:
 
171
        tree = WorkingTree.open_containing(default_branch)[0]
 
172
        if tree.supports_views() and apply_view:
 
173
            view_files = tree.views.lookup_view()
 
174
            if view_files:
 
175
                file_list = view_files
 
176
                view_str = views.view_display_str(view_files)
 
177
                note("Ignoring files outside view. View is %s" % view_str)
 
178
        return tree, file_list
 
179
    tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
 
180
    return tree, safe_relpath_files(tree, file_list, canonicalize,
 
181
        apply_view=apply_view)
 
182
 
 
183
 
 
184
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
 
185
    """Convert file_list into a list of relpaths in tree.
 
186
 
 
187
    :param tree: A tree to operate on.
 
188
    :param file_list: A list of user provided paths or None.
 
189
    :param apply_view: if True and a view is set, apply it or check that
 
190
        specified files are within it
 
191
    :return: A list of relative paths.
 
192
    :raises errors.PathNotChild: When a provided path is in a different tree
 
193
        than tree.
 
194
    """
 
195
    if file_list is None:
 
196
        return None
 
197
    if tree.supports_views() and apply_view:
 
198
        view_files = tree.views.lookup_view()
 
199
    else:
 
200
        view_files = []
 
201
    new_list = []
 
202
    # tree.relpath exists as a "thunk" to osutils, but canonical_relpath
 
203
    # doesn't - fix that up here before we enter the loop.
 
204
    if canonicalize:
 
205
        fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
 
206
    else:
 
207
        fixer = tree.relpath
 
208
    for filename in file_list:
 
209
        try:
 
210
            relpath = fixer(osutils.dereference_path(filename))
 
211
            if  view_files and not osutils.is_inside_any(view_files, relpath):
 
212
                raise errors.FileOutsideView(filename, view_files)
 
213
            new_list.append(relpath)
 
214
        except errors.PathNotChild:
 
215
            raise errors.FileInWrongBranch(tree.branch, filename)
 
216
    return new_list
180
217
 
181
218
 
182
219
def _get_view_info_for_change_reporter(tree):
191
228
    return view_info
192
229
 
193
230
 
194
 
def _open_directory_or_containing_tree_or_branch(filename, directory):
195
 
    """Open the tree or branch containing the specified file, unless
196
 
    the --directory option is used to specify a different branch."""
197
 
    if directory is not None:
198
 
        return (None, Branch.open(directory), filename)
199
 
    return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
200
 
 
201
 
 
202
231
# TODO: Make sure no commands unconditionally use the working directory as a
203
232
# branch.  If a filename argument is used, the first of them should be used to
204
233
# specify the branch.  (Perhaps this can be factored out into some kind of
206
235
# opens the branch?)
207
236
 
208
237
class cmd_status(Command):
209
 
    __doc__ = """Display status summary.
 
238
    """Display status summary.
210
239
 
211
240
    This reports on versioned and unknown files, reporting them
212
241
    grouped by state.  Possible states are:
253
282
    To skip the display of pending merge information altogether, use
254
283
    the no-pending option or specify a file/directory.
255
284
 
256
 
    To compare the working directory to a specific revision, pass a
257
 
    single revision to the revision argument.
258
 
 
259
 
    To see which files have changed in a specific revision, or between
260
 
    two revisions, pass a revision range to the revision argument.
261
 
    This will produce the same results as calling 'bzr diff --summarize'.
 
285
    If a revision argument is given, the status is calculated against
 
286
    that revision, or between two revisions if two are provided.
262
287
    """
263
288
 
264
289
    # TODO: --no-recurse, --recurse options
286
311
            raise errors.BzrCommandError('bzr status --revision takes exactly'
287
312
                                         ' one or two revision specifiers')
288
313
 
289
 
        tree, relfile_list = WorkingTree.open_containing_paths(file_list)
 
314
        tree, relfile_list = tree_files(file_list)
290
315
        # Avoid asking for specific files when that is not needed.
291
316
        if relfile_list == ['']:
292
317
            relfile_list = None
303
328
 
304
329
 
305
330
class cmd_cat_revision(Command):
306
 
    __doc__ = """Write out metadata for a revision.
 
331
    """Write out metadata for a revision.
307
332
 
308
333
    The revision to print can either be specified by a specific
309
334
    revision identifier, or you can use --revision.
311
336
 
312
337
    hidden = True
313
338
    takes_args = ['revision_id?']
314
 
    takes_options = ['directory', 'revision']
 
339
    takes_options = ['revision']
315
340
    # cat-revision is more for frontends so should be exact
316
341
    encoding = 'strict'
317
342
 
324
349
        self.outf.write(revtext.decode('utf-8'))
325
350
 
326
351
    @display_command
327
 
    def run(self, revision_id=None, revision=None, directory=u'.'):
 
352
    def run(self, revision_id=None, revision=None):
328
353
        if revision_id is not None and revision is not None:
329
354
            raise errors.BzrCommandError('You can only supply one of'
330
355
                                         ' revision_id or --revision')
331
356
        if revision_id is None and revision is None:
332
357
            raise errors.BzrCommandError('You must supply either'
333
358
                                         ' --revision or a revision_id')
334
 
 
335
 
        b = bzrdir.BzrDir.open_containing_tree_or_branch(directory)[1]
 
359
        b = WorkingTree.open_containing(u'.')[0].branch
336
360
 
337
361
        revisions = b.repository.revisions
338
362
        if revisions is None:
362
386
        
363
387
 
364
388
class cmd_dump_btree(Command):
365
 
    __doc__ = """Dump the contents of a btree index file to stdout.
 
389
    """Dump the contents of a btree index file to stdout.
366
390
 
367
391
    PATH is a btree index file, it can be any URL. This includes things like
368
392
    .bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
416
440
                self.outf.write(page_bytes[:header_end])
417
441
                page_bytes = data
418
442
            self.outf.write('\nPage %d\n' % (page_idx,))
419
 
            if len(page_bytes) == 0:
420
 
                self.outf.write('(empty)\n');
421
 
            else:
422
 
                decomp_bytes = zlib.decompress(page_bytes)
423
 
                self.outf.write(decomp_bytes)
424
 
                self.outf.write('\n')
 
443
            decomp_bytes = zlib.decompress(page_bytes)
 
444
            self.outf.write(decomp_bytes)
 
445
            self.outf.write('\n')
425
446
 
426
447
    def _dump_entries(self, trans, basename):
427
448
        try:
435
456
        for node in bt.iter_all_entries():
436
457
            # Node is made up of:
437
458
            # (index, key, value, [references])
438
 
            try:
439
 
                refs = node[3]
440
 
            except IndexError:
441
 
                refs_as_tuples = None
442
 
            else:
443
 
                refs_as_tuples = static_tuple.as_tuples(refs)
 
459
            refs_as_tuples = static_tuple.as_tuples(node[3])
444
460
            as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
445
461
            self.outf.write('%s\n' % (as_tuple,))
446
462
 
447
463
 
448
464
class cmd_remove_tree(Command):
449
 
    __doc__ = """Remove the working tree from a given branch/checkout.
 
465
    """Remove the working tree from a given branch/checkout.
450
466
 
451
467
    Since a lightweight checkout is little more than a working tree
452
468
    this will refuse to run against one.
458
474
    takes_options = [
459
475
        Option('force',
460
476
               help='Remove the working tree even if it has '
461
 
                    'uncommitted or shelved changes.'),
 
477
                    'uncommitted changes.'),
462
478
        ]
463
479
 
464
480
    def run(self, location_list, force=False):
478
494
            if not force:
479
495
                if (working.has_changes()):
480
496
                    raise errors.UncommittedChanges(working)
481
 
                if working.get_shelf_manager().last_shelf() is not None:
482
 
                    raise errors.ShelvedChanges(working)
483
497
 
484
 
            if working.user_url != working.branch.user_url:
 
498
            working_path = working.bzrdir.root_transport.base
 
499
            branch_path = working.branch.bzrdir.root_transport.base
 
500
            if working_path != branch_path:
485
501
                raise errors.BzrCommandError("You cannot remove the working tree"
486
502
                                             " from a lightweight checkout")
487
503
 
488
504
            d.destroy_workingtree()
489
505
 
490
506
 
491
 
class cmd_repair_workingtree(Command):
492
 
    __doc__ = """Reset the working tree state file.
493
 
 
494
 
    This is not meant to be used normally, but more as a way to recover from
495
 
    filesystem corruption, etc. This rebuilds the working inventory back to a
496
 
    'known good' state. Any new modifications (adding a file, renaming, etc)
497
 
    will be lost, though modified files will still be detected as such.
498
 
 
499
 
    Most users will want something more like "bzr revert" or "bzr update"
500
 
    unless the state file has become corrupted.
501
 
 
502
 
    By default this attempts to recover the current state by looking at the
503
 
    headers of the state file. If the state file is too corrupted to even do
504
 
    that, you can supply --revision to force the state of the tree.
505
 
    """
506
 
 
507
 
    takes_options = ['revision', 'directory',
508
 
        Option('force',
509
 
               help='Reset the tree even if it doesn\'t appear to be'
510
 
                    ' corrupted.'),
511
 
    ]
512
 
    hidden = True
513
 
 
514
 
    def run(self, revision=None, directory='.', force=False):
515
 
        tree, _ = WorkingTree.open_containing(directory)
516
 
        self.add_cleanup(tree.lock_tree_write().unlock)
517
 
        if not force:
518
 
            try:
519
 
                tree.check_state()
520
 
            except errors.BzrError:
521
 
                pass # There seems to be a real error here, so we'll reset
522
 
            else:
523
 
                # Refuse
524
 
                raise errors.BzrCommandError(
525
 
                    'The tree does not appear to be corrupt. You probably'
526
 
                    ' want "bzr revert" instead. Use "--force" if you are'
527
 
                    ' sure you want to reset the working tree.')
528
 
        if revision is None:
529
 
            revision_ids = None
530
 
        else:
531
 
            revision_ids = [r.as_revision_id(tree.branch) for r in revision]
532
 
        try:
533
 
            tree.reset_state(revision_ids)
534
 
        except errors.BzrError, e:
535
 
            if revision_ids is None:
536
 
                extra = (', the header appears corrupt, try passing -r -1'
537
 
                         ' to set the state to the last commit')
538
 
            else:
539
 
                extra = ''
540
 
            raise errors.BzrCommandError('failed to reset the tree state'
541
 
                                         + extra)
542
 
 
543
 
 
544
507
class cmd_revno(Command):
545
 
    __doc__ = """Show current revision number.
 
508
    """Show current revision number.
546
509
 
547
510
    This is equal to the number of revisions on this branch.
548
511
    """
558
521
        if tree:
559
522
            try:
560
523
                wt = WorkingTree.open_containing(location)[0]
561
 
                self.add_cleanup(wt.lock_read().unlock)
 
524
                wt.lock_read()
562
525
            except (errors.NoWorkingTree, errors.NotLocalUrl):
563
526
                raise errors.NoWorkingTree(location)
 
527
            self.add_cleanup(wt.unlock)
564
528
            revid = wt.last_revision()
565
529
            try:
566
530
                revno_t = wt.branch.revision_id_to_dotted_revno(revid)
569
533
            revno = ".".join(str(n) for n in revno_t)
570
534
        else:
571
535
            b = Branch.open_containing(location)[0]
572
 
            self.add_cleanup(b.lock_read().unlock)
 
536
            b.lock_read()
 
537
            self.add_cleanup(b.unlock)
573
538
            revno = b.revno()
574
539
        self.cleanup_now()
575
540
        self.outf.write(str(revno) + '\n')
576
541
 
577
542
 
578
543
class cmd_revision_info(Command):
579
 
    __doc__ = """Show revision number and revision id for a given revision identifier.
 
544
    """Show revision number and revision id for a given revision identifier.
580
545
    """
581
546
    hidden = True
582
547
    takes_args = ['revision_info*']
583
548
    takes_options = [
584
549
        'revision',
585
 
        custom_help('directory',
 
550
        Option('directory',
586
551
            help='Branch to examine, '
587
 
                 'rather than the one containing the working directory.'),
 
552
                 'rather than the one containing the working directory.',
 
553
            short_name='d',
 
554
            type=unicode,
 
555
            ),
588
556
        Option('tree', help='Show revno of working tree'),
589
557
        ]
590
558
 
595
563
        try:
596
564
            wt = WorkingTree.open_containing(directory)[0]
597
565
            b = wt.branch
598
 
            self.add_cleanup(wt.lock_read().unlock)
 
566
            wt.lock_read()
 
567
            self.add_cleanup(wt.unlock)
599
568
        except (errors.NoWorkingTree, errors.NotLocalUrl):
600
569
            wt = None
601
570
            b = Branch.open_containing(directory)[0]
602
 
            self.add_cleanup(b.lock_read().unlock)
 
571
            b.lock_read()
 
572
            self.add_cleanup(b.unlock)
603
573
        revision_ids = []
604
574
        if revision is not None:
605
575
            revision_ids.extend(rev.as_revision_id(b) for rev in revision)
633
603
 
634
604
 
635
605
class cmd_add(Command):
636
 
    __doc__ = """Add specified files or directories.
 
606
    """Add specified files or directories.
637
607
 
638
608
    In non-recursive mode, all the named items are added, regardless
639
609
    of whether they were previously ignored.  A warning is given if
704
674
                should_print=(not is_quiet()))
705
675
 
706
676
        if base_tree:
707
 
            self.add_cleanup(base_tree.lock_read().unlock)
 
677
            base_tree.lock_read()
 
678
            self.add_cleanup(base_tree.unlock)
708
679
        tree, file_list = tree_files_for_add(file_list)
709
680
        added, ignored = tree.smart_add(file_list, not
710
681
            no_recurse, action=action, save=not dry_run)
718
689
 
719
690
 
720
691
class cmd_mkdir(Command):
721
 
    __doc__ = """Create a new versioned directory.
 
692
    """Create a new versioned directory.
722
693
 
723
694
    This is equivalent to creating the directory and then adding it.
724
695
    """
740
711
 
741
712
 
742
713
class cmd_relpath(Command):
743
 
    __doc__ = """Show path of a file relative to root"""
 
714
    """Show path of a file relative to root"""
744
715
 
745
716
    takes_args = ['filename']
746
717
    hidden = True
755
726
 
756
727
 
757
728
class cmd_inventory(Command):
758
 
    __doc__ = """Show inventory of the current working copy or a revision.
 
729
    """Show inventory of the current working copy or a revision.
759
730
 
760
731
    It is possible to limit the output to a particular entry
761
732
    type using the --kind option.  For example: --kind file.
781
752
            raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
782
753
 
783
754
        revision = _get_one_revision('inventory', revision)
784
 
        work_tree, file_list = WorkingTree.open_containing_paths(file_list)
785
 
        self.add_cleanup(work_tree.lock_read().unlock)
 
755
        work_tree, file_list = tree_files(file_list)
 
756
        work_tree.lock_read()
 
757
        self.add_cleanup(work_tree.unlock)
786
758
        if revision is not None:
787
759
            tree = revision.as_tree(work_tree.branch)
788
760
 
789
761
            extra_trees = [work_tree]
790
 
            self.add_cleanup(tree.lock_read().unlock)
 
762
            tree.lock_read()
 
763
            self.add_cleanup(tree.unlock)
791
764
        else:
792
765
            tree = work_tree
793
766
            extra_trees = []
797
770
                                      require_versioned=True)
798
771
            # find_ids_across_trees may include some paths that don't
799
772
            # exist in 'tree'.
800
 
            entries = sorted(
801
 
                (tree.id2path(file_id), tree.inventory[file_id])
802
 
                for file_id in file_ids if tree.has_id(file_id))
 
773
            entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
 
774
                             for file_id in file_ids if file_id in tree)
803
775
        else:
804
776
            entries = tree.inventory.entries()
805
777
 
815
787
 
816
788
 
817
789
class cmd_mv(Command):
818
 
    __doc__ = """Move or rename a file.
 
790
    """Move or rename a file.
819
791
 
820
792
    :Usage:
821
793
        bzr mv OLDNAME NEWNAME
853
825
            names_list = []
854
826
        if len(names_list) < 2:
855
827
            raise errors.BzrCommandError("missing file argument")
856
 
        tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
857
 
        self.add_cleanup(tree.lock_tree_write().unlock)
 
828
        tree, rel_names = tree_files(names_list, canonicalize=False)
 
829
        tree.lock_tree_write()
 
830
        self.add_cleanup(tree.unlock)
858
831
        self._run(tree, names_list, rel_names, after)
859
832
 
860
833
    def run_auto(self, names_list, after, dry_run):
864
837
        if after:
865
838
            raise errors.BzrCommandError('--after cannot be specified with'
866
839
                                         ' --auto.')
867
 
        work_tree, file_list = WorkingTree.open_containing_paths(
868
 
            names_list, default_directory='.')
869
 
        self.add_cleanup(work_tree.lock_tree_write().unlock)
 
840
        work_tree, file_list = tree_files(names_list, default_branch='.')
 
841
        work_tree.lock_tree_write()
 
842
        self.add_cleanup(work_tree.unlock)
870
843
        rename_map.RenameMap.guess_renames(work_tree, dry_run)
871
844
 
872
845
    def _run(self, tree, names_list, rel_names, after):
951
924
 
952
925
 
953
926
class cmd_pull(Command):
954
 
    __doc__ = """Turn this branch into a mirror of another branch.
 
927
    """Turn this branch into a mirror of another branch.
955
928
 
956
929
    By default, this command only works on branches that have not diverged.
957
930
    Branches are considered diverged if the destination branch's most recent 
966
939
    match the remote one, use pull --overwrite. This will work even if the two
967
940
    branches have diverged.
968
941
 
969
 
    If there is no default location set, the first pull will set it (use
970
 
    --no-remember to avoid settting it). After that, you can omit the
971
 
    location to use the default.  To change the default, use --remember. The
972
 
    value will only be saved if the remote location can be accessed.
 
942
    If there is no default location set, the first pull will set it.  After
 
943
    that, you can omit the location to use the default.  To change the
 
944
    default, use --remember. The value will only be saved if the remote
 
945
    location can be accessed.
973
946
 
974
947
    Note: The location can be specified either in the form of a branch,
975
948
    or in the form of a path to a file containing a merge directive generated
980
953
    takes_options = ['remember', 'overwrite', 'revision',
981
954
        custom_help('verbose',
982
955
            help='Show logs of pulled revisions.'),
983
 
        custom_help('directory',
 
956
        Option('directory',
984
957
            help='Branch to pull into, '
985
 
                 'rather than the one containing the working directory.'),
 
958
                 'rather than the one containing the working directory.',
 
959
            short_name='d',
 
960
            type=unicode,
 
961
            ),
986
962
        Option('local',
987
963
            help="Perform a local pull in a bound "
988
964
                 "branch.  Local pulls are not applied to "
989
965
                 "the master branch."
990
966
            ),
991
 
        Option('show-base',
992
 
            help="Show base revision text in conflicts.")
993
967
        ]
994
968
    takes_args = ['location?']
995
969
    encoding_type = 'replace'
996
970
 
997
 
    def run(self, location=None, remember=None, overwrite=False,
 
971
    def run(self, location=None, remember=False, overwrite=False,
998
972
            revision=None, verbose=False,
999
 
            directory=None, local=False,
1000
 
            show_base=False):
 
973
            directory=None, local=False):
1001
974
        # FIXME: too much stuff is in the command class
1002
975
        revision_id = None
1003
976
        mergeable = None
1006
979
        try:
1007
980
            tree_to = WorkingTree.open_containing(directory)[0]
1008
981
            branch_to = tree_to.branch
1009
 
            self.add_cleanup(tree_to.lock_write().unlock)
1010
982
        except errors.NoWorkingTree:
1011
983
            tree_to = None
1012
984
            branch_to = Branch.open_containing(directory)[0]
1013
 
            self.add_cleanup(branch_to.lock_write().unlock)
1014
 
 
1015
 
        if tree_to is None and show_base:
1016
 
            raise errors.BzrCommandError("Need working tree for --show-base.")
1017
 
 
 
985
        
1018
986
        if local and not branch_to.get_bound_location():
1019
987
            raise errors.LocalRequiresBoundBranch()
1020
988
 
1050
1018
        else:
1051
1019
            branch_from = Branch.open(location,
1052
1020
                possible_transports=possible_transports)
1053
 
            self.add_cleanup(branch_from.lock_read().unlock)
1054
 
            # Remembers if asked explicitly or no previous location is set
1055
 
            if (remember
1056
 
                or (remember is None and branch_to.get_parent() is None)):
 
1021
 
 
1022
            if branch_to.get_parent() is None or remember:
1057
1023
                branch_to.set_parent(branch_from.base)
1058
1024
 
 
1025
        if branch_from is not branch_to:
 
1026
            branch_from.lock_read()
 
1027
            self.add_cleanup(branch_from.unlock)
1059
1028
        if revision is not None:
1060
1029
            revision_id = revision.as_revision_id(branch_from)
1061
1030
 
 
1031
        branch_to.lock_write()
 
1032
        self.add_cleanup(branch_to.unlock)
1062
1033
        if tree_to is not None:
1063
1034
            view_info = _get_view_info_for_change_reporter(tree_to)
1064
1035
            change_reporter = delta._ChangeReporter(
1066
1037
                view_info=view_info)
1067
1038
            result = tree_to.pull(
1068
1039
                branch_from, overwrite, revision_id, change_reporter,
1069
 
                possible_transports=possible_transports, local=local,
1070
 
                show_base=show_base)
 
1040
                possible_transports=possible_transports, local=local)
1071
1041
        else:
1072
1042
            result = branch_to.pull(
1073
1043
                branch_from, overwrite, revision_id, local=local)
1077
1047
            log.show_branch_change(
1078
1048
                branch_to, self.outf, result.old_revno,
1079
1049
                result.old_revid)
1080
 
        if getattr(result, 'tag_conflicts', None):
1081
 
            return 1
1082
 
        else:
1083
 
            return 0
1084
1050
 
1085
1051
 
1086
1052
class cmd_push(Command):
1087
 
    __doc__ = """Update a mirror of this branch.
 
1053
    """Update a mirror of this branch.
1088
1054
 
1089
1055
    The target branch will not have its working tree populated because this
1090
1056
    is both expensive, and is not supported on remote file systems.
1103
1069
    do a merge (see bzr help merge) from the other branch, and commit that.
1104
1070
    After that you will be able to do a push without '--overwrite'.
1105
1071
 
1106
 
    If there is no default push location set, the first push will set it (use
1107
 
    --no-remember to avoid settting it).  After that, you can omit the
1108
 
    location to use the default.  To change the default, use --remember. The
1109
 
    value will only be saved if the remote location can be accessed.
 
1072
    If there is no default push location set, the first push will set it.
 
1073
    After that, you can omit the location to use the default.  To change the
 
1074
    default, use --remember. The value will only be saved if the remote
 
1075
    location can be accessed.
1110
1076
    """
1111
1077
 
1112
1078
    _see_also = ['pull', 'update', 'working-trees']
1114
1080
        Option('create-prefix',
1115
1081
               help='Create the path leading up to the branch '
1116
1082
                    'if it does not already exist.'),
1117
 
        custom_help('directory',
 
1083
        Option('directory',
1118
1084
            help='Branch to push from, '
1119
 
                 'rather than the one containing the working directory.'),
 
1085
                 'rather than the one containing the working directory.',
 
1086
            short_name='d',
 
1087
            type=unicode,
 
1088
            ),
1120
1089
        Option('use-existing-dir',
1121
1090
               help='By default push will fail if the target'
1122
1091
                    ' directory exists, but does not already'
1133
1102
        Option('strict',
1134
1103
               help='Refuse to push if there are uncommitted changes in'
1135
1104
               ' the working tree, --no-strict disables the check.'),
1136
 
        Option('no-tree',
1137
 
               help="Don't populate the working tree, even for protocols"
1138
 
               " that support it."),
1139
1105
        ]
1140
1106
    takes_args = ['location?']
1141
1107
    encoding_type = 'replace'
1142
1108
 
1143
 
    def run(self, location=None, remember=None, overwrite=False,
 
1109
    def run(self, location=None, remember=False, overwrite=False,
1144
1110
        create_prefix=False, verbose=False, revision=None,
1145
1111
        use_existing_dir=False, directory=None, stacked_on=None,
1146
 
        stacked=False, strict=None, no_tree=False):
 
1112
        stacked=False, strict=None):
1147
1113
        from bzrlib.push import _show_push_branch
1148
1114
 
1149
1115
        if directory is None:
1151
1117
        # Get the source branch
1152
1118
        (tree, br_from,
1153
1119
         _unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
 
1120
        if strict is None:
 
1121
            strict = br_from.get_config().get_user_option_as_bool('push_strict')
 
1122
        if strict is None: strict = True # default value
1154
1123
        # Get the tip's revision_id
1155
1124
        revision = _get_one_revision('push', revision)
1156
1125
        if revision is not None:
1157
1126
            revision_id = revision.in_history(br_from).rev_id
1158
1127
        else:
1159
1128
            revision_id = None
1160
 
        if tree is not None and revision_id is None:
1161
 
            tree.check_changed_or_out_of_date(
1162
 
                strict, 'push_strict',
1163
 
                more_error='Use --no-strict to force the push.',
1164
 
                more_warning='Uncommitted changes will not be pushed.')
 
1129
        if strict and tree is not None and revision_id is None:
 
1130
            if (tree.has_changes()):
 
1131
                raise errors.UncommittedChanges(
 
1132
                    tree, more='Use --no-strict to force the push.')
 
1133
            if tree.last_revision() != tree.branch.last_revision():
 
1134
                # The tree has lost sync with its branch, there is little
 
1135
                # chance that the user is aware of it but he can still force
 
1136
                # the push with --no-strict
 
1137
                raise errors.OutOfDateTree(
 
1138
                    tree, more='Use --no-strict to force the push.')
 
1139
 
1165
1140
        # Get the stacked_on branch, if any
1166
1141
        if stacked_on is not None:
1167
1142
            stacked_on = urlutils.normalize_url(stacked_on)
1195
1170
        _show_push_branch(br_from, revision_id, location, self.outf,
1196
1171
            verbose=verbose, overwrite=overwrite, remember=remember,
1197
1172
            stacked_on=stacked_on, create_prefix=create_prefix,
1198
 
            use_existing_dir=use_existing_dir, no_tree=no_tree)
 
1173
            use_existing_dir=use_existing_dir)
1199
1174
 
1200
1175
 
1201
1176
class cmd_branch(Command):
1202
 
    __doc__ = """Create a new branch that is a copy of an existing branch.
 
1177
    """Create a new branch that is a copy of an existing branch.
1203
1178
 
1204
1179
    If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1205
1180
    be used.  In other words, "branch ../foo/bar" will attempt to create ./bar.
1210
1185
 
1211
1186
    To retrieve the branch as of a particular revision, supply the --revision
1212
1187
    parameter, as in "branch foo/bar -r 5".
1213
 
 
1214
 
    The synonyms 'clone' and 'get' for this command are deprecated.
1215
1188
    """
1216
1189
 
1217
1190
    _see_also = ['checkout']
1218
1191
    takes_args = ['from_location', 'to_location?']
1219
 
    takes_options = ['revision',
1220
 
        Option('hardlink', help='Hard-link working tree files where possible.'),
1221
 
        Option('files-from', type=str,
1222
 
               help="Get file contents from this tree."),
 
1192
    takes_options = ['revision', Option('hardlink',
 
1193
        help='Hard-link working tree files where possible.'),
1223
1194
        Option('no-tree',
1224
1195
            help="Create a branch without a working-tree."),
1225
1196
        Option('switch',
1243
1214
 
1244
1215
    def run(self, from_location, to_location=None, revision=None,
1245
1216
            hardlink=False, stacked=False, standalone=False, no_tree=False,
1246
 
            use_existing_dir=False, switch=False, bind=False,
1247
 
            files_from=None):
 
1217
            use_existing_dir=False, switch=False, bind=False):
1248
1218
        from bzrlib import switch as _mod_switch
1249
1219
        from bzrlib.tag import _merge_tags_if_possible
1250
 
        if self.invoked_as in ['get', 'clone']:
1251
 
            ui.ui_factory.show_user_warning(
1252
 
                'deprecated_command',
1253
 
                deprecated_name=self.invoked_as,
1254
 
                recommended_name='branch',
1255
 
                deprecated_in_version='2.4')
1256
1220
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1257
1221
            from_location)
1258
 
        if not (hardlink or files_from):
1259
 
            # accelerator_tree is usually slower because you have to read N
1260
 
            # files (no readahead, lots of seeks, etc), but allow the user to
1261
 
            # explicitly request it
1262
 
            accelerator_tree = None
1263
 
        if files_from is not None and files_from != from_location:
1264
 
            accelerator_tree = WorkingTree.open(files_from)
1265
1222
        revision = _get_one_revision('branch', revision)
1266
 
        self.add_cleanup(br_from.lock_read().unlock)
 
1223
        br_from.lock_read()
 
1224
        self.add_cleanup(br_from.unlock)
1267
1225
        if revision is not None:
1268
1226
            revision_id = revision.as_revision_id(br_from)
1269
1227
        else:
1329
1287
 
1330
1288
 
1331
1289
class cmd_checkout(Command):
1332
 
    __doc__ = """Create a new checkout of an existing branch.
 
1290
    """Create a new checkout of an existing branch.
1333
1291
 
1334
1292
    If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1335
1293
    the branch found in '.'. This is useful if you have removed the working tree
1374
1332
            to_location = branch_location
1375
1333
        accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1376
1334
            branch_location)
1377
 
        if not (hardlink or files_from):
1378
 
            # accelerator_tree is usually slower because you have to read N
1379
 
            # files (no readahead, lots of seeks, etc), but allow the user to
1380
 
            # explicitly request it
1381
 
            accelerator_tree = None
1382
1335
        revision = _get_one_revision('checkout', revision)
1383
 
        if files_from is not None and files_from != branch_location:
 
1336
        if files_from is not None:
1384
1337
            accelerator_tree = WorkingTree.open(files_from)
1385
1338
        if revision is not None:
1386
1339
            revision_id = revision.as_revision_id(source)
1403
1356
 
1404
1357
 
1405
1358
class cmd_renames(Command):
1406
 
    __doc__ = """Show list of renamed files.
 
1359
    """Show list of renamed files.
1407
1360
    """
1408
1361
    # TODO: Option to show renames between two historical versions.
1409
1362
 
1414
1367
    @display_command
1415
1368
    def run(self, dir=u'.'):
1416
1369
        tree = WorkingTree.open_containing(dir)[0]
1417
 
        self.add_cleanup(tree.lock_read().unlock)
 
1370
        tree.lock_read()
 
1371
        self.add_cleanup(tree.unlock)
1418
1372
        new_inv = tree.inventory
1419
1373
        old_tree = tree.basis_tree()
1420
 
        self.add_cleanup(old_tree.lock_read().unlock)
 
1374
        old_tree.lock_read()
 
1375
        self.add_cleanup(old_tree.unlock)
1421
1376
        old_inv = old_tree.inventory
1422
1377
        renames = []
1423
1378
        iterator = tree.iter_changes(old_tree, include_unchanged=True)
1433
1388
 
1434
1389
 
1435
1390
class cmd_update(Command):
1436
 
    __doc__ = """Update a tree to have the latest code committed to its branch.
 
1391
    """Update a tree to have the latest code committed to its branch.
1437
1392
 
1438
1393
    This will perform a merge into the working tree, and may generate
1439
1394
    conflicts. If you have any local changes, you will still
1442
1397
    If you want to discard your local changes, you can just do a
1443
1398
    'bzr revert' instead of 'bzr commit' after the update.
1444
1399
 
1445
 
    If you want to restore a file that has been removed locally, use
1446
 
    'bzr revert' instead of 'bzr update'.
1447
 
 
1448
1400
    If the tree's branch is bound to a master branch, it will also update
1449
1401
    the branch from the master.
1450
1402
    """
1451
1403
 
1452
1404
    _see_also = ['pull', 'working-trees', 'status-flags']
1453
1405
    takes_args = ['dir?']
1454
 
    takes_options = ['revision',
1455
 
                     Option('show-base',
1456
 
                            help="Show base revision text in conflicts."),
1457
 
                     ]
 
1406
    takes_options = ['revision']
1458
1407
    aliases = ['up']
1459
1408
 
1460
 
    def run(self, dir='.', revision=None, show_base=None):
 
1409
    def run(self, dir='.', revision=None):
1461
1410
        if revision is not None and len(revision) != 1:
1462
1411
            raise errors.BzrCommandError(
1463
1412
                        "bzr update --revision takes exactly one revision")
1467
1416
        master = branch.get_master_branch(
1468
1417
            possible_transports=possible_transports)
1469
1418
        if master is not None:
 
1419
            tree.lock_write()
1470
1420
            branch_location = master.base
1471
 
            tree.lock_write()
1472
1421
        else:
 
1422
            tree.lock_tree_write()
1473
1423
            branch_location = tree.branch.base
1474
 
            tree.lock_tree_write()
1475
1424
        self.add_cleanup(tree.unlock)
1476
1425
        # get rid of the final '/' and be ready for display
1477
 
        branch_location = urlutils.unescape_for_display(
1478
 
            branch_location.rstrip('/'),
1479
 
            self.outf.encoding)
 
1426
        branch_location = urlutils.unescape_for_display(branch_location[:-1],
 
1427
                                                        self.outf.encoding)
1480
1428
        existing_pending_merges = tree.get_parent_ids()[1:]
1481
1429
        if master is None:
1482
1430
            old_tip = None
1490
1438
        else:
1491
1439
            revision_id = branch.last_revision()
1492
1440
        if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1493
 
            revno = branch.revision_id_to_dotted_revno(revision_id)
1494
 
            note("Tree is up to date at revision %s of branch %s" %
1495
 
                ('.'.join(map(str, revno)), branch_location))
 
1441
            revno = branch.revision_id_to_revno(revision_id)
 
1442
            note("Tree is up to date at revision %d of branch %s" %
 
1443
                (revno, branch_location))
1496
1444
            return 0
1497
1445
        view_info = _get_view_info_for_change_reporter(tree)
1498
1446
        change_reporter = delta._ChangeReporter(
1503
1451
                change_reporter,
1504
1452
                possible_transports=possible_transports,
1505
1453
                revision=revision_id,
1506
 
                old_tip=old_tip,
1507
 
                show_base=show_base)
 
1454
                old_tip=old_tip)
1508
1455
        except errors.NoSuchRevision, e:
1509
1456
            raise errors.BzrCommandError(
1510
1457
                                  "branch has no revision %s\n"
1511
1458
                                  "bzr update --revision only works"
1512
1459
                                  " for a revision in the branch history"
1513
1460
                                  % (e.revision))
1514
 
        revno = tree.branch.revision_id_to_dotted_revno(
 
1461
        revno = tree.branch.revision_id_to_revno(
1515
1462
            _mod_revision.ensure_null(tree.last_revision()))
1516
 
        note('Updated to revision %s of branch %s' %
1517
 
             ('.'.join(map(str, revno)), branch_location))
1518
 
        parent_ids = tree.get_parent_ids()
1519
 
        if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
 
1463
        note('Updated to revision %d of branch %s' %
 
1464
             (revno, branch_location))
 
1465
        if tree.get_parent_ids()[1:] != existing_pending_merges:
1520
1466
            note('Your local commits will now show as pending merges with '
1521
1467
                 "'bzr status', and can be committed with 'bzr commit'.")
1522
1468
        if conflicts != 0:
1526
1472
 
1527
1473
 
1528
1474
class cmd_info(Command):
1529
 
    __doc__ = """Show information about a working tree, branch or repository.
 
1475
    """Show information about a working tree, branch or repository.
1530
1476
 
1531
1477
    This command will show all known locations and formats associated to the
1532
1478
    tree, branch or repository.
1570
1516
 
1571
1517
 
1572
1518
class cmd_remove(Command):
1573
 
    __doc__ = """Remove files or directories.
 
1519
    """Remove files or directories.
1574
1520
 
1575
 
    This makes Bazaar stop tracking changes to the specified files. Bazaar will
1576
 
    delete them if they can easily be recovered using revert otherwise they
1577
 
    will be backed up (adding an extention of the form .~#~). If no options or
1578
 
    parameters are given Bazaar will scan for files that are being tracked by
1579
 
    Bazaar but missing in your tree and stop tracking them for you.
 
1521
    This makes bzr stop tracking changes to the specified files. bzr will delete
 
1522
    them if they can easily be recovered using revert. If no options or
 
1523
    parameters are given bzr will scan for files that are being tracked by bzr
 
1524
    but missing in your tree and stop tracking them for you.
1580
1525
    """
1581
1526
    takes_args = ['file*']
1582
1527
    takes_options = ['verbose',
1584
1529
        RegistryOption.from_kwargs('file-deletion-strategy',
1585
1530
            'The file deletion mode to be used.',
1586
1531
            title='Deletion Strategy', value_switches=True, enum_switch=False,
1587
 
            safe='Backup changed files (default).',
 
1532
            safe='Only delete files if they can be'
 
1533
                 ' safely recovered (default).',
1588
1534
            keep='Delete from bzr but leave the working copy.',
1589
 
            no_backup='Don\'t backup changed files.',
1590
1535
            force='Delete all the specified files, even if they can not be '
1591
 
                'recovered and even if they are non-empty directories. '
1592
 
                '(deprecated, use no-backup)')]
 
1536
                'recovered and even if they are non-empty directories.')]
1593
1537
    aliases = ['rm', 'del']
1594
1538
    encoding_type = 'replace'
1595
1539
 
1596
1540
    def run(self, file_list, verbose=False, new=False,
1597
1541
        file_deletion_strategy='safe'):
1598
 
        if file_deletion_strategy == 'force':
1599
 
            note("(The --force option is deprecated, rather use --no-backup "
1600
 
                "in future.)")
1601
 
            file_deletion_strategy = 'no-backup'
1602
 
 
1603
 
        tree, file_list = WorkingTree.open_containing_paths(file_list)
 
1542
        tree, file_list = tree_files(file_list)
1604
1543
 
1605
1544
        if file_list is not None:
1606
1545
            file_list = [f for f in file_list]
1607
1546
 
1608
 
        self.add_cleanup(tree.lock_write().unlock)
 
1547
        tree.lock_write()
 
1548
        self.add_cleanup(tree.unlock)
1609
1549
        # Heuristics should probably all move into tree.remove_smart or
1610
1550
        # some such?
1611
1551
        if new:
1626
1566
            file_deletion_strategy = 'keep'
1627
1567
        tree.remove(file_list, verbose=verbose, to_file=self.outf,
1628
1568
            keep_files=file_deletion_strategy=='keep',
1629
 
            force=(file_deletion_strategy=='no-backup'))
 
1569
            force=file_deletion_strategy=='force')
1630
1570
 
1631
1571
 
1632
1572
class cmd_file_id(Command):
1633
 
    __doc__ = """Print file_id of a particular file or directory.
 
1573
    """Print file_id of a particular file or directory.
1634
1574
 
1635
1575
    The file_id is assigned when the file is first added and remains the
1636
1576
    same through all revisions where the file exists, even when it is
1652
1592
 
1653
1593
 
1654
1594
class cmd_file_path(Command):
1655
 
    __doc__ = """Print path of file_ids to a file or directory.
 
1595
    """Print path of file_ids to a file or directory.
1656
1596
 
1657
1597
    This prints one line for each directory down to the target,
1658
1598
    starting at the branch root.
1674
1614
 
1675
1615
 
1676
1616
class cmd_reconcile(Command):
1677
 
    __doc__ = """Reconcile bzr metadata in a branch.
 
1617
    """Reconcile bzr metadata in a branch.
1678
1618
 
1679
1619
    This can correct data mismatches that may have been caused by
1680
1620
    previous ghost operations or bzr upgrades. You should only
1694
1634
 
1695
1635
    _see_also = ['check']
1696
1636
    takes_args = ['branch?']
1697
 
    takes_options = [
1698
 
        Option('canonicalize-chks',
1699
 
               help='Make sure CHKs are in canonical form (repairs '
1700
 
                    'bug 522637).',
1701
 
               hidden=True),
1702
 
        ]
1703
1637
 
1704
 
    def run(self, branch=".", canonicalize_chks=False):
 
1638
    def run(self, branch="."):
1705
1639
        from bzrlib.reconcile import reconcile
1706
1640
        dir = bzrdir.BzrDir.open(branch)
1707
 
        reconcile(dir, canonicalize_chks=canonicalize_chks)
 
1641
        reconcile(dir)
1708
1642
 
1709
1643
 
1710
1644
class cmd_revision_history(Command):
1711
 
    __doc__ = """Display the list of revision ids on a branch."""
 
1645
    """Display the list of revision ids on a branch."""
1712
1646
 
1713
1647
    _see_also = ['log']
1714
1648
    takes_args = ['location?']
1724
1658
 
1725
1659
 
1726
1660
class cmd_ancestry(Command):
1727
 
    __doc__ = """List all revisions merged into this branch."""
 
1661
    """List all revisions merged into this branch."""
1728
1662
 
1729
1663
    _see_also = ['log', 'revision-history']
1730
1664
    takes_args = ['location?']
1742
1676
            b = wt.branch
1743
1677
            last_revision = wt.last_revision()
1744
1678
 
1745
 
        self.add_cleanup(b.repository.lock_read().unlock)
1746
 
        graph = b.repository.get_graph()
1747
 
        revisions = [revid for revid, parents in
1748
 
            graph.iter_ancestry([last_revision])]
1749
 
        for revision_id in reversed(revisions):
1750
 
            if _mod_revision.is_null(revision_id):
1751
 
                continue
 
1679
        revision_ids = b.repository.get_ancestry(last_revision)
 
1680
        revision_ids.pop(0)
 
1681
        for revision_id in revision_ids:
1752
1682
            self.outf.write(revision_id + '\n')
1753
1683
 
1754
1684
 
1755
1685
class cmd_init(Command):
1756
 
    __doc__ = """Make a directory into a versioned branch.
 
1686
    """Make a directory into a versioned branch.
1757
1687
 
1758
1688
    Use this to create an empty branch, or before importing an
1759
1689
    existing project.
1791
1721
                ),
1792
1722
         Option('append-revisions-only',
1793
1723
                help='Never change revnos or the existing log.'
1794
 
                '  Append revisions to it only.'),
1795
 
         Option('no-tree',
1796
 
                'Create a branch without a working tree.')
 
1724
                '  Append revisions to it only.')
1797
1725
         ]
1798
1726
    def run(self, location=None, format=None, append_revisions_only=False,
1799
 
            create_prefix=False, no_tree=False):
 
1727
            create_prefix=False):
1800
1728
        if format is None:
1801
1729
            format = bzrdir.format_registry.make_bzrdir('default')
1802
1730
        if location is None:
1825
1753
        except errors.NotBranchError:
1826
1754
            # really a NotBzrDir error...
1827
1755
            create_branch = bzrdir.BzrDir.create_branch_convenience
1828
 
            if no_tree:
1829
 
                force_new_tree = False
1830
 
            else:
1831
 
                force_new_tree = None
1832
1756
            branch = create_branch(to_transport.base, format=format,
1833
 
                                   possible_transports=[to_transport],
1834
 
                                   force_new_tree=force_new_tree)
 
1757
                                   possible_transports=[to_transport])
1835
1758
            a_bzrdir = branch.bzrdir
1836
1759
        else:
1837
1760
            from bzrlib.transport.local import LocalTransport
1841
1764
                        raise errors.BranchExistsWithoutWorkingTree(location)
1842
1765
                raise errors.AlreadyBranchError(location)
1843
1766
            branch = a_bzrdir.create_branch()
1844
 
            if not no_tree:
1845
 
                a_bzrdir.create_workingtree()
 
1767
            a_bzrdir.create_workingtree()
1846
1768
        if append_revisions_only:
1847
1769
            try:
1848
1770
                branch.set_append_revisions_only(True)
1870
1792
 
1871
1793
 
1872
1794
class cmd_init_repository(Command):
1873
 
    __doc__ = """Create a shared repository for branches to share storage space.
 
1795
    """Create a shared repository for branches to share storage space.
1874
1796
 
1875
1797
    New branches created under the repository directory will store their
1876
1798
    revisions in the repository, not in the branch directory.  For branches
1930
1852
 
1931
1853
 
1932
1854
class cmd_diff(Command):
1933
 
    __doc__ = """Show differences in the working tree, between revisions or branches.
 
1855
    """Show differences in the working tree, between revisions or branches.
1934
1856
 
1935
1857
    If no arguments are given, all changes for the current tree are listed.
1936
1858
    If files are given, only the changes in those files are listed.
1942
1864
    "bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1943
1865
    produces patches suitable for "patch -p1".
1944
1866
 
1945
 
    Note that when using the -r argument with a range of revisions, the
1946
 
    differences are computed between the two specified revisions.  That
1947
 
    is, the command does not show the changes introduced by the first 
1948
 
    revision in the range.  This differs from the interpretation of 
1949
 
    revision ranges used by "bzr log" which includes the first revision
1950
 
    in the range.
1951
 
 
1952
1867
    :Exit values:
1953
1868
        1 - changed
1954
1869
        2 - unrepresentable changes
1972
1887
 
1973
1888
            bzr diff -r1..3 xxx
1974
1889
 
1975
 
        The changes introduced by revision 2 (equivalent to -r1..2)::
1976
 
 
1977
 
            bzr diff -c2
1978
 
 
1979
 
        To see the changes introduced by revision X::
 
1890
        To see the changes introduced in revision X::
1980
1891
        
1981
1892
            bzr diff -cX
1982
1893
 
1986
1897
 
1987
1898
            bzr diff -r<chosen_parent>..X
1988
1899
 
1989
 
        The changes between the current revision and the previous revision
1990
 
        (equivalent to -c-1 and -r-2..-1)
 
1900
        The changes introduced by revision 2 (equivalent to -r1..2)::
1991
1901
 
1992
 
            bzr diff -r-2..
 
1902
            bzr diff -c2
1993
1903
 
1994
1904
        Show just the differences for file NEWS::
1995
1905
 
2010
1920
        Same as 'bzr diff' but prefix paths with old/ and new/::
2011
1921
 
2012
1922
            bzr diff --prefix old/:new/
2013
 
            
2014
 
        Show the differences using a custom diff program with options::
2015
 
        
2016
 
            bzr diff --using /usr/bin/diff --diff-options -wu
2017
1923
    """
2018
1924
    _see_also = ['status']
2019
1925
    takes_args = ['file*']
2038
1944
            help='Use this command to compare files.',
2039
1945
            type=unicode,
2040
1946
            ),
2041
 
        RegistryOption('format',
2042
 
            short_name='F',
2043
 
            help='Diff format to use.',
2044
 
            lazy_registry=('bzrlib.diff', 'format_registry'),
2045
 
            title='Diff format'),
2046
1947
        ]
2047
1948
    aliases = ['di', 'dif']
2048
1949
    encoding_type = 'exact'
2049
1950
 
2050
1951
    @display_command
2051
1952
    def run(self, revision=None, file_list=None, diff_options=None,
2052
 
            prefix=None, old=None, new=None, using=None, format=None):
2053
 
        from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
2054
 
            show_diff_trees)
 
1953
            prefix=None, old=None, new=None, using=None):
 
1954
        from bzrlib.diff import get_trees_and_branches_to_diff, show_diff_trees
2055
1955
 
2056
1956
        if (prefix is None) or (prefix == '0'):
2057
1957
            # diff -p0 format
2071
1971
            raise errors.BzrCommandError('bzr diff --revision takes exactly'
2072
1972
                                         ' one or two revision specifiers')
2073
1973
 
2074
 
        if using is not None and format is not None:
2075
 
            raise errors.BzrCommandError('--using and --format are mutually '
2076
 
                'exclusive.')
2077
 
 
2078
1974
        (old_tree, new_tree,
2079
1975
         old_branch, new_branch,
2080
 
         specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
2081
 
            file_list, revision, old, new, self.add_cleanup, apply_view=True)
2082
 
        # GNU diff on Windows uses ANSI encoding for filenames
2083
 
        path_encoding = osutils.get_diff_header_encoding()
 
1976
         specific_files, extra_trees) = get_trees_and_branches_to_diff(
 
1977
            file_list, revision, old, new, apply_view=True)
2084
1978
        return show_diff_trees(old_tree, new_tree, sys.stdout,
2085
1979
                               specific_files=specific_files,
2086
1980
                               external_diff_options=diff_options,
2087
1981
                               old_label=old_label, new_label=new_label,
2088
 
                               extra_trees=extra_trees,
2089
 
                               path_encoding=path_encoding,
2090
 
                               using=using,
2091
 
                               format_cls=format)
 
1982
                               extra_trees=extra_trees, using=using)
2092
1983
 
2093
1984
 
2094
1985
class cmd_deleted(Command):
2095
 
    __doc__ = """List files deleted in the working tree.
 
1986
    """List files deleted in the working tree.
2096
1987
    """
2097
1988
    # TODO: Show files deleted since a previous revision, or
2098
1989
    # between two revisions.
2101
1992
    # level of effort but possibly much less IO.  (Or possibly not,
2102
1993
    # if the directories are very large...)
2103
1994
    _see_also = ['status', 'ls']
2104
 
    takes_options = ['directory', 'show-ids']
 
1995
    takes_options = ['show-ids']
2105
1996
 
2106
1997
    @display_command
2107
 
    def run(self, show_ids=False, directory=u'.'):
2108
 
        tree = WorkingTree.open_containing(directory)[0]
2109
 
        self.add_cleanup(tree.lock_read().unlock)
 
1998
    def run(self, show_ids=False):
 
1999
        tree = WorkingTree.open_containing(u'.')[0]
 
2000
        tree.lock_read()
 
2001
        self.add_cleanup(tree.unlock)
2110
2002
        old = tree.basis_tree()
2111
 
        self.add_cleanup(old.lock_read().unlock)
 
2003
        old.lock_read()
 
2004
        self.add_cleanup(old.unlock)
2112
2005
        for path, ie in old.inventory.iter_entries():
2113
2006
            if not tree.has_id(ie.file_id):
2114
2007
                self.outf.write(path)
2119
2012
 
2120
2013
 
2121
2014
class cmd_modified(Command):
2122
 
    __doc__ = """List files modified in working tree.
 
2015
    """List files modified in working tree.
2123
2016
    """
2124
2017
 
2125
2018
    hidden = True
2126
2019
    _see_also = ['status', 'ls']
2127
 
    takes_options = ['directory', 'null']
 
2020
    takes_options = [
 
2021
            Option('null',
 
2022
                   help='Write an ascii NUL (\\0) separator '
 
2023
                   'between files rather than a newline.')
 
2024
            ]
2128
2025
 
2129
2026
    @display_command
2130
 
    def run(self, null=False, directory=u'.'):
2131
 
        tree = WorkingTree.open_containing(directory)[0]
2132
 
        self.add_cleanup(tree.lock_read().unlock)
 
2027
    def run(self, null=False):
 
2028
        tree = WorkingTree.open_containing(u'.')[0]
2133
2029
        td = tree.changes_from(tree.basis_tree())
2134
 
        self.cleanup_now()
2135
2030
        for path, id, kind, text_modified, meta_modified in td.modified:
2136
2031
            if null:
2137
2032
                self.outf.write(path + '\0')
2140
2035
 
2141
2036
 
2142
2037
class cmd_added(Command):
2143
 
    __doc__ = """List files added in working tree.
 
2038
    """List files added in working tree.
2144
2039
    """
2145
2040
 
2146
2041
    hidden = True
2147
2042
    _see_also = ['status', 'ls']
2148
 
    takes_options = ['directory', 'null']
 
2043
    takes_options = [
 
2044
            Option('null',
 
2045
                   help='Write an ascii NUL (\\0) separator '
 
2046
                   'between files rather than a newline.')
 
2047
            ]
2149
2048
 
2150
2049
    @display_command
2151
 
    def run(self, null=False, directory=u'.'):
2152
 
        wt = WorkingTree.open_containing(directory)[0]
2153
 
        self.add_cleanup(wt.lock_read().unlock)
 
2050
    def run(self, null=False):
 
2051
        wt = WorkingTree.open_containing(u'.')[0]
 
2052
        wt.lock_read()
 
2053
        self.add_cleanup(wt.unlock)
2154
2054
        basis = wt.basis_tree()
2155
 
        self.add_cleanup(basis.lock_read().unlock)
 
2055
        basis.lock_read()
 
2056
        self.add_cleanup(basis.unlock)
2156
2057
        basis_inv = basis.inventory
2157
2058
        inv = wt.inventory
2158
2059
        for file_id in inv:
2159
 
            if basis_inv.has_id(file_id):
 
2060
            if file_id in basis_inv:
2160
2061
                continue
2161
2062
            if inv.is_root(file_id) and len(basis_inv) == 0:
2162
2063
                continue
2163
2064
            path = inv.id2path(file_id)
2164
 
            if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
 
2065
            if not os.access(osutils.abspath(path), os.F_OK):
2165
2066
                continue
2166
2067
            if null:
2167
2068
                self.outf.write(path + '\0')
2170
2071
 
2171
2072
 
2172
2073
class cmd_root(Command):
2173
 
    __doc__ = """Show the tree root directory.
 
2074
    """Show the tree root directory.
2174
2075
 
2175
2076
    The root is the nearest enclosing directory with a .bzr control
2176
2077
    directory."""
2200
2101
 
2201
2102
 
2202
2103
class cmd_log(Command):
2203
 
    __doc__ = """Show historical log for a branch or subset of a branch.
 
2104
    """Show historical log for a branch or subset of a branch.
2204
2105
 
2205
2106
    log is bzr's default tool for exploring the history of a branch.
2206
2107
    The branch to use is taken from the first parameter. If no parameters
2367
2268
                   help='Show just the specified revision.'
2368
2269
                   ' See also "help revisionspec".'),
2369
2270
            'log-format',
2370
 
            RegistryOption('authors',
2371
 
                'What names to list as authors - first, all or committer.',
2372
 
                title='Authors',
2373
 
                lazy_registry=('bzrlib.log', 'author_list_registry'),
2374
 
            ),
2375
2271
            Option('levels',
2376
2272
                   short_name='n',
2377
2273
                   help='Number of levels to display - 0 for all, 1 for flat.',
2392
2288
                   help='Show changes made in each revision as a patch.'),
2393
2289
            Option('include-merges',
2394
2290
                   help='Show merged revisions like --levels 0 does.'),
2395
 
            Option('exclude-common-ancestry',
2396
 
                   help='Display only the revisions that are not part'
2397
 
                   ' of both ancestries (require -rX..Y)'
2398
 
                   ),
2399
 
            Option('signatures',
2400
 
                   help='Show digital signature validity'),
2401
2291
            ]
2402
2292
    encoding_type = 'replace'
2403
2293
 
2413
2303
            message=None,
2414
2304
            limit=None,
2415
2305
            show_diff=False,
2416
 
            include_merges=False,
2417
 
            authors=None,
2418
 
            exclude_common_ancestry=False,
2419
 
            signatures=False,
2420
 
            ):
 
2306
            include_merges=False):
2421
2307
        from bzrlib.log import (
2422
2308
            Logger,
2423
2309
            make_log_request_dict,
2424
2310
            _get_info_for_log_files,
2425
2311
            )
2426
2312
        direction = (forward and 'forward') or 'reverse'
2427
 
        if (exclude_common_ancestry
2428
 
            and (revision is None or len(revision) != 2)):
2429
 
            raise errors.BzrCommandError(
2430
 
                '--exclude-common-ancestry requires -r with two revisions')
2431
2313
        if include_merges:
2432
2314
            if levels is None:
2433
2315
                levels = 0
2449
2331
        if file_list:
2450
2332
            # find the file ids to log and check for directory filtering
2451
2333
            b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2452
 
                revision, file_list, self.add_cleanup)
 
2334
                revision, file_list)
 
2335
            self.add_cleanup(b.unlock)
2453
2336
            for relpath, file_id, kind in file_info_list:
2454
2337
                if file_id is None:
2455
2338
                    raise errors.BzrCommandError(
2473
2356
                location = '.'
2474
2357
            dir, relpath = bzrdir.BzrDir.open_containing(location)
2475
2358
            b = dir.open_branch()
2476
 
            self.add_cleanup(b.lock_read().unlock)
 
2359
            b.lock_read()
 
2360
            self.add_cleanup(b.unlock)
2477
2361
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2478
2362
 
2479
 
        if b.get_config().validate_signatures_in_log():
2480
 
            signatures = True
2481
 
 
2482
 
        if signatures:
2483
 
            if not gpg.GPGStrategy.verify_signatures_available():
2484
 
                raise errors.GpgmeNotInstalled(None)
2485
 
 
2486
2363
        # Decide on the type of delta & diff filtering to use
2487
2364
        # TODO: add an --all-files option to make this configurable & consistent
2488
2365
        if not verbose:
2506
2383
                        show_timezone=timezone,
2507
2384
                        delta_format=get_verbosity_level(),
2508
2385
                        levels=levels,
2509
 
                        show_advice=levels is None,
2510
 
                        author_list_handler=authors)
 
2386
                        show_advice=levels is None)
2511
2387
 
2512
2388
        # Choose the algorithm for doing the logging. It's annoying
2513
2389
        # having multiple code paths like this but necessary until
2532
2408
            direction=direction, specific_fileids=file_ids,
2533
2409
            start_revision=rev1, end_revision=rev2, limit=limit,
2534
2410
            message_search=message, delta_type=delta_type,
2535
 
            diff_type=diff_type, _match_using_deltas=match_using_deltas,
2536
 
            exclude_common_ancestry=exclude_common_ancestry,
2537
 
            signature=signatures
2538
 
            )
 
2411
            diff_type=diff_type, _match_using_deltas=match_using_deltas)
2539
2412
        Logger(b, rqst).show(lf)
2540
2413
 
2541
2414
 
2560
2433
            raise errors.BzrCommandError(
2561
2434
                "bzr %s doesn't accept two revisions in different"
2562
2435
                " branches." % command_name)
2563
 
        if start_spec.spec is None:
2564
 
            # Avoid loading all the history.
2565
 
            rev1 = RevisionInfo(branch, None, None)
2566
 
        else:
2567
 
            rev1 = start_spec.in_history(branch)
 
2436
        rev1 = start_spec.in_history(branch)
2568
2437
        # Avoid loading all of history when we know a missing
2569
2438
        # end of range means the last revision ...
2570
2439
        if end_spec.spec is None:
2599
2468
 
2600
2469
 
2601
2470
class cmd_touching_revisions(Command):
2602
 
    __doc__ = """Return revision-ids which affected a particular file.
 
2471
    """Return revision-ids which affected a particular file.
2603
2472
 
2604
2473
    A more user-friendly interface is "bzr log FILE".
2605
2474
    """
2612
2481
        tree, relpath = WorkingTree.open_containing(filename)
2613
2482
        file_id = tree.path2id(relpath)
2614
2483
        b = tree.branch
2615
 
        self.add_cleanup(b.lock_read().unlock)
 
2484
        b.lock_read()
 
2485
        self.add_cleanup(b.unlock)
2616
2486
        touching_revs = log.find_touching_revisions(b, file_id)
2617
2487
        for revno, revision_id, what in touching_revs:
2618
2488
            self.outf.write("%6d %s\n" % (revno, what))
2619
2489
 
2620
2490
 
2621
2491
class cmd_ls(Command):
2622
 
    __doc__ = """List files in a tree.
 
2492
    """List files in a tree.
2623
2493
    """
2624
2494
 
2625
2495
    _see_also = ['status', 'cat']
2631
2501
                   help='Recurse into subdirectories.'),
2632
2502
            Option('from-root',
2633
2503
                   help='Print paths relative to the root of the branch.'),
2634
 
            Option('unknown', short_name='u',
2635
 
                help='Print unknown files.'),
 
2504
            Option('unknown', help='Print unknown files.'),
2636
2505
            Option('versioned', help='Print versioned files.',
2637
2506
                   short_name='V'),
2638
 
            Option('ignored', short_name='i',
2639
 
                help='Print ignored files.'),
2640
 
            Option('kind', short_name='k',
 
2507
            Option('ignored', help='Print ignored files.'),
 
2508
            Option('null',
 
2509
                   help='Write an ascii NUL (\\0) separator '
 
2510
                   'between files rather than a newline.'),
 
2511
            Option('kind',
2641
2512
                   help='List entries of a particular kind: file, directory, symlink.',
2642
2513
                   type=unicode),
2643
 
            'null',
2644
2514
            'show-ids',
2645
 
            'directory',
2646
2515
            ]
2647
2516
    @display_command
2648
2517
    def run(self, revision=None, verbose=False,
2649
2518
            recursive=False, from_root=False,
2650
2519
            unknown=False, versioned=False, ignored=False,
2651
 
            null=False, kind=None, show_ids=False, path=None, directory=None):
 
2520
            null=False, kind=None, show_ids=False, path=None):
2652
2521
 
2653
2522
        if kind and kind not in ('file', 'directory', 'symlink'):
2654
2523
            raise errors.BzrCommandError('invalid kind specified')
2666
2535
                raise errors.BzrCommandError('cannot specify both --from-root'
2667
2536
                                             ' and PATH')
2668
2537
            fs_path = path
2669
 
        tree, branch, relpath = \
2670
 
            _open_directory_or_containing_tree_or_branch(fs_path, directory)
 
2538
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
2539
            fs_path)
2671
2540
 
2672
2541
        # Calculate the prefix to use
2673
2542
        prefix = None
2688
2557
                view_str = views.view_display_str(view_files)
2689
2558
                note("Ignoring files outside view. View is %s" % view_str)
2690
2559
 
2691
 
        self.add_cleanup(tree.lock_read().unlock)
 
2560
        tree.lock_read()
 
2561
        self.add_cleanup(tree.unlock)
2692
2562
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2693
2563
            from_dir=relpath, recursive=recursive):
2694
2564
            # Apply additional masking
2736
2606
 
2737
2607
 
2738
2608
class cmd_unknowns(Command):
2739
 
    __doc__ = """List unknown files.
 
2609
    """List unknown files.
2740
2610
    """
2741
2611
 
2742
2612
    hidden = True
2743
2613
    _see_also = ['ls']
2744
 
    takes_options = ['directory']
2745
2614
 
2746
2615
    @display_command
2747
 
    def run(self, directory=u'.'):
2748
 
        for f in WorkingTree.open_containing(directory)[0].unknowns():
 
2616
    def run(self):
 
2617
        for f in WorkingTree.open_containing(u'.')[0].unknowns():
2749
2618
            self.outf.write(osutils.quotefn(f) + '\n')
2750
2619
 
2751
2620
 
2752
2621
class cmd_ignore(Command):
2753
 
    __doc__ = """Ignore specified files or patterns.
 
2622
    """Ignore specified files or patterns.
2754
2623
 
2755
2624
    See ``bzr help patterns`` for details on the syntax of patterns.
2756
2625
 
2765
2634
    using this command or directly by using an editor, be sure to commit
2766
2635
    it.
2767
2636
    
2768
 
    Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
2769
 
    the global ignore file can be found in the application data directory as
2770
 
    C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
2771
 
    Global ignores are not touched by this command. The global ignore file
2772
 
    can be edited directly using an editor.
2773
 
 
2774
2637
    Patterns prefixed with '!' are exceptions to ignore patterns and take
2775
2638
    precedence over regular ignores.  Such exceptions are used to specify
2776
2639
    files that should be versioned which would otherwise be ignored.
2778
2641
    Patterns prefixed with '!!' act as regular ignore patterns, but have
2779
2642
    precedence over the '!' exception patterns.
2780
2643
 
2781
 
    :Notes: 
2782
 
        
2783
 
    * Ignore patterns containing shell wildcards must be quoted from
2784
 
      the shell on Unix.
2785
 
 
2786
 
    * Ignore patterns starting with "#" act as comments in the ignore file.
2787
 
      To ignore patterns that begin with that character, use the "RE:" prefix.
 
2644
    Note: ignore patterns containing shell wildcards must be quoted from
 
2645
    the shell on Unix.
2788
2646
 
2789
2647
    :Examples:
2790
2648
        Ignore the top level Makefile::
2799
2657
 
2800
2658
            bzr ignore "!special.class"
2801
2659
 
2802
 
        Ignore files whose name begins with the "#" character::
2803
 
 
2804
 
            bzr ignore "RE:^#"
2805
 
 
2806
2660
        Ignore .o files under the lib directory::
2807
2661
 
2808
2662
            bzr ignore "lib/**/*.o"
2816
2670
            bzr ignore "RE:(?!debian/).*"
2817
2671
        
2818
2672
        Ignore everything except the "local" toplevel directory,
2819
 
        but always ignore autosave files ending in ~, even under local/::
 
2673
        but always ignore "*~" autosave files, even under local/::
2820
2674
        
2821
2675
            bzr ignore "*"
2822
2676
            bzr ignore "!./local"
2825
2679
 
2826
2680
    _see_also = ['status', 'ignored', 'patterns']
2827
2681
    takes_args = ['name_pattern*']
2828
 
    takes_options = ['directory',
2829
 
        Option('default-rules',
2830
 
               help='Display the default ignore rules that bzr uses.')
 
2682
    takes_options = [
 
2683
        Option('old-default-rules',
 
2684
               help='Write out the ignore rules bzr < 0.9 always used.')
2831
2685
        ]
2832
2686
 
2833
 
    def run(self, name_pattern_list=None, default_rules=None,
2834
 
            directory=u'.'):
 
2687
    def run(self, name_pattern_list=None, old_default_rules=None):
2835
2688
        from bzrlib import ignores
2836
 
        if default_rules is not None:
2837
 
            # dump the default rules and exit
2838
 
            for pattern in ignores.USER_DEFAULTS:
 
2689
        if old_default_rules is not None:
 
2690
            # dump the rules and exit
 
2691
            for pattern in ignores.OLD_DEFAULTS:
2839
2692
                self.outf.write("%s\n" % pattern)
2840
2693
            return
2841
2694
        if not name_pattern_list:
2842
2695
            raise errors.BzrCommandError("ignore requires at least one "
2843
 
                "NAME_PATTERN or --default-rules.")
 
2696
                                  "NAME_PATTERN or --old-default-rules")
2844
2697
        name_pattern_list = [globbing.normalize_pattern(p)
2845
2698
                             for p in name_pattern_list]
2846
 
        bad_patterns = ''
2847
 
        for p in name_pattern_list:
2848
 
            if not globbing.Globster.is_pattern_valid(p):
2849
 
                bad_patterns += ('\n  %s' % p)
2850
 
        if bad_patterns:
2851
 
            msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
2852
 
            ui.ui_factory.show_error(msg)
2853
 
            raise errors.InvalidPattern('')
2854
2699
        for name_pattern in name_pattern_list:
2855
2700
            if (name_pattern[0] == '/' or
2856
2701
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
2857
2702
                raise errors.BzrCommandError(
2858
2703
                    "NAME_PATTERN should not be an absolute path")
2859
 
        tree, relpath = WorkingTree.open_containing(directory)
 
2704
        tree, relpath = WorkingTree.open_containing(u'.')
2860
2705
        ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2861
2706
        ignored = globbing.Globster(name_pattern_list)
2862
2707
        matches = []
2863
 
        self.add_cleanup(tree.lock_read().unlock)
 
2708
        tree.lock_read()
2864
2709
        for entry in tree.list_files():
2865
2710
            id = entry[3]
2866
2711
            if id is not None:
2867
2712
                filename = entry[0]
2868
2713
                if ignored.match(filename):
2869
2714
                    matches.append(filename)
 
2715
        tree.unlock()
2870
2716
        if len(matches) > 0:
2871
2717
            self.outf.write("Warning: the following files are version controlled and"
2872
2718
                  " match your ignore pattern:\n%s"
2875
2721
 
2876
2722
 
2877
2723
class cmd_ignored(Command):
2878
 
    __doc__ = """List ignored files and the patterns that matched them.
 
2724
    """List ignored files and the patterns that matched them.
2879
2725
 
2880
2726
    List all the ignored files and the ignore pattern that caused the file to
2881
2727
    be ignored.
2887
2733
 
2888
2734
    encoding_type = 'replace'
2889
2735
    _see_also = ['ignore', 'ls']
2890
 
    takes_options = ['directory']
2891
2736
 
2892
2737
    @display_command
2893
 
    def run(self, directory=u'.'):
2894
 
        tree = WorkingTree.open_containing(directory)[0]
2895
 
        self.add_cleanup(tree.lock_read().unlock)
 
2738
    def run(self):
 
2739
        tree = WorkingTree.open_containing(u'.')[0]
 
2740
        tree.lock_read()
 
2741
        self.add_cleanup(tree.unlock)
2896
2742
        for path, file_class, kind, file_id, entry in tree.list_files():
2897
2743
            if file_class != 'I':
2898
2744
                continue
2902
2748
 
2903
2749
 
2904
2750
class cmd_lookup_revision(Command):
2905
 
    __doc__ = """Lookup the revision-id from a revision-number
 
2751
    """Lookup the revision-id from a revision-number
2906
2752
 
2907
2753
    :Examples:
2908
2754
        bzr lookup-revision 33
2909
2755
    """
2910
2756
    hidden = True
2911
2757
    takes_args = ['revno']
2912
 
    takes_options = ['directory']
2913
2758
 
2914
2759
    @display_command
2915
 
    def run(self, revno, directory=u'.'):
 
2760
    def run(self, revno):
2916
2761
        try:
2917
2762
            revno = int(revno)
2918
2763
        except ValueError:
2919
2764
            raise errors.BzrCommandError("not a valid revision-number: %r"
2920
2765
                                         % revno)
2921
 
        revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
 
2766
        revid = WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2922
2767
        self.outf.write("%s\n" % revid)
2923
2768
 
2924
2769
 
2925
2770
class cmd_export(Command):
2926
 
    __doc__ = """Export current or past revision to a destination directory or archive.
 
2771
    """Export current or past revision to a destination directory or archive.
2927
2772
 
2928
2773
    If no revision is specified this exports the last committed revision.
2929
2774
 
2950
2795
         zip                          .zip
2951
2796
      =================       =========================
2952
2797
    """
2953
 
    encoding = 'exact'
2954
2798
    takes_args = ['dest', 'branch_or_subdir?']
2955
 
    takes_options = ['directory',
 
2799
    takes_options = [
2956
2800
        Option('format',
2957
2801
               help="Type of file to export to.",
2958
2802
               type=unicode),
2962
2806
        Option('root',
2963
2807
               type=str,
2964
2808
               help="Name of the root directory inside the exported file."),
2965
 
        Option('per-file-timestamps',
2966
 
               help='Set modification time of files to that of the last '
2967
 
                    'revision in which it was changed.'),
2968
2809
        ]
2969
2810
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2970
 
        root=None, filters=False, per_file_timestamps=False, directory=u'.'):
 
2811
        root=None, filters=False):
2971
2812
        from bzrlib.export import export
2972
2813
 
2973
2814
        if branch_or_subdir is None:
2974
 
            tree = WorkingTree.open_containing(directory)[0]
 
2815
            tree = WorkingTree.open_containing(u'.')[0]
2975
2816
            b = tree.branch
2976
2817
            subdir = None
2977
2818
        else:
2980
2821
 
2981
2822
        rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2982
2823
        try:
2983
 
            export(rev_tree, dest, format, root, subdir, filtered=filters,
2984
 
                   per_file_timestamps=per_file_timestamps)
 
2824
            export(rev_tree, dest, format, root, subdir, filtered=filters)
2985
2825
        except errors.NoSuchExportFormat, e:
2986
2826
            raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
2987
2827
 
2988
2828
 
2989
2829
class cmd_cat(Command):
2990
 
    __doc__ = """Write the contents of a file as of a given revision to standard output.
 
2830
    """Write the contents of a file as of a given revision to standard output.
2991
2831
 
2992
2832
    If no revision is nominated, the last revision is used.
2993
2833
 
2996
2836
    """
2997
2837
 
2998
2838
    _see_also = ['ls']
2999
 
    takes_options = ['directory',
 
2839
    takes_options = [
3000
2840
        Option('name-from-revision', help='The path name in the old tree.'),
3001
2841
        Option('filters', help='Apply content filters to display the '
3002
2842
                'convenience form.'),
3007
2847
 
3008
2848
    @display_command
3009
2849
    def run(self, filename, revision=None, name_from_revision=False,
3010
 
            filters=False, directory=None):
 
2850
            filters=False):
3011
2851
        if revision is not None and len(revision) != 1:
3012
2852
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
3013
2853
                                         " one revision specifier")
3014
2854
        tree, branch, relpath = \
3015
 
            _open_directory_or_containing_tree_or_branch(filename, directory)
3016
 
        self.add_cleanup(branch.lock_read().unlock)
 
2855
            bzrdir.BzrDir.open_containing_tree_or_branch(filename)
 
2856
        branch.lock_read()
 
2857
        self.add_cleanup(branch.unlock)
3017
2858
        return self._run(tree, branch, relpath, filename, revision,
3018
2859
                         name_from_revision, filters)
3019
2860
 
3022
2863
        if tree is None:
3023
2864
            tree = b.basis_tree()
3024
2865
        rev_tree = _get_one_revision_tree('cat', revision, branch=b)
3025
 
        self.add_cleanup(rev_tree.lock_read().unlock)
 
2866
        rev_tree.lock_read()
 
2867
        self.add_cleanup(rev_tree.unlock)
3026
2868
 
3027
2869
        old_file_id = rev_tree.path2id(relpath)
3028
2870
 
3071
2913
 
3072
2914
 
3073
2915
class cmd_local_time_offset(Command):
3074
 
    __doc__ = """Show the offset in seconds from GMT to local time."""
 
2916
    """Show the offset in seconds from GMT to local time."""
3075
2917
    hidden = True
3076
2918
    @display_command
3077
2919
    def run(self):
3080
2922
 
3081
2923
 
3082
2924
class cmd_commit(Command):
3083
 
    __doc__ = """Commit changes into a new revision.
 
2925
    """Commit changes into a new revision.
3084
2926
 
3085
2927
    An explanatory message needs to be given for each commit. This is
3086
2928
    often done by using the --message option (getting the message from the
3134
2976
      to trigger updates to external systems like bug trackers. The --fixes
3135
2977
      option can be used to record the association between a revision and
3136
2978
      one or more bugs. See ``bzr help bugs`` for details.
 
2979
 
 
2980
      A selective commit may fail in some cases where the committed
 
2981
      tree would be invalid. Consider::
 
2982
  
 
2983
        bzr init foo
 
2984
        mkdir foo/bar
 
2985
        bzr add foo/bar
 
2986
        bzr commit foo -m "committing foo"
 
2987
        bzr mv foo/bar foo/baz
 
2988
        mkdir foo/bar
 
2989
        bzr add foo/bar
 
2990
        bzr commit foo/bar -m "committing bar but not baz"
 
2991
  
 
2992
      In the example above, the last commit will fail by design. This gives
 
2993
      the user the opportunity to decide whether they want to commit the
 
2994
      rename at the same time, separately first, or not at all. (As a general
 
2995
      rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
3137
2996
    """
 
2997
    # TODO: Run hooks on tree to-be-committed, and after commit.
 
2998
 
 
2999
    # TODO: Strict commit that fails if there are deleted files.
 
3000
    #       (what does "deleted files" mean ??)
 
3001
 
 
3002
    # TODO: Give better message for -s, --summary, used by tla people
 
3003
 
 
3004
    # XXX: verbose currently does nothing
3138
3005
 
3139
3006
    _see_also = ['add', 'bugs', 'hooks', 'uncommit']
3140
3007
    takes_args = ['selected*']
3169
3036
                         "the master branch until a normal commit "
3170
3037
                         "is performed."
3171
3038
                    ),
3172
 
             Option('show-diff', short_name='p',
 
3039
             Option('show-diff',
3173
3040
                    help='When no message is supplied, show the diff along'
3174
3041
                    ' with the status summary in the message editor.'),
3175
 
             Option('lossy', 
3176
 
                    help='When committing to a foreign version control '
3177
 
                    'system do not push data that can not be natively '
3178
 
                    'represented.'),
3179
3042
             ]
3180
3043
    aliases = ['ci', 'checkin']
3181
3044
 
3200
3063
 
3201
3064
    def run(self, message=None, file=None, verbose=False, selected_list=None,
3202
3065
            unchanged=False, strict=False, local=False, fixes=None,
3203
 
            author=None, show_diff=False, exclude=None, commit_time=None,
3204
 
            lossy=False):
 
3066
            author=None, show_diff=False, exclude=None, commit_time=None):
3205
3067
        from bzrlib.errors import (
3206
3068
            PointlessCommit,
3207
3069
            ConflictsInTree,
3210
3072
        from bzrlib.msgeditor import (
3211
3073
            edit_commit_message_encoded,
3212
3074
            generate_commit_message_template,
3213
 
            make_commit_message_template_encoded,
3214
 
            set_commit_message,
 
3075
            make_commit_message_template_encoded
3215
3076
        )
3216
3077
 
3217
3078
        commit_stamp = offset = None
3222
3083
                raise errors.BzrCommandError(
3223
3084
                    "Could not parse --commit-time: " + str(e))
3224
3085
 
 
3086
        # TODO: Need a blackbox test for invoking the external editor; may be
 
3087
        # slightly problematic to run this cross-platform.
 
3088
 
 
3089
        # TODO: do more checks that the commit will succeed before
 
3090
        # spending the user's valuable time typing a commit message.
 
3091
 
3225
3092
        properties = {}
3226
3093
 
3227
 
        tree, selected_list = WorkingTree.open_containing_paths(selected_list)
 
3094
        tree, selected_list = tree_files(selected_list)
3228
3095
        if selected_list == ['']:
3229
3096
            # workaround - commit of root of tree should be exactly the same
3230
3097
            # as just default commit in that tree, and succeed even though
3255
3122
                    '(use --file "%(f)s" to take commit message from that file)'
3256
3123
                    % { 'f': message })
3257
3124
                ui.ui_factory.show_warning(warning_msg)
3258
 
            if '\r' in message:
3259
 
                message = message.replace('\r\n', '\n')
3260
 
                message = message.replace('\r', '\n')
3261
 
            if file:
3262
 
                raise errors.BzrCommandError(
3263
 
                    "please specify either --message or --file")
3264
3125
 
3265
3126
        def get_message(commit_obj):
3266
3127
            """Callback to get commit message"""
3267
 
            if file:
3268
 
                f = open(file)
3269
 
                try:
3270
 
                    my_message = f.read().decode(osutils.get_user_encoding())
3271
 
                finally:
3272
 
                    f.close()
3273
 
            elif message is not None:
3274
 
                my_message = message
3275
 
            else:
3276
 
                # No message supplied: make one up.
3277
 
                # text is the status of the tree
3278
 
                text = make_commit_message_template_encoded(tree,
 
3128
            my_message = message
 
3129
            if my_message is not None and '\r' in my_message:
 
3130
                my_message = my_message.replace('\r\n', '\n')
 
3131
                my_message = my_message.replace('\r', '\n')
 
3132
            if my_message is None and not file:
 
3133
                t = make_commit_message_template_encoded(tree,
3279
3134
                        selected_list, diff=show_diff,
3280
3135
                        output_encoding=osutils.get_user_encoding())
3281
 
                # start_message is the template generated from hooks
3282
 
                # XXX: Warning - looks like hooks return unicode,
3283
 
                # make_commit_message_template_encoded returns user encoding.
3284
 
                # We probably want to be using edit_commit_message instead to
3285
 
                # avoid this.
3286
 
                my_message = set_commit_message(commit_obj)
3287
 
                if my_message is None:
3288
 
                    start_message = generate_commit_message_template(commit_obj)
3289
 
                    my_message = edit_commit_message_encoded(text,
3290
 
                        start_message=start_message)
 
3136
                start_message = generate_commit_message_template(commit_obj)
 
3137
                my_message = edit_commit_message_encoded(t,
 
3138
                    start_message=start_message)
3291
3139
                if my_message is None:
3292
3140
                    raise errors.BzrCommandError("please specify a commit"
3293
3141
                        " message with either --message or --file")
 
3142
            elif my_message and file:
 
3143
                raise errors.BzrCommandError(
 
3144
                    "please specify either --message or --file")
 
3145
            if file:
 
3146
                my_message = codecs.open(file, 'rt',
 
3147
                                         osutils.get_user_encoding()).read()
3294
3148
            if my_message == "":
3295
3149
                raise errors.BzrCommandError("empty commit message specified")
3296
3150
            return my_message
3306
3160
                        reporter=None, verbose=verbose, revprops=properties,
3307
3161
                        authors=author, timestamp=commit_stamp,
3308
3162
                        timezone=offset,
3309
 
                        exclude=tree.safe_relpath_files(exclude),
3310
 
                        lossy=lossy)
 
3163
                        exclude=safe_relpath_files(tree, exclude))
3311
3164
        except PointlessCommit:
 
3165
            # FIXME: This should really happen before the file is read in;
 
3166
            # perhaps prepare the commit; get the message; then actually commit
3312
3167
            raise errors.BzrCommandError("No changes to commit."
3313
 
                " Please 'bzr add' the files you want to commit, or use"
3314
 
                " --unchanged to force an empty commit.")
 
3168
                              " Use --unchanged to commit anyhow.")
3315
3169
        except ConflictsInTree:
3316
3170
            raise errors.BzrCommandError('Conflicts detected in working '
3317
3171
                'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
3328
3182
 
3329
3183
 
3330
3184
class cmd_check(Command):
3331
 
    __doc__ = """Validate working tree structure, branch consistency and repository history.
 
3185
    """Validate working tree structure, branch consistency and repository history.
3332
3186
 
3333
3187
    This command checks various invariants about branch and repository storage
3334
3188
    to detect data corruption or bzr bugs.
3398
3252
 
3399
3253
 
3400
3254
class cmd_upgrade(Command):
3401
 
    __doc__ = """Upgrade a repository, branch or working tree to a newer format.
3402
 
 
3403
 
    When the default format has changed after a major new release of
3404
 
    Bazaar, you may be informed during certain operations that you
3405
 
    should upgrade. Upgrading to a newer format may improve performance
3406
 
    or make new features available. It may however limit interoperability
3407
 
    with older repositories or with older versions of Bazaar.
3408
 
 
3409
 
    If you wish to upgrade to a particular format rather than the
3410
 
    current default, that can be specified using the --format option.
3411
 
    As a consequence, you can use the upgrade command this way to
3412
 
    "downgrade" to an earlier format, though some conversions are
3413
 
    a one way process (e.g. changing from the 1.x default to the
3414
 
    2.x default) so downgrading is not always possible.
3415
 
 
3416
 
    A backup.bzr.~#~ directory is created at the start of the conversion
3417
 
    process (where # is a number). By default, this is left there on
3418
 
    completion. If the conversion fails, delete the new .bzr directory
3419
 
    and rename this one back in its place. Use the --clean option to ask
3420
 
    for the backup.bzr directory to be removed on successful conversion.
3421
 
    Alternatively, you can delete it by hand if everything looks good
3422
 
    afterwards.
3423
 
 
3424
 
    If the location given is a shared repository, dependent branches
3425
 
    are also converted provided the repository converts successfully.
3426
 
    If the conversion of a branch fails, remaining branches are still
3427
 
    tried.
3428
 
 
3429
 
    For more information on upgrades, see the Bazaar Upgrade Guide,
3430
 
    http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
 
3255
    """Upgrade branch storage to current format.
 
3256
 
 
3257
    The check command or bzr developers may sometimes advise you to run
 
3258
    this command. When the default format has changed you may also be warned
 
3259
    during other operations to upgrade.
3431
3260
    """
3432
3261
 
3433
 
    _see_also = ['check', 'reconcile', 'formats']
 
3262
    _see_also = ['check']
3434
3263
    takes_args = ['url?']
3435
3264
    takes_options = [
3436
 
        RegistryOption('format',
3437
 
            help='Upgrade to a specific format.  See "bzr help'
3438
 
                 ' formats" for details.',
3439
 
            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3440
 
            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3441
 
            value_switches=True, title='Branch format'),
3442
 
        Option('clean',
3443
 
            help='Remove the backup.bzr directory if successful.'),
3444
 
        Option('dry-run',
3445
 
            help="Show what would be done, but don't actually do anything."),
3446
 
    ]
 
3265
                    RegistryOption('format',
 
3266
                        help='Upgrade to a specific format.  See "bzr help'
 
3267
                             ' formats" for details.',
 
3268
                        lazy_registry=('bzrlib.bzrdir', 'format_registry'),
 
3269
                        converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
 
3270
                        value_switches=True, title='Branch format'),
 
3271
                    ]
3447
3272
 
3448
 
    def run(self, url='.', format=None, clean=False, dry_run=False):
 
3273
    def run(self, url='.', format=None):
3449
3274
        from bzrlib.upgrade import upgrade
3450
 
        exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
3451
 
        if exceptions:
3452
 
            if len(exceptions) == 1:
3453
 
                # Compatibility with historical behavior
3454
 
                raise exceptions[0]
3455
 
            else:
3456
 
                return 3
 
3275
        upgrade(url, format)
3457
3276
 
3458
3277
 
3459
3278
class cmd_whoami(Command):
3460
 
    __doc__ = """Show or set bzr user id.
 
3279
    """Show or set bzr user id.
3461
3280
 
3462
3281
    :Examples:
3463
3282
        Show the email of the current user::
3468
3287
 
3469
3288
            bzr whoami "Frank Chu <fchu@example.com>"
3470
3289
    """
3471
 
    takes_options = [ 'directory',
3472
 
                      Option('email',
 
3290
    takes_options = [ Option('email',
3473
3291
                             help='Display email address only.'),
3474
3292
                      Option('branch',
3475
3293
                             help='Set identity for the current branch instead of '
3479
3297
    encoding_type = 'replace'
3480
3298
 
3481
3299
    @display_command
3482
 
    def run(self, email=False, branch=False, name=None, directory=None):
 
3300
    def run(self, email=False, branch=False, name=None):
3483
3301
        if name is None:
3484
 
            if directory is None:
3485
 
                # use branch if we're inside one; otherwise global config
3486
 
                try:
3487
 
                    c = Branch.open_containing(u'.')[0].get_config()
3488
 
                except errors.NotBranchError:
3489
 
                    c = _mod_config.GlobalConfig()
3490
 
            else:
3491
 
                c = Branch.open(directory).get_config()
 
3302
            # use branch if we're inside one; otherwise global config
 
3303
            try:
 
3304
                c = Branch.open_containing('.')[0].get_config()
 
3305
            except errors.NotBranchError:
 
3306
                c = config.GlobalConfig()
3492
3307
            if email:
3493
3308
                self.outf.write(c.user_email() + '\n')
3494
3309
            else:
3495
3310
                self.outf.write(c.username() + '\n')
3496
3311
            return
3497
3312
 
3498
 
        if email:
3499
 
            raise errors.BzrCommandError("--email can only be used to display existing "
3500
 
                                         "identity")
3501
 
 
3502
3313
        # display a warning if an email address isn't included in the given name.
3503
3314
        try:
3504
 
            _mod_config.extract_email_address(name)
 
3315
            config.extract_email_address(name)
3505
3316
        except errors.NoEmailInUsername, e:
3506
3317
            warning('"%s" does not seem to contain an email address.  '
3507
3318
                    'This is allowed, but not recommended.', name)
3508
3319
 
3509
3320
        # use global config unless --branch given
3510
3321
        if branch:
3511
 
            if directory is None:
3512
 
                c = Branch.open_containing(u'.')[0].get_config()
3513
 
            else:
3514
 
                c = Branch.open(directory).get_config()
 
3322
            c = Branch.open_containing('.')[0].get_config()
3515
3323
        else:
3516
 
            c = _mod_config.GlobalConfig()
 
3324
            c = config.GlobalConfig()
3517
3325
        c.set_user_option('email', name)
3518
3326
 
3519
3327
 
3520
3328
class cmd_nick(Command):
3521
 
    __doc__ = """Print or set the branch nickname.
 
3329
    """Print or set the branch nickname.
3522
3330
 
3523
3331
    If unset, the tree root directory name is used as the nickname.
3524
3332
    To print the current nickname, execute with no argument.
3529
3337
 
3530
3338
    _see_also = ['info']
3531
3339
    takes_args = ['nickname?']
3532
 
    takes_options = ['directory']
3533
 
    def run(self, nickname=None, directory=u'.'):
3534
 
        branch = Branch.open_containing(directory)[0]
 
3340
    def run(self, nickname=None):
 
3341
        branch = Branch.open_containing(u'.')[0]
3535
3342
        if nickname is None:
3536
3343
            self.printme(branch)
3537
3344
        else:
3543
3350
 
3544
3351
 
3545
3352
class cmd_alias(Command):
3546
 
    __doc__ = """Set/unset and display aliases.
 
3353
    """Set/unset and display aliases.
3547
3354
 
3548
3355
    :Examples:
3549
3356
        Show the current aliases::
3586
3393
                'bzr alias --remove expects an alias to remove.')
3587
3394
        # If alias is not found, print something like:
3588
3395
        # unalias: foo: not found
3589
 
        c = _mod_config.GlobalConfig()
 
3396
        c = config.GlobalConfig()
3590
3397
        c.unset_alias(alias_name)
3591
3398
 
3592
3399
    @display_command
3593
3400
    def print_aliases(self):
3594
3401
        """Print out the defined aliases in a similar format to bash."""
3595
 
        aliases = _mod_config.GlobalConfig().get_aliases()
 
3402
        aliases = config.GlobalConfig().get_aliases()
3596
3403
        for key, value in sorted(aliases.iteritems()):
3597
3404
            self.outf.write('bzr alias %s="%s"\n' % (key, value))
3598
3405
 
3608
3415
 
3609
3416
    def set_alias(self, alias_name, alias_command):
3610
3417
        """Save the alias in the global config."""
3611
 
        c = _mod_config.GlobalConfig()
 
3418
        c = config.GlobalConfig()
3612
3419
        c.set_alias(alias_name, alias_command)
3613
3420
 
3614
3421
 
3615
3422
class cmd_selftest(Command):
3616
 
    __doc__ = """Run internal test suite.
 
3423
    """Run internal test suite.
3617
3424
 
3618
3425
    If arguments are given, they are regular expressions that say which tests
3619
3426
    should run.  Tests matching any expression are run, and other tests are
3649
3456
    If you set BZR_TEST_PDB=1 when running selftest, failing tests will drop
3650
3457
    into a pdb postmortem session.
3651
3458
 
3652
 
    The --coverage=DIRNAME global option produces a report with covered code
3653
 
    indicated.
3654
 
 
3655
3459
    :Examples:
3656
3460
        Run only tests relating to 'ignore'::
3657
3461
 
3668
3472
        if typestring == "sftp":
3669
3473
            from bzrlib.tests import stub_sftp
3670
3474
            return stub_sftp.SFTPAbsoluteServer
3671
 
        elif typestring == "memory":
 
3475
        if typestring == "memory":
3672
3476
            from bzrlib.tests import test_server
3673
3477
            return memory.MemoryServer
3674
 
        elif typestring == "fakenfs":
 
3478
        if typestring == "fakenfs":
3675
3479
            from bzrlib.tests import test_server
3676
3480
            return test_server.FakeNFSServer
3677
3481
        msg = "No known transport type %s. Supported types are: sftp\n" %\
3690
3494
                                 'throughout the test suite.',
3691
3495
                            type=get_transport_type),
3692
3496
                     Option('benchmark',
3693
 
                            help='Run the benchmarks rather than selftests.',
3694
 
                            hidden=True),
 
3497
                            help='Run the benchmarks rather than selftests.'),
3695
3498
                     Option('lsprof-timed',
3696
3499
                            help='Generate lsprof output for benchmarked'
3697
3500
                                 ' sections of code.'),
3698
3501
                     Option('lsprof-tests',
3699
3502
                            help='Generate lsprof output for each test.'),
 
3503
                     Option('cache-dir', type=str,
 
3504
                            help='Cache intermediate benchmark output in this '
 
3505
                                 'directory.'),
3700
3506
                     Option('first',
3701
3507
                            help='Run all tests, but run specified tests first.',
3702
3508
                            short_name='f',
3711
3517
                     Option('randomize', type=str, argname="SEED",
3712
3518
                            help='Randomize the order of tests using the given'
3713
3519
                                 ' seed or "now" for the current time.'),
3714
 
                     ListOption('exclude', type=str, argname="PATTERN",
3715
 
                                short_name='x',
3716
 
                                help='Exclude tests that match this regular'
3717
 
                                ' expression.'),
 
3520
                     Option('exclude', type=str, argname="PATTERN",
 
3521
                            short_name='x',
 
3522
                            help='Exclude tests that match this regular'
 
3523
                                 ' expression.'),
3718
3524
                     Option('subunit',
3719
3525
                        help='Output test progress via subunit.'),
3720
3526
                     Option('strict', help='Fail on missing dependencies or '
3736
3542
 
3737
3543
    def run(self, testspecs_list=None, verbose=False, one=False,
3738
3544
            transport=None, benchmark=None,
3739
 
            lsprof_timed=None,
 
3545
            lsprof_timed=None, cache_dir=None,
3740
3546
            first=False, list_only=False,
3741
3547
            randomize=None, exclude=None, strict=False,
3742
3548
            load_list=None, debugflag=None, starting_with=None, subunit=False,
3743
3549
            parallel=None, lsprof_tests=False):
3744
 
        from bzrlib import tests
3745
 
 
 
3550
        from bzrlib.tests import selftest
 
3551
        import bzrlib.benchmarks as benchmarks
 
3552
        from bzrlib.benchmarks import tree_creator
 
3553
 
 
3554
        # Make deprecation warnings visible, unless -Werror is set
 
3555
        symbol_versioning.activate_deprecation_warnings(override=False)
 
3556
 
 
3557
        if cache_dir is not None:
 
3558
            tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
3746
3559
        if testspecs_list is not None:
3747
3560
            pattern = '|'.join(testspecs_list)
3748
3561
        else:
3754
3567
                raise errors.BzrCommandError("subunit not available. subunit "
3755
3568
                    "needs to be installed to use --subunit.")
3756
3569
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3757
 
            # On Windows, disable automatic conversion of '\n' to '\r\n' in
3758
 
            # stdout, which would corrupt the subunit stream. 
3759
 
            # FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3760
 
            # following code can be deleted when it's sufficiently deployed
3761
 
            # -- vila/mgz 20100514
3762
 
            if (sys.platform == "win32"
3763
 
                and getattr(sys.stdout, 'fileno', None) is not None):
3764
 
                import msvcrt
3765
 
                msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3766
3570
        if parallel:
3767
3571
            self.additional_selftest_args.setdefault(
3768
3572
                'suite_decorators', []).append(parallel)
3769
3573
        if benchmark:
3770
 
            raise errors.BzrCommandError(
3771
 
                "--benchmark is no longer supported from bzr 2.2; "
3772
 
                "use bzr-usertest instead")
3773
 
        test_suite_factory = None
3774
 
        if not exclude:
3775
 
            exclude_pattern = None
 
3574
            test_suite_factory = benchmarks.test_suite
 
3575
            # Unless user explicitly asks for quiet, be verbose in benchmarks
 
3576
            verbose = not is_quiet()
 
3577
            # TODO: should possibly lock the history file...
 
3578
            benchfile = open(".perf_history", "at", buffering=1)
 
3579
            self.add_cleanup(benchfile.close)
3776
3580
        else:
3777
 
            exclude_pattern = '(' + '|'.join(exclude) + ')'
 
3581
            test_suite_factory = None
 
3582
            benchfile = None
3778
3583
        selftest_kwargs = {"verbose": verbose,
3779
3584
                          "pattern": pattern,
3780
3585
                          "stop_on_failure": one,
3782
3587
                          "test_suite_factory": test_suite_factory,
3783
3588
                          "lsprof_timed": lsprof_timed,
3784
3589
                          "lsprof_tests": lsprof_tests,
 
3590
                          "bench_history": benchfile,
3785
3591
                          "matching_tests_first": first,
3786
3592
                          "list_only": list_only,
3787
3593
                          "random_seed": randomize,
3788
 
                          "exclude_pattern": exclude_pattern,
 
3594
                          "exclude_pattern": exclude,
3789
3595
                          "strict": strict,
3790
3596
                          "load_list": load_list,
3791
3597
                          "debug_flags": debugflag,
3792
3598
                          "starting_with": starting_with
3793
3599
                          }
3794
3600
        selftest_kwargs.update(self.additional_selftest_args)
3795
 
 
3796
 
        # Make deprecation warnings visible, unless -Werror is set
3797
 
        cleanup = symbol_versioning.activate_deprecation_warnings(
3798
 
            override=False)
3799
 
        try:
3800
 
            result = tests.selftest(**selftest_kwargs)
3801
 
        finally:
3802
 
            cleanup()
 
3601
        result = selftest(**selftest_kwargs)
3803
3602
        return int(not result)
3804
3603
 
3805
3604
 
3806
3605
class cmd_version(Command):
3807
 
    __doc__ = """Show version of bzr."""
 
3606
    """Show version of bzr."""
3808
3607
 
3809
3608
    encoding_type = 'replace'
3810
3609
    takes_options = [
3821
3620
 
3822
3621
 
3823
3622
class cmd_rocks(Command):
3824
 
    __doc__ = """Statement of optimism."""
 
3623
    """Statement of optimism."""
3825
3624
 
3826
3625
    hidden = True
3827
3626
 
3831
3630
 
3832
3631
 
3833
3632
class cmd_find_merge_base(Command):
3834
 
    __doc__ = """Find and print a base revision for merging two branches."""
 
3633
    """Find and print a base revision for merging two branches."""
3835
3634
    # TODO: Options to specify revisions on either side, as if
3836
3635
    #       merging only part of the history.
3837
3636
    takes_args = ['branch', 'other']
3843
3642
 
3844
3643
        branch1 = Branch.open_containing(branch)[0]
3845
3644
        branch2 = Branch.open_containing(other)[0]
3846
 
        self.add_cleanup(branch1.lock_read().unlock)
3847
 
        self.add_cleanup(branch2.lock_read().unlock)
 
3645
        branch1.lock_read()
 
3646
        self.add_cleanup(branch1.unlock)
 
3647
        branch2.lock_read()
 
3648
        self.add_cleanup(branch2.unlock)
3848
3649
        last1 = ensure_null(branch1.last_revision())
3849
3650
        last2 = ensure_null(branch2.last_revision())
3850
3651
 
3855
3656
 
3856
3657
 
3857
3658
class cmd_merge(Command):
3858
 
    __doc__ = """Perform a three-way merge.
 
3659
    """Perform a three-way merge.
3859
3660
 
3860
3661
    The source of the merge can be specified either in the form of a branch,
3861
3662
    or in the form of a path to a file containing a merge directive generated
3862
3663
    with bzr send. If neither is specified, the default is the upstream branch
3863
 
    or the branch most recently merged using --remember.  The source of the
3864
 
    merge may also be specified in the form of a path to a file in another
3865
 
    branch:  in this case, only the modifications to that file are merged into
3866
 
    the current working tree.
3867
 
 
3868
 
    When merging from a branch, by default bzr will try to merge in all new
3869
 
    work from the other branch, automatically determining an appropriate base
3870
 
    revision.  If this fails, you may need to give an explicit base.
3871
 
 
3872
 
    To pick a different ending revision, pass "--revision OTHER".  bzr will
3873
 
    try to merge in all new work up to and including revision OTHER.
3874
 
 
3875
 
    If you specify two values, "--revision BASE..OTHER", only revisions BASE
3876
 
    through OTHER, excluding BASE but including OTHER, will be merged.  If this
3877
 
    causes some revisions to be skipped, i.e. if the destination branch does
3878
 
    not already contain revision BASE, such a merge is commonly referred to as
3879
 
    a "cherrypick". Unlike a normal merge, Bazaar does not currently track
3880
 
    cherrypicks. The changes look like a normal commit, and the history of the
3881
 
    changes from the other branch is not stored in the commit.
3882
 
 
3883
 
    Revision numbers are always relative to the source branch.
 
3664
    or the branch most recently merged using --remember.
 
3665
 
 
3666
    When merging a branch, by default the tip will be merged. To pick a different
 
3667
    revision, pass --revision. If you specify two values, the first will be used as
 
3668
    BASE and the second one as OTHER. Merging individual revisions, or a subset of
 
3669
    available revisions, like this is commonly referred to as "cherrypicking".
 
3670
 
 
3671
    Revision numbers are always relative to the branch being merged.
 
3672
 
 
3673
    By default, bzr will try to merge in all new work from the other
 
3674
    branch, automatically determining an appropriate base.  If this
 
3675
    fails, you may need to give an explicit base.
3884
3676
 
3885
3677
    Merge will do its best to combine the changes in two branches, but there
3886
3678
    are some kinds of problems only a human can fix.  When it encounters those,
3889
3681
 
3890
3682
    Use bzr resolve when you have fixed a problem.  See also bzr conflicts.
3891
3683
 
3892
 
    If there is no default branch set, the first merge will set it (use
3893
 
    --no-remember to avoid settting it). After that, you can omit the branch
3894
 
    to use the default.  To change the default, use --remember. The value will
3895
 
    only be saved if the remote location can be accessed.
 
3684
    If there is no default branch set, the first merge will set it. After
 
3685
    that, you can omit the branch to use the default.  To change the
 
3686
    default, use --remember. The value will only be saved if the remote
 
3687
    location can be accessed.
3896
3688
 
3897
3689
    The results of the merge are placed into the destination working
3898
3690
    directory, where they can be reviewed (with bzr diff), tested, and then
3899
3691
    committed to record the result of the merge.
3900
3692
 
3901
3693
    merge refuses to run if there are any uncommitted changes, unless
3902
 
    --force is given.  If --force is given, then the changes from the source 
3903
 
    will be merged with the current working tree, including any uncommitted
3904
 
    changes in the tree.  The --force option can also be used to create a
 
3694
    --force is given. The --force option can also be used to create a
3905
3695
    merge revision which has more than two parents.
3906
3696
 
3907
3697
    If one would like to merge changes from the working tree of the other
3912
3702
    you to apply each diff hunk and file change, similar to "shelve".
3913
3703
 
3914
3704
    :Examples:
3915
 
        To merge all new revisions from bzr.dev::
 
3705
        To merge the latest revision from bzr.dev::
3916
3706
 
3917
3707
            bzr merge ../bzr.dev
3918
3708
 
3955
3745
                ' completely merged into the source, pull from the'
3956
3746
                ' source rather than merging.  When this happens,'
3957
3747
                ' you do not need to commit the result.'),
3958
 
        custom_help('directory',
 
3748
        Option('directory',
3959
3749
               help='Branch to merge into, '
3960
 
                    'rather than the one containing the working directory.'),
 
3750
                    'rather than the one containing the working directory.',
 
3751
               short_name='d',
 
3752
               type=unicode,
 
3753
               ),
3961
3754
        Option('preview', help='Instead of merging, show a diff of the'
3962
3755
               ' merge.'),
3963
3756
        Option('interactive', help='Select changes interactively.',
3965
3758
    ]
3966
3759
 
3967
3760
    def run(self, location=None, revision=None, force=False,
3968
 
            merge_type=None, show_base=False, reprocess=None, remember=None,
 
3761
            merge_type=None, show_base=False, reprocess=None, remember=False,
3969
3762
            uncommitted=False, pull=False,
3970
3763
            directory=None,
3971
3764
            preview=False,
3979
3772
        merger = None
3980
3773
        allow_pending = True
3981
3774
        verified = 'inapplicable'
3982
 
 
3983
3775
        tree = WorkingTree.open_containing(directory)[0]
3984
 
        if tree.branch.revno() == 0:
3985
 
            raise errors.BzrCommandError('Merging into empty branches not currently supported, '
3986
 
                                         'https://bugs.launchpad.net/bzr/+bug/308562')
3987
3776
 
3988
3777
        try:
3989
3778
            basis_tree = tree.revision_tree(tree.last_revision())
4000
3789
            unversioned_filter=tree.is_ignored, view_info=view_info)
4001
3790
        pb = ui.ui_factory.nested_progress_bar()
4002
3791
        self.add_cleanup(pb.finished)
4003
 
        self.add_cleanup(tree.lock_write().unlock)
 
3792
        tree.lock_write()
 
3793
        self.add_cleanup(tree.unlock)
4004
3794
        if location is not None:
4005
3795
            try:
4006
3796
                mergeable = bundle.read_mergeable_from_url(location,
4035
3825
        self.sanity_check_merger(merger)
4036
3826
        if (merger.base_rev_id == merger.other_rev_id and
4037
3827
            merger.other_rev_id is not None):
4038
 
            # check if location is a nonexistent file (and not a branch) to
4039
 
            # disambiguate the 'Nothing to do'
4040
 
            if merger.interesting_files:
4041
 
                if not merger.other_tree.has_filename(
4042
 
                    merger.interesting_files[0]):
4043
 
                    note("merger: " + str(merger))
4044
 
                    raise errors.PathsDoNotExist([location])
4045
3828
            note('Nothing to do.')
4046
3829
            return 0
4047
 
        if pull and not preview:
 
3830
        if pull:
4048
3831
            if merger.interesting_files is not None:
4049
3832
                raise errors.BzrCommandError('Cannot pull individual files')
4050
3833
            if (merger.base_rev_id == tree.last_revision()):
4074
3857
    def _do_preview(self, merger):
4075
3858
        from bzrlib.diff import show_diff_trees
4076
3859
        result_tree = self._get_preview(merger)
4077
 
        path_encoding = osutils.get_diff_header_encoding()
4078
3860
        show_diff_trees(merger.this_tree, result_tree, self.outf,
4079
 
                        old_label='', new_label='',
4080
 
                        path_encoding=path_encoding)
 
3861
                        old_label='', new_label='')
4081
3862
 
4082
3863
    def _do_merge(self, merger, change_reporter, allow_pending, verified):
4083
3864
        merger.change_reporter = change_reporter
4159
3940
        if other_revision_id is None:
4160
3941
            other_revision_id = _mod_revision.ensure_null(
4161
3942
                other_branch.last_revision())
4162
 
        # Remember where we merge from. We need to remember if:
4163
 
        # - user specify a location (and we don't merge from the parent
4164
 
        #   branch)
4165
 
        # - user ask to remember or there is no previous location set to merge
4166
 
        #   from and user didn't ask to *not* remember
4167
 
        if (user_location is not None
4168
 
            and ((remember
4169
 
                  or (remember is None
4170
 
                      and tree.branch.get_submit_branch() is None)))):
 
3943
        # Remember where we merge from
 
3944
        if ((remember or tree.branch.get_submit_branch() is None) and
 
3945
             user_location is not None):
4171
3946
            tree.branch.set_submit_branch(other_branch.base)
4172
 
        # Merge tags (but don't set them in the master branch yet, the user
4173
 
        # might revert this merge).  Commit will propagate them.
4174
 
        _merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
 
3947
        _merge_tags_if_possible(other_branch, tree.branch)
4175
3948
        merger = _mod_merge.Merger.from_revision_ids(pb, tree,
4176
3949
            other_revision_id, base_revision_id, other_branch, base_branch)
4177
3950
        if other_path != '':
4244
4017
 
4245
4018
 
4246
4019
class cmd_remerge(Command):
4247
 
    __doc__ = """Redo a merge.
 
4020
    """Redo a merge.
4248
4021
 
4249
4022
    Use this if you want to try a different merge technique while resolving
4250
4023
    conflicts.  Some merge techniques are better than others, and remerge
4275
4048
 
4276
4049
    def run(self, file_list=None, merge_type=None, show_base=False,
4277
4050
            reprocess=False):
4278
 
        from bzrlib.conflicts import restore
4279
4051
        if merge_type is None:
4280
4052
            merge_type = _mod_merge.Merge3Merger
4281
 
        tree, file_list = WorkingTree.open_containing_paths(file_list)
4282
 
        self.add_cleanup(tree.lock_write().unlock)
 
4053
        tree, file_list = tree_files(file_list)
 
4054
        tree.lock_write()
 
4055
        self.add_cleanup(tree.unlock)
4283
4056
        parents = tree.get_parent_ids()
4284
4057
        if len(parents) != 2:
4285
4058
            raise errors.BzrCommandError("Sorry, remerge only works after normal"
4338
4111
 
4339
4112
 
4340
4113
class cmd_revert(Command):
4341
 
    __doc__ = """Revert files to a previous revision.
 
4114
    """Revert files to a previous revision.
4342
4115
 
4343
4116
    Giving a list of files will revert only those files.  Otherwise, all files
4344
4117
    will be reverted.  If the revision is not specified with '--revision', the
4345
4118
    last committed revision is used.
4346
4119
 
4347
4120
    To remove only some changes, without reverting to a prior version, use
4348
 
    merge instead.  For example, "merge . -r -2..-3" (don't forget the ".")
4349
 
    will remove the changes introduced by the second last commit (-2), without
4350
 
    affecting the changes introduced by the last commit (-1).  To remove
4351
 
    certain changes on a hunk-by-hunk basis, see the shelve command.
 
4121
    merge instead.  For example, "merge . --revision -2..-3" will remove the
 
4122
    changes introduced by -2, without affecting the changes introduced by -1.
 
4123
    Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
4352
4124
 
4353
4125
    By default, any files that have been manually changed will be backed up
4354
4126
    first.  (Files changed only by merge are not backed up.)  Backup files have
4384
4156
    target branches.
4385
4157
    """
4386
4158
 
4387
 
    _see_also = ['cat', 'export', 'merge', 'shelve']
 
4159
    _see_also = ['cat', 'export']
4388
4160
    takes_options = [
4389
4161
        'revision',
4390
4162
        Option('no-backup', "Do not save backups of reverted files."),
4395
4167
 
4396
4168
    def run(self, revision=None, no_backup=False, file_list=None,
4397
4169
            forget_merges=None):
4398
 
        tree, file_list = WorkingTree.open_containing_paths(file_list)
4399
 
        self.add_cleanup(tree.lock_tree_write().unlock)
 
4170
        tree, file_list = tree_files(file_list)
 
4171
        tree.lock_write()
 
4172
        self.add_cleanup(tree.unlock)
4400
4173
        if forget_merges:
4401
4174
            tree.set_parent_ids(tree.get_parent_ids()[:1])
4402
4175
        else:
4410
4183
 
4411
4184
 
4412
4185
class cmd_assert_fail(Command):
4413
 
    __doc__ = """Test reporting of assertion failures"""
 
4186
    """Test reporting of assertion failures"""
4414
4187
    # intended just for use in testing
4415
4188
 
4416
4189
    hidden = True
4420
4193
 
4421
4194
 
4422
4195
class cmd_help(Command):
4423
 
    __doc__ = """Show help on a command or other topic.
 
4196
    """Show help on a command or other topic.
4424
4197
    """
4425
4198
 
4426
4199
    _see_also = ['topics']
4439
4212
 
4440
4213
 
4441
4214
class cmd_shell_complete(Command):
4442
 
    __doc__ = """Show appropriate completions for context.
 
4215
    """Show appropriate completions for context.
4443
4216
 
4444
4217
    For a list of all available commands, say 'bzr shell-complete'.
4445
4218
    """
4454
4227
 
4455
4228
 
4456
4229
class cmd_missing(Command):
4457
 
    __doc__ = """Show unmerged/unpulled revisions between two branches.
 
4230
    """Show unmerged/unpulled revisions between two branches.
4458
4231
 
4459
4232
    OTHER_BRANCH may be local or remote.
4460
4233
 
4491
4264
    _see_also = ['merge', 'pull']
4492
4265
    takes_args = ['other_branch?']
4493
4266
    takes_options = [
4494
 
        'directory',
4495
4267
        Option('reverse', 'Reverse the order of revisions.'),
4496
4268
        Option('mine-only',
4497
4269
               'Display changes in the local branch only.'),
4519
4291
            theirs_only=False,
4520
4292
            log_format=None, long=False, short=False, line=False,
4521
4293
            show_ids=False, verbose=False, this=False, other=False,
4522
 
            include_merges=False, revision=None, my_revision=None,
4523
 
            directory=u'.'):
 
4294
            include_merges=False, revision=None, my_revision=None):
4524
4295
        from bzrlib.missing import find_unmerged, iter_log_revisions
4525
4296
        def message(s):
4526
4297
            if not is_quiet():
4539
4310
        elif theirs_only:
4540
4311
            restrict = 'remote'
4541
4312
 
4542
 
        local_branch = Branch.open_containing(directory)[0]
4543
 
        self.add_cleanup(local_branch.lock_read().unlock)
4544
 
 
 
4313
        local_branch = Branch.open_containing(u".")[0]
4545
4314
        parent = local_branch.get_parent()
4546
4315
        if other_branch is None:
4547
4316
            other_branch = parent
4556
4325
        remote_branch = Branch.open(other_branch)
4557
4326
        if remote_branch.base == local_branch.base:
4558
4327
            remote_branch = local_branch
4559
 
        else:
4560
 
            self.add_cleanup(remote_branch.lock_read().unlock)
4561
4328
 
 
4329
        local_branch.lock_read()
 
4330
        self.add_cleanup(local_branch.unlock)
4562
4331
        local_revid_range = _revision_range_to_revid_range(
4563
4332
            _get_revision_range(my_revision, local_branch,
4564
4333
                self.name()))
4565
4334
 
 
4335
        remote_branch.lock_read()
 
4336
        self.add_cleanup(remote_branch.unlock)
4566
4337
        remote_revid_range = _revision_range_to_revid_range(
4567
4338
            _get_revision_range(revision,
4568
4339
                remote_branch, self.name()))
4618
4389
            message("Branches are up to date.\n")
4619
4390
        self.cleanup_now()
4620
4391
        if not status_code and parent is None and other_branch is not None:
4621
 
            self.add_cleanup(local_branch.lock_write().unlock)
 
4392
            local_branch.lock_write()
 
4393
            self.add_cleanup(local_branch.unlock)
4622
4394
            # handle race conditions - a parent might be set while we run.
4623
4395
            if local_branch.get_parent() is None:
4624
4396
                local_branch.set_parent(remote_branch.base)
4626
4398
 
4627
4399
 
4628
4400
class cmd_pack(Command):
4629
 
    __doc__ = """Compress the data within a repository.
4630
 
 
4631
 
    This operation compresses the data within a bazaar repository. As
4632
 
    bazaar supports automatic packing of repository, this operation is
4633
 
    normally not required to be done manually.
4634
 
 
4635
 
    During the pack operation, bazaar takes a backup of existing repository
4636
 
    data, i.e. pack files. This backup is eventually removed by bazaar
4637
 
    automatically when it is safe to do so. To save disk space by removing
4638
 
    the backed up pack files, the --clean-obsolete-packs option may be
4639
 
    used.
4640
 
 
4641
 
    Warning: If you use --clean-obsolete-packs and your machine crashes
4642
 
    during or immediately after repacking, you may be left with a state
4643
 
    where the deletion has been written to disk but the new packs have not
4644
 
    been. In this case the repository may be unusable.
4645
 
    """
 
4401
    """Compress the data within a repository."""
4646
4402
 
4647
4403
    _see_also = ['repositories']
4648
4404
    takes_args = ['branch_or_repo?']
4649
 
    takes_options = [
4650
 
        Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4651
 
        ]
4652
4405
 
4653
 
    def run(self, branch_or_repo='.', clean_obsolete_packs=False):
 
4406
    def run(self, branch_or_repo='.'):
4654
4407
        dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4655
4408
        try:
4656
4409
            branch = dir.open_branch()
4657
4410
            repository = branch.repository
4658
4411
        except errors.NotBranchError:
4659
4412
            repository = dir.open_repository()
4660
 
        repository.pack(clean_obsolete_packs=clean_obsolete_packs)
 
4413
        repository.pack()
4661
4414
 
4662
4415
 
4663
4416
class cmd_plugins(Command):
4664
 
    __doc__ = """List the installed plugins.
 
4417
    """List the installed plugins.
4665
4418
 
4666
4419
    This command displays the list of installed plugins including
4667
4420
    version of plugin and a short description of each.
4683
4436
 
4684
4437
    @display_command
4685
4438
    def run(self, verbose=False):
4686
 
        from bzrlib import plugin
4687
 
        # Don't give writelines a generator as some codecs don't like that
4688
 
        self.outf.writelines(
4689
 
            list(plugin.describe_plugins(show_paths=verbose)))
 
4439
        import bzrlib.plugin
 
4440
        from inspect import getdoc
 
4441
        result = []
 
4442
        for name, plugin in bzrlib.plugin.plugins().items():
 
4443
            version = plugin.__version__
 
4444
            if version == 'unknown':
 
4445
                version = ''
 
4446
            name_ver = '%s %s' % (name, version)
 
4447
            d = getdoc(plugin.module)
 
4448
            if d:
 
4449
                doc = d.split('\n')[0]
 
4450
            else:
 
4451
                doc = '(no description)'
 
4452
            result.append((name_ver, doc, plugin.path()))
 
4453
        for name_ver, doc, path in sorted(result):
 
4454
            self.outf.write("%s\n" % name_ver)
 
4455
            self.outf.write("   %s\n" % doc)
 
4456
            if verbose:
 
4457
                self.outf.write("   %s\n" % path)
 
4458
            self.outf.write("\n")
4690
4459
 
4691
4460
 
4692
4461
class cmd_testament(Command):
4693
 
    __doc__ = """Show testament (signing-form) of a revision."""
 
4462
    """Show testament (signing-form) of a revision."""
4694
4463
    takes_options = [
4695
4464
            'revision',
4696
4465
            Option('long', help='Produce long-format testament.'),
4708
4477
            b = Branch.open_containing(branch)[0]
4709
4478
        else:
4710
4479
            b = Branch.open(branch)
4711
 
        self.add_cleanup(b.lock_read().unlock)
 
4480
        b.lock_read()
 
4481
        self.add_cleanup(b.unlock)
4712
4482
        if revision is None:
4713
4483
            rev_id = b.last_revision()
4714
4484
        else:
4721
4491
 
4722
4492
 
4723
4493
class cmd_annotate(Command):
4724
 
    __doc__ = """Show the origin of each line in a file.
 
4494
    """Show the origin of each line in a file.
4725
4495
 
4726
4496
    This prints out the given file with an annotation on the left side
4727
4497
    indicating which revision, author and date introduced the change.
4738
4508
                     Option('long', help='Show commit date in annotations.'),
4739
4509
                     'revision',
4740
4510
                     'show-ids',
4741
 
                     'directory',
4742
4511
                     ]
4743
4512
    encoding_type = 'exact'
4744
4513
 
4745
4514
    @display_command
4746
4515
    def run(self, filename, all=False, long=False, revision=None,
4747
 
            show_ids=False, directory=None):
4748
 
        from bzrlib.annotate import (
4749
 
            annotate_file_tree,
4750
 
            )
 
4516
            show_ids=False):
 
4517
        from bzrlib.annotate import annotate_file, annotate_file_tree
4751
4518
        wt, branch, relpath = \
4752
 
            _open_directory_or_containing_tree_or_branch(filename, directory)
 
4519
            bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4753
4520
        if wt is not None:
4754
 
            self.add_cleanup(wt.lock_read().unlock)
 
4521
            wt.lock_read()
 
4522
            self.add_cleanup(wt.unlock)
4755
4523
        else:
4756
 
            self.add_cleanup(branch.lock_read().unlock)
 
4524
            branch.lock_read()
 
4525
            self.add_cleanup(branch.unlock)
4757
4526
        tree = _get_one_revision_tree('annotate', revision, branch=branch)
4758
 
        self.add_cleanup(tree.lock_read().unlock)
4759
 
        if wt is not None and revision is None:
 
4527
        tree.lock_read()
 
4528
        self.add_cleanup(tree.unlock)
 
4529
        if wt is not None:
4760
4530
            file_id = wt.path2id(relpath)
4761
4531
        else:
4762
4532
            file_id = tree.path2id(relpath)
4763
4533
        if file_id is None:
4764
4534
            raise errors.NotVersionedError(filename)
 
4535
        file_version = tree.inventory[file_id].revision
4765
4536
        if wt is not None and revision is None:
4766
4537
            # If there is a tree and we're not annotating historical
4767
4538
            # versions, annotate the working tree's content.
4768
4539
            annotate_file_tree(wt, file_id, self.outf, long, all,
4769
4540
                show_ids=show_ids)
4770
4541
        else:
4771
 
            annotate_file_tree(tree, file_id, self.outf, long, all,
4772
 
                show_ids=show_ids, branch=branch)
 
4542
            annotate_file(branch, file_version, file_id, long, all, self.outf,
 
4543
                          show_ids=show_ids)
4773
4544
 
4774
4545
 
4775
4546
class cmd_re_sign(Command):
4776
 
    __doc__ = """Create a digital signature for an existing revision."""
 
4547
    """Create a digital signature for an existing revision."""
4777
4548
    # TODO be able to replace existing ones.
4778
4549
 
4779
4550
    hidden = True # is this right ?
4780
4551
    takes_args = ['revision_id*']
4781
 
    takes_options = ['directory', 'revision']
 
4552
    takes_options = ['revision']
4782
4553
 
4783
 
    def run(self, revision_id_list=None, revision=None, directory=u'.'):
 
4554
    def run(self, revision_id_list=None, revision=None):
4784
4555
        if revision_id_list is not None and revision is not None:
4785
4556
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4786
4557
        if revision_id_list is None and revision is None:
4787
4558
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4788
 
        b = WorkingTree.open_containing(directory)[0].branch
4789
 
        self.add_cleanup(b.lock_write().unlock)
 
4559
        b = WorkingTree.open_containing(u'.')[0].branch
 
4560
        b.lock_write()
 
4561
        self.add_cleanup(b.unlock)
4790
4562
        return self._run(b, revision_id_list, revision)
4791
4563
 
4792
4564
    def _run(self, b, revision_id_list, revision):
4838
4610
 
4839
4611
 
4840
4612
class cmd_bind(Command):
4841
 
    __doc__ = """Convert the current branch into a checkout of the supplied branch.
4842
 
    If no branch is supplied, rebind to the last bound location.
 
4613
    """Convert the current branch into a checkout of the supplied branch.
4843
4614
 
4844
4615
    Once converted into a checkout, commits must succeed on the master branch
4845
4616
    before they will be applied to the local branch.
4851
4622
 
4852
4623
    _see_also = ['checkouts', 'unbind']
4853
4624
    takes_args = ['location?']
4854
 
    takes_options = ['directory']
 
4625
    takes_options = []
4855
4626
 
4856
 
    def run(self, location=None, directory=u'.'):
4857
 
        b, relpath = Branch.open_containing(directory)
 
4627
    def run(self, location=None):
 
4628
        b, relpath = Branch.open_containing(u'.')
4858
4629
        if location is None:
4859
4630
            try:
4860
4631
                location = b.get_old_bound_location()
4879
4650
 
4880
4651
 
4881
4652
class cmd_unbind(Command):
4882
 
    __doc__ = """Convert the current checkout into a regular branch.
 
4653
    """Convert the current checkout into a regular branch.
4883
4654
 
4884
4655
    After unbinding, the local branch is considered independent and subsequent
4885
4656
    commits will be local only.
4887
4658
 
4888
4659
    _see_also = ['checkouts', 'bind']
4889
4660
    takes_args = []
4890
 
    takes_options = ['directory']
 
4661
    takes_options = []
4891
4662
 
4892
 
    def run(self, directory=u'.'):
4893
 
        b, relpath = Branch.open_containing(directory)
 
4663
    def run(self):
 
4664
        b, relpath = Branch.open_containing(u'.')
4894
4665
        if not b.unbind():
4895
4666
            raise errors.BzrCommandError('Local branch is not bound')
4896
4667
 
4897
4668
 
4898
4669
class cmd_uncommit(Command):
4899
 
    __doc__ = """Remove the last committed revision.
 
4670
    """Remove the last committed revision.
4900
4671
 
4901
4672
    --verbose will print out what is being removed.
4902
4673
    --dry-run will go through all the motions, but not actually
4942
4713
            b = control.open_branch()
4943
4714
 
4944
4715
        if tree is not None:
4945
 
            self.add_cleanup(tree.lock_write().unlock)
 
4716
            tree.lock_write()
 
4717
            self.add_cleanup(tree.unlock)
4946
4718
        else:
4947
 
            self.add_cleanup(b.lock_write().unlock)
 
4719
            b.lock_write()
 
4720
            self.add_cleanup(b.unlock)
4948
4721
        return self._run(b, tree, dry_run, verbose, revision, force, local=local)
4949
4722
 
4950
4723
    def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
4989
4762
            self.outf.write('The above revision(s) will be removed.\n')
4990
4763
 
4991
4764
        if not force:
4992
 
            if not ui.ui_factory.confirm_action(
4993
 
                    u'Uncommit these revisions',
4994
 
                    'bzrlib.builtins.uncommit',
4995
 
                    {}):
4996
 
                self.outf.write('Canceled\n')
 
4765
            if not ui.ui_factory.get_boolean('Are you sure'):
 
4766
                self.outf.write('Canceled')
4997
4767
                return 0
4998
4768
 
4999
4769
        mutter('Uncommitting from {%s} to {%s}',
5005
4775
 
5006
4776
 
5007
4777
class cmd_break_lock(Command):
5008
 
    __doc__ = """Break a dead lock.
5009
 
 
5010
 
    This command breaks a lock on a repository, branch, working directory or
5011
 
    config file.
 
4778
    """Break a dead lock on a repository, branch or working directory.
5012
4779
 
5013
4780
    CAUTION: Locks should only be broken when you are sure that the process
5014
4781
    holding the lock has been stopped.
5019
4786
    :Examples:
5020
4787
        bzr break-lock
5021
4788
        bzr break-lock bzr+ssh://example.com/bzr/foo
5022
 
        bzr break-lock --conf ~/.bazaar
5023
4789
    """
5024
 
 
5025
4790
    takes_args = ['location?']
5026
 
    takes_options = [
5027
 
        Option('config',
5028
 
               help='LOCATION is the directory where the config lock is.'),
5029
 
        Option('force',
5030
 
            help='Do not ask for confirmation before breaking the lock.'),
5031
 
        ]
5032
4791
 
5033
 
    def run(self, location=None, config=False, force=False):
 
4792
    def run(self, location=None, show=False):
5034
4793
        if location is None:
5035
4794
            location = u'.'
5036
 
        if force:
5037
 
            ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
5038
 
                None,
5039
 
                {'bzrlib.lockdir.break': True})
5040
 
        if config:
5041
 
            conf = _mod_config.LockableConfig(file_name=location)
5042
 
            conf.break_lock()
5043
 
        else:
5044
 
            control, relpath = bzrdir.BzrDir.open_containing(location)
5045
 
            try:
5046
 
                control.break_lock()
5047
 
            except NotImplementedError:
5048
 
                pass
 
4795
        control, relpath = bzrdir.BzrDir.open_containing(location)
 
4796
        try:
 
4797
            control.break_lock()
 
4798
        except NotImplementedError:
 
4799
            pass
5049
4800
 
5050
4801
 
5051
4802
class cmd_wait_until_signalled(Command):
5052
 
    __doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
 
4803
    """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
5053
4804
 
5054
4805
    This just prints a line to signal when it is ready, then blocks on stdin.
5055
4806
    """
5063
4814
 
5064
4815
 
5065
4816
class cmd_serve(Command):
5066
 
    __doc__ = """Run the bzr server."""
 
4817
    """Run the bzr server."""
5067
4818
 
5068
4819
    aliases = ['server']
5069
4820
 
5080
4831
                    'result in a dynamically allocated port.  The default port '
5081
4832
                    'depends on the protocol.',
5082
4833
               type=str),
5083
 
        custom_help('directory',
5084
 
               help='Serve contents of this directory.'),
 
4834
        Option('directory',
 
4835
               help='Serve contents of this directory.',
 
4836
               type=unicode),
5085
4837
        Option('allow-writes',
5086
4838
               help='By default the server is a readonly server.  Supplying '
5087
4839
                    '--allow-writes enables write access to the contents of '
5114
4866
 
5115
4867
    def run(self, port=None, inet=False, directory=None, allow_writes=False,
5116
4868
            protocol=None):
5117
 
        from bzrlib import transport
 
4869
        from bzrlib.transport import get_transport, transport_server_registry
5118
4870
        if directory is None:
5119
4871
            directory = os.getcwd()
5120
4872
        if protocol is None:
5121
 
            protocol = transport.transport_server_registry.get()
 
4873
            protocol = transport_server_registry.get()
5122
4874
        host, port = self.get_host_and_port(port)
5123
4875
        url = urlutils.local_path_to_url(directory)
5124
4876
        if not allow_writes:
5125
4877
            url = 'readonly+' + url
5126
 
        t = transport.get_transport(url)
5127
 
        protocol(t, host, port, inet)
 
4878
        transport = get_transport(url)
 
4879
        protocol(transport, host, port, inet)
5128
4880
 
5129
4881
 
5130
4882
class cmd_join(Command):
5131
 
    __doc__ = """Combine a tree into its containing tree.
 
4883
    """Combine a tree into its containing tree.
5132
4884
 
5133
4885
    This command requires the target tree to be in a rich-root format.
5134
4886
 
5136
4888
    not part of it.  (Such trees can be produced by "bzr split", but also by
5137
4889
    running "bzr branch" with the target inside a tree.)
5138
4890
 
5139
 
    The result is a combined tree, with the subtree no longer an independent
 
4891
    The result is a combined tree, with the subtree no longer an independant
5140
4892
    part.  This is marked as a merge of the subtree into the containing tree,
5141
4893
    and all history is preserved.
5142
4894
    """
5174
4926
 
5175
4927
 
5176
4928
class cmd_split(Command):
5177
 
    __doc__ = """Split a subdirectory of a tree into a separate tree.
 
4929
    """Split a subdirectory of a tree into a separate tree.
5178
4930
 
5179
4931
    This command will produce a target tree in a format that supports
5180
4932
    rich roots, like 'rich-root' or 'rich-root-pack'.  These formats cannot be
5200
4952
 
5201
4953
 
5202
4954
class cmd_merge_directive(Command):
5203
 
    __doc__ = """Generate a merge directive for auto-merge tools.
 
4955
    """Generate a merge directive for auto-merge tools.
5204
4956
 
5205
4957
    A directive requests a merge to be performed, and also provides all the
5206
4958
    information necessary to do so.  This means it must either include a
5223
4975
    _see_also = ['send']
5224
4976
 
5225
4977
    takes_options = [
5226
 
        'directory',
5227
4978
        RegistryOption.from_kwargs('patch-type',
5228
4979
            'The type of patch to include in the directive.',
5229
4980
            title='Patch type',
5242
4993
    encoding_type = 'exact'
5243
4994
 
5244
4995
    def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
5245
 
            sign=False, revision=None, mail_to=None, message=None,
5246
 
            directory=u'.'):
 
4996
            sign=False, revision=None, mail_to=None, message=None):
5247
4997
        from bzrlib.revision import ensure_null, NULL_REVISION
5248
4998
        include_patch, include_bundle = {
5249
4999
            'plain': (False, False),
5250
5000
            'diff': (True, False),
5251
5001
            'bundle': (True, True),
5252
5002
            }[patch_type]
5253
 
        branch = Branch.open(directory)
 
5003
        branch = Branch.open('.')
5254
5004
        stored_submit_branch = branch.get_submit_branch()
5255
5005
        if submit_branch is None:
5256
5006
            submit_branch = stored_submit_branch
5301
5051
 
5302
5052
 
5303
5053
class cmd_send(Command):
5304
 
    __doc__ = """Mail or create a merge-directive for submitting changes.
 
5054
    """Mail or create a merge-directive for submitting changes.
5305
5055
 
5306
5056
    A merge directive provides many things needed for requesting merges:
5307
5057
 
5332
5082
    source branch defaults to that containing the working directory, but can
5333
5083
    be changed using --from.
5334
5084
 
5335
 
    Both the submit branch and the public branch follow the usual behavior with
5336
 
    respect to --remember: If there is no default location set, the first send
5337
 
    will set it (use --no-remember to avoid settting it). After that, you can
5338
 
    omit the location to use the default.  To change the default, use
5339
 
    --remember. The value will only be saved if the location can be accessed.
5340
 
 
5341
5085
    In order to calculate those changes, bzr must analyse the submit branch.
5342
5086
    Therefore it is most efficient for the submit branch to be a local mirror.
5343
5087
    If a public location is known for the submit_branch, that location is used
5347
5091
    given, in which case it is sent to a file.
5348
5092
 
5349
5093
    Mail is sent using your preferred mail program.  This should be transparent
5350
 
    on Windows (it uses MAPI).  On Unix, it requires the xdg-email utility.
 
5094
    on Windows (it uses MAPI).  On Linux, it requires the xdg-email utility.
5351
5095
    If the preferred client can't be found (or used), your editor will be used.
5352
5096
 
5353
5097
    To use a specific mail program, set the mail_client configuration option.
5395
5139
               short_name='f',
5396
5140
               type=unicode),
5397
5141
        Option('output', short_name='o',
5398
 
               help='Write merge directive to this file or directory; '
 
5142
               help='Write merge directive to this file; '
5399
5143
                    'use - for stdout.',
5400
5144
               type=unicode),
5401
5145
        Option('strict',
5412
5156
        ]
5413
5157
 
5414
5158
    def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5415
 
            no_patch=False, revision=None, remember=None, output=None,
 
5159
            no_patch=False, revision=None, remember=False, output=None,
5416
5160
            format=None, mail_to=None, message=None, body=None,
5417
5161
            strict=None, **kwargs):
5418
5162
        from bzrlib.send import send
5424
5168
 
5425
5169
 
5426
5170
class cmd_bundle_revisions(cmd_send):
5427
 
    __doc__ = """Create a merge-directive for submitting changes.
 
5171
    """Create a merge-directive for submitting changes.
5428
5172
 
5429
5173
    A merge directive provides many things needed for requesting merges:
5430
5174
 
5497
5241
 
5498
5242
 
5499
5243
class cmd_tag(Command):
5500
 
    __doc__ = """Create, remove or modify a tag naming a revision.
 
5244
    """Create, remove or modify a tag naming a revision.
5501
5245
 
5502
5246
    Tags give human-meaningful names to revisions.  Commands that take a -r
5503
5247
    (--revision) option can be given -rtag:X, where X is any previously
5511
5255
 
5512
5256
    To rename a tag (change the name but keep it on the same revsion), run ``bzr
5513
5257
    tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5514
 
 
5515
 
    If no tag name is specified it will be determined through the 
5516
 
    'automatic_tag_name' hook. This can e.g. be used to automatically tag
5517
 
    upstream releases by reading configure.ac. See ``bzr help hooks`` for
5518
 
    details.
5519
5258
    """
5520
5259
 
5521
5260
    _see_also = ['commit', 'tags']
5522
 
    takes_args = ['tag_name?']
 
5261
    takes_args = ['tag_name']
5523
5262
    takes_options = [
5524
5263
        Option('delete',
5525
5264
            help='Delete this tag rather than placing it.',
5526
5265
            ),
5527
 
        custom_help('directory',
5528
 
            help='Branch in which to place the tag.'),
 
5266
        Option('directory',
 
5267
            help='Branch in which to place the tag.',
 
5268
            short_name='d',
 
5269
            type=unicode,
 
5270
            ),
5529
5271
        Option('force',
5530
5272
            help='Replace existing tags.',
5531
5273
            ),
5532
5274
        'revision',
5533
5275
        ]
5534
5276
 
5535
 
    def run(self, tag_name=None,
 
5277
    def run(self, tag_name,
5536
5278
            delete=None,
5537
5279
            directory='.',
5538
5280
            force=None,
5539
5281
            revision=None,
5540
5282
            ):
5541
5283
        branch, relpath = Branch.open_containing(directory)
5542
 
        self.add_cleanup(branch.lock_write().unlock)
 
5284
        branch.lock_write()
 
5285
        self.add_cleanup(branch.unlock)
5543
5286
        if delete:
5544
 
            if tag_name is None:
5545
 
                raise errors.BzrCommandError("No tag specified to delete.")
5546
5287
            branch.tags.delete_tag(tag_name)
5547
 
            note('Deleted tag %s.' % tag_name)
 
5288
            self.outf.write('Deleted tag %s.\n' % tag_name)
5548
5289
        else:
5549
5290
            if revision:
5550
5291
                if len(revision) != 1:
5554
5295
                revision_id = revision[0].as_revision_id(branch)
5555
5296
            else:
5556
5297
                revision_id = branch.last_revision()
5557
 
            if tag_name is None:
5558
 
                tag_name = branch.automatic_tag_name(revision_id)
5559
 
                if tag_name is None:
5560
 
                    raise errors.BzrCommandError(
5561
 
                        "Please specify a tag name.")
5562
5298
            if (not force) and branch.tags.has_tag(tag_name):
5563
5299
                raise errors.TagAlreadyExists(tag_name)
5564
5300
            branch.tags.set_tag(tag_name, revision_id)
5565
 
            note('Created tag %s.' % tag_name)
 
5301
            self.outf.write('Created tag %s.\n' % tag_name)
5566
5302
 
5567
5303
 
5568
5304
class cmd_tags(Command):
5569
 
    __doc__ = """List tags.
 
5305
    """List tags.
5570
5306
 
5571
5307
    This command shows a table of tag names and the revisions they reference.
5572
5308
    """
5573
5309
 
5574
5310
    _see_also = ['tag']
5575
5311
    takes_options = [
5576
 
        custom_help('directory',
5577
 
            help='Branch whose tags should be displayed.'),
5578
 
        RegistryOption('sort',
 
5312
        Option('directory',
 
5313
            help='Branch whose tags should be displayed.',
 
5314
            short_name='d',
 
5315
            type=unicode,
 
5316
            ),
 
5317
        RegistryOption.from_kwargs('sort',
5579
5318
            'Sort tags by different criteria.', title='Sorting',
5580
 
            lazy_registry=('bzrlib.tag', 'tag_sort_methods')
 
5319
            alpha='Sort tags lexicographically (default).',
 
5320
            time='Sort tags chronologically.',
5581
5321
            ),
5582
5322
        'show-ids',
5583
5323
        'revision',
5584
5324
    ]
5585
5325
 
5586
5326
    @display_command
5587
 
    def run(self, directory='.', sort=None, show_ids=False, revision=None):
5588
 
        from bzrlib.tag import tag_sort_methods
 
5327
    def run(self,
 
5328
            directory='.',
 
5329
            sort='alpha',
 
5330
            show_ids=False,
 
5331
            revision=None,
 
5332
            ):
5589
5333
        branch, relpath = Branch.open_containing(directory)
5590
5334
 
5591
5335
        tags = branch.tags.get_tag_dict().items()
5592
5336
        if not tags:
5593
5337
            return
5594
5338
 
5595
 
        self.add_cleanup(branch.lock_read().unlock)
 
5339
        branch.lock_read()
 
5340
        self.add_cleanup(branch.unlock)
5596
5341
        if revision:
5597
5342
            graph = branch.repository.get_graph()
5598
5343
            rev1, rev2 = _get_revision_range(revision, branch, self.name())
5600
5345
            # only show revisions between revid1 and revid2 (inclusive)
5601
5346
            tags = [(tag, revid) for tag, revid in tags if
5602
5347
                graph.is_between(revid, revid1, revid2)]
5603
 
        if sort is None:
5604
 
            sort = tag_sort_methods.get()
5605
 
        sort(branch, tags)
 
5348
        if sort == 'alpha':
 
5349
            tags.sort()
 
5350
        elif sort == 'time':
 
5351
            timestamps = {}
 
5352
            for tag, revid in tags:
 
5353
                try:
 
5354
                    revobj = branch.repository.get_revision(revid)
 
5355
                except errors.NoSuchRevision:
 
5356
                    timestamp = sys.maxint # place them at the end
 
5357
                else:
 
5358
                    timestamp = revobj.timestamp
 
5359
                timestamps[revid] = timestamp
 
5360
            tags.sort(key=lambda x: timestamps[x[1]])
5606
5361
        if not show_ids:
5607
5362
            # [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5608
5363
            for index, (tag, revid) in enumerate(tags):
5610
5365
                    revno = branch.revision_id_to_dotted_revno(revid)
5611
5366
                    if isinstance(revno, tuple):
5612
5367
                        revno = '.'.join(map(str, revno))
5613
 
                except (errors.NoSuchRevision, errors.GhostRevisionsHaveNoRevno):
 
5368
                except errors.NoSuchRevision:
5614
5369
                    # Bad tag data/merges can lead to tagged revisions
5615
5370
                    # which are not in this branch. Fail gracefully ...
5616
5371
                    revno = '?'
5621
5376
 
5622
5377
 
5623
5378
class cmd_reconfigure(Command):
5624
 
    __doc__ = """Reconfigure the type of a bzr directory.
 
5379
    """Reconfigure the type of a bzr directory.
5625
5380
 
5626
5381
    A target configuration must be specified.
5627
5382
 
5674
5429
            unstacked=None):
5675
5430
        directory = bzrdir.BzrDir.open(location)
5676
5431
        if stacked_on and unstacked:
5677
 
            raise errors.BzrCommandError("Can't use both --stacked-on and --unstacked")
 
5432
            raise BzrCommandError("Can't use both --stacked-on and --unstacked")
5678
5433
        elif stacked_on is not None:
5679
5434
            reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5680
5435
        elif unstacked:
5712
5467
 
5713
5468
 
5714
5469
class cmd_switch(Command):
5715
 
    __doc__ = """Set the branch of a checkout and update.
 
5470
    """Set the branch of a checkout and update.
5716
5471
 
5717
5472
    For lightweight checkouts, this changes the branch being referenced.
5718
5473
    For heavyweight checkouts, this checks that there are no local commits
5735
5490
    """
5736
5491
 
5737
5492
    takes_args = ['to_location?']
5738
 
    takes_options = ['directory',
5739
 
                     Option('force',
 
5493
    takes_options = [Option('force',
5740
5494
                        help='Switch even if local commits will be lost.'),
5741
5495
                     'revision',
5742
5496
                     Option('create-branch', short_name='b',
5745
5499
                    ]
5746
5500
 
5747
5501
    def run(self, to_location=None, force=False, create_branch=False,
5748
 
            revision=None, directory=u'.'):
 
5502
            revision=None):
5749
5503
        from bzrlib import switch
5750
 
        tree_location = directory
 
5504
        tree_location = '.'
5751
5505
        revision = _get_one_revision('switch', revision)
5752
5506
        control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5753
5507
        if to_location is None:
5754
5508
            if revision is None:
5755
5509
                raise errors.BzrCommandError('You must supply either a'
5756
5510
                                             ' revision or a location')
5757
 
            to_location = tree_location
 
5511
            to_location = '.'
5758
5512
        try:
5759
5513
            branch = control_dir.open_branch()
5760
5514
            had_explicit_nick = branch.get_config().has_explicit_nickname()
5809
5563
 
5810
5564
 
5811
5565
class cmd_view(Command):
5812
 
    __doc__ = """Manage filtered views.
 
5566
    """Manage filtered views.
5813
5567
 
5814
5568
    Views provide a mask over the tree so that users can focus on
5815
5569
    a subset of a tree when doing their work. After creating a view,
5895
5649
            name=None,
5896
5650
            switch=None,
5897
5651
            ):
5898
 
        tree, file_list = WorkingTree.open_containing_paths(file_list,
5899
 
            apply_view=False)
 
5652
        tree, file_list = tree_files(file_list, apply_view=False)
5900
5653
        current_view, view_dict = tree.views.get_view_info()
5901
5654
        if name is None:
5902
5655
            name = current_view
5964
5717
 
5965
5718
 
5966
5719
class cmd_hooks(Command):
5967
 
    __doc__ = """Show hooks."""
 
5720
    """Show hooks."""
5968
5721
 
5969
5722
    hidden = True
5970
5723
 
5983
5736
                    self.outf.write("    <no hooks installed>\n")
5984
5737
 
5985
5738
 
5986
 
class cmd_remove_branch(Command):
5987
 
    __doc__ = """Remove a branch.
5988
 
 
5989
 
    This will remove the branch from the specified location but 
5990
 
    will keep any working tree or repository in place.
5991
 
 
5992
 
    :Examples:
5993
 
 
5994
 
      Remove the branch at repo/trunk::
5995
 
 
5996
 
        bzr remove-branch repo/trunk
5997
 
 
5998
 
    """
5999
 
 
6000
 
    takes_args = ["location?"]
6001
 
 
6002
 
    aliases = ["rmbranch"]
6003
 
 
6004
 
    def run(self, location=None):
6005
 
        if location is None:
6006
 
            location = "."
6007
 
        branch = Branch.open_containing(location)[0]
6008
 
        branch.bzrdir.destroy_branch()
6009
 
 
6010
 
 
6011
5739
class cmd_shelve(Command):
6012
 
    __doc__ = """Temporarily set aside some changes from the current tree.
 
5740
    """Temporarily set aside some changes from the current tree.
6013
5741
 
6014
5742
    Shelve allows you to temporarily put changes you've made "on the shelf",
6015
5743
    ie. out of the way, until a later time when you can bring them back from
6031
5759
 
6032
5760
    You can put multiple items on the shelf, and by default, 'unshelve' will
6033
5761
    restore the most recently shelved changes.
6034
 
 
6035
 
    For complicated changes, it is possible to edit the changes in a separate
6036
 
    editor program to decide what the file remaining in the working copy
6037
 
    should look like.  To do this, add the configuration option
6038
 
 
6039
 
        change_editor = PROGRAM @new_path @old_path
6040
 
 
6041
 
    where @new_path is replaced with the path of the new version of the 
6042
 
    file and @old_path is replaced with the path of the old version of 
6043
 
    the file.  The PROGRAM should save the new file with the desired 
6044
 
    contents of the file in the working tree.
6045
 
        
6046
5762
    """
6047
5763
 
6048
5764
    takes_args = ['file*']
6049
5765
 
6050
5766
    takes_options = [
6051
 
        'directory',
6052
5767
        'revision',
6053
5768
        Option('all', help='Shelve all changes.'),
6054
5769
        'message',
6060
5775
        Option('destroy',
6061
5776
               help='Destroy removed changes instead of shelving them.'),
6062
5777
    ]
6063
 
    _see_also = ['unshelve', 'configuration']
 
5778
    _see_also = ['unshelve']
6064
5779
 
6065
5780
    def run(self, revision=None, all=False, file_list=None, message=None,
6066
 
            writer=None, list=False, destroy=False, directory=None):
 
5781
            writer=None, list=False, destroy=False):
6067
5782
        if list:
6068
 
            return self.run_for_list(directory=directory)
 
5783
            return self.run_for_list()
6069
5784
        from bzrlib.shelf_ui import Shelver
6070
5785
        if writer is None:
6071
5786
            writer = bzrlib.option.diff_writer_registry.get()
6072
5787
        try:
6073
5788
            shelver = Shelver.from_args(writer(sys.stdout), revision, all,
6074
 
                file_list, message, destroy=destroy, directory=directory)
 
5789
                file_list, message, destroy=destroy)
6075
5790
            try:
6076
5791
                shelver.run()
6077
5792
            finally:
6079
5794
        except errors.UserAbort:
6080
5795
            return 0
6081
5796
 
6082
 
    def run_for_list(self, directory=None):
6083
 
        if directory is None:
6084
 
            directory = u'.'
6085
 
        tree = WorkingTree.open_containing(directory)[0]
6086
 
        self.add_cleanup(tree.lock_read().unlock)
 
5797
    def run_for_list(self):
 
5798
        tree = WorkingTree.open_containing('.')[0]
 
5799
        tree.lock_read()
 
5800
        self.add_cleanup(tree.unlock)
6087
5801
        manager = tree.get_shelf_manager()
6088
5802
        shelves = manager.active_shelves()
6089
5803
        if len(shelves) == 0:
6098
5812
 
6099
5813
 
6100
5814
class cmd_unshelve(Command):
6101
 
    __doc__ = """Restore shelved changes.
 
5815
    """Restore shelved changes.
6102
5816
 
6103
5817
    By default, the most recently shelved changes are restored. However if you
6104
5818
    specify a shelf by id those changes will be restored instead.  This works
6107
5821
 
6108
5822
    takes_args = ['shelf_id?']
6109
5823
    takes_options = [
6110
 
        'directory',
6111
5824
        RegistryOption.from_kwargs(
6112
5825
            'action', help="The action to perform.",
6113
5826
            enum_switch=False, value_switches=True,
6121
5834
    ]
6122
5835
    _see_also = ['shelve']
6123
5836
 
6124
 
    def run(self, shelf_id=None, action='apply', directory=u'.'):
 
5837
    def run(self, shelf_id=None, action='apply'):
6125
5838
        from bzrlib.shelf_ui import Unshelver
6126
 
        unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
 
5839
        unshelver = Unshelver.from_args(shelf_id, action)
6127
5840
        try:
6128
5841
            unshelver.run()
6129
5842
        finally:
6131
5844
 
6132
5845
 
6133
5846
class cmd_clean_tree(Command):
6134
 
    __doc__ = """Remove unwanted files from working tree.
 
5847
    """Remove unwanted files from working tree.
6135
5848
 
6136
5849
    By default, only unknown files, not ignored files, are deleted.  Versioned
6137
5850
    files are never deleted.
6145
5858
 
6146
5859
    To check what clean-tree will do, use --dry-run.
6147
5860
    """
6148
 
    takes_options = ['directory',
6149
 
                     Option('ignored', help='Delete all ignored files.'),
6150
 
                     Option('detritus', help='Delete conflict files, merge and revert'
 
5861
    takes_options = [Option('ignored', help='Delete all ignored files.'),
 
5862
                     Option('detritus', help='Delete conflict files, merge'
6151
5863
                            ' backups, and failed selftest dirs.'),
6152
5864
                     Option('unknown',
6153
5865
                            help='Delete files unknown to bzr (default).'),
6155
5867
                            ' deleting them.'),
6156
5868
                     Option('force', help='Do not prompt before deleting.')]
6157
5869
    def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6158
 
            force=False, directory=u'.'):
 
5870
            force=False):
6159
5871
        from bzrlib.clean_tree import clean_tree
6160
5872
        if not (unknown or ignored or detritus):
6161
5873
            unknown = True
6162
5874
        if dry_run:
6163
5875
            force = True
6164
 
        clean_tree(directory, unknown=unknown, ignored=ignored,
6165
 
                   detritus=detritus, dry_run=dry_run, no_prompt=force)
 
5876
        clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
 
5877
                   dry_run=dry_run, no_prompt=force)
6166
5878
 
6167
5879
 
6168
5880
class cmd_reference(Command):
6169
 
    __doc__ = """list, view and set branch locations for nested trees.
 
5881
    """list, view and set branch locations for nested trees.
6170
5882
 
6171
5883
    If no arguments are provided, lists the branch locations for nested trees.
6172
5884
    If one argument is provided, display the branch location for that tree.
6212
5924
            self.outf.write('%s %s\n' % (path, location))
6213
5925
 
6214
5926
 
6215
 
class cmd_export_pot(Command):
6216
 
    __doc__ = """Export command helps and error messages in po format."""
6217
 
 
6218
 
    hidden = True
6219
 
 
6220
 
    def run(self):
6221
 
        from bzrlib.export_pot import export_pot
6222
 
        export_pot(self.outf)
6223
 
 
6224
 
 
6225
 
def _register_lazy_builtins():
6226
 
    # register lazy builtins from other modules; called at startup and should
6227
 
    # be only called once.
6228
 
    for (name, aliases, module_name) in [
6229
 
        ('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6230
 
        ('cmd_config', [], 'bzrlib.config'),
6231
 
        ('cmd_dpush', [], 'bzrlib.foreign'),
6232
 
        ('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6233
 
        ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6234
 
        ('cmd_conflicts', [], 'bzrlib.conflicts'),
6235
 
        ('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6236
 
        ('cmd_verify_signatures', [],
6237
 
                                        'bzrlib.commit_signature_commands'),
6238
 
        ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6239
 
        ]:
6240
 
        builtin_command_registry.register_lazy(name, aliases, module_name)
 
5927
# these get imported and then picked up by the scan for cmd_*
 
5928
# TODO: Some more consistent way to split command definitions across files;
 
5929
# we do need to load at least some information about them to know of
 
5930
# aliases.  ideally we would avoid loading the implementation until the
 
5931
# details were needed.
 
5932
from bzrlib.cmd_version_info import cmd_version_info
 
5933
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
 
5934
from bzrlib.bundle.commands import (
 
5935
    cmd_bundle_info,
 
5936
    )
 
5937
from bzrlib.foreign import cmd_dpush
 
5938
from bzrlib.sign_my_commits import cmd_sign_my_commits