/brz/remove-bazaar

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

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Martin Pool
  • Date: 2010-04-23 00:44:15 UTC
  • mto: This revision was merged to the branch mainline in revision 5189.
  • Revision ID: mbp@canonical.com-20100423004415-py8ozrtkjo6tphj2
Update more code to use user_transport when it should

Show diffs side-by-side

added added

removed removed

Lines of Context:
232
232
    return view_info
233
233
 
234
234
 
235
 
def _open_directory_or_containing_tree_or_branch(filename, directory):
236
 
    """Open the tree or branch containing the specified file, unless
237
 
    the --directory option is used to specify a different branch."""
238
 
    if directory is not None:
239
 
        return (None, Branch.open(directory), filename)
240
 
    return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
241
 
 
242
 
 
243
235
# TODO: Make sure no commands unconditionally use the working directory as a
244
236
# branch.  If a filename argument is used, the first of them should be used to
245
237
# specify the branch.  (Perhaps this can be factored out into some kind of
247
239
# opens the branch?)
248
240
 
249
241
class cmd_status(Command):
250
 
    __doc__ = """Display status summary.
 
242
    """Display status summary.
251
243
 
252
244
    This reports on versioned and unknown files, reporting them
253
245
    grouped by state.  Possible states are:
340
332
 
341
333
 
342
334
class cmd_cat_revision(Command):
343
 
    __doc__ = """Write out metadata for a revision.
 
335
    """Write out metadata for a revision.
344
336
 
345
337
    The revision to print can either be specified by a specific
346
338
    revision identifier, or you can use --revision.
348
340
 
349
341
    hidden = True
350
342
    takes_args = ['revision_id?']
351
 
    takes_options = ['directory', 'revision']
 
343
    takes_options = ['revision']
352
344
    # cat-revision is more for frontends so should be exact
353
345
    encoding = 'strict'
354
346
 
361
353
        self.outf.write(revtext.decode('utf-8'))
362
354
 
363
355
    @display_command
364
 
    def run(self, revision_id=None, revision=None, directory=u'.'):
 
356
    def run(self, revision_id=None, revision=None):
365
357
        if revision_id is not None and revision is not None:
366
358
            raise errors.BzrCommandError('You can only supply one of'
367
359
                                         ' revision_id or --revision')
368
360
        if revision_id is None and revision is None:
369
361
            raise errors.BzrCommandError('You must supply either'
370
362
                                         ' --revision or a revision_id')
371
 
        b = WorkingTree.open_containing(directory)[0].branch
 
363
        b = WorkingTree.open_containing(u'.')[0].branch
372
364
 
373
365
        revisions = b.repository.revisions
374
366
        if revisions is None:
398
390
        
399
391
 
400
392
class cmd_dump_btree(Command):
401
 
    __doc__ = """Dump the contents of a btree index file to stdout.
 
393
    """Dump the contents of a btree index file to stdout.
402
394
 
403
395
    PATH is a btree index file, it can be any URL. This includes things like
404
396
    .bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
479
471
 
480
472
 
481
473
class cmd_remove_tree(Command):
482
 
    __doc__ = """Remove the working tree from a given branch/checkout.
 
474
    """Remove the working tree from a given branch/checkout.
483
475
 
484
476
    Since a lightweight checkout is little more than a working tree
485
477
    this will refuse to run against one.
520
512
 
521
513
 
522
514
class cmd_revno(Command):
523
 
    __doc__ = """Show current revision number.
 
515
    """Show current revision number.
524
516
 
525
517
    This is equal to the number of revisions on this branch.
526
518
    """
536
528
        if tree:
537
529
            try:
538
530
                wt = WorkingTree.open_containing(location)[0]
539
 
                self.add_cleanup(wt.lock_read().unlock)
 
531
                wt.lock_read()
540
532
            except (errors.NoWorkingTree, errors.NotLocalUrl):
541
533
                raise errors.NoWorkingTree(location)
 
534
            self.add_cleanup(wt.unlock)
542
535
            revid = wt.last_revision()
543
536
            try:
544
537
                revno_t = wt.branch.revision_id_to_dotted_revno(revid)
547
540
            revno = ".".join(str(n) for n in revno_t)
548
541
        else:
549
542
            b = Branch.open_containing(location)[0]
550
 
            self.add_cleanup(b.lock_read().unlock)
 
543
            b.lock_read()
 
544
            self.add_cleanup(b.unlock)
551
545
            revno = b.revno()
552
546
        self.cleanup_now()
553
547
        self.outf.write(str(revno) + '\n')
554
548
 
555
549
 
556
550
class cmd_revision_info(Command):
557
 
    __doc__ = """Show revision number and revision id for a given revision identifier.
 
551
    """Show revision number and revision id for a given revision identifier.
558
552
    """
559
553
    hidden = True
560
554
    takes_args = ['revision_info*']
561
555
    takes_options = [
562
556
        'revision',
563
 
        custom_help('directory',
 
557
        Option('directory',
564
558
            help='Branch to examine, '
565
 
                 'rather than the one containing the working directory.'),
 
559
                 'rather than the one containing the working directory.',
 
560
            short_name='d',
 
561
            type=unicode,
 
562
            ),
566
563
        Option('tree', help='Show revno of working tree'),
567
564
        ]
568
565
 
573
570
        try:
574
571
            wt = WorkingTree.open_containing(directory)[0]
575
572
            b = wt.branch
576
 
            self.add_cleanup(wt.lock_read().unlock)
 
573
            wt.lock_read()
 
574
            self.add_cleanup(wt.unlock)
577
575
        except (errors.NoWorkingTree, errors.NotLocalUrl):
578
576
            wt = None
579
577
            b = Branch.open_containing(directory)[0]
580
 
            self.add_cleanup(b.lock_read().unlock)
 
578
            b.lock_read()
 
579
            self.add_cleanup(b.unlock)
581
580
        revision_ids = []
582
581
        if revision is not None:
583
582
            revision_ids.extend(rev.as_revision_id(b) for rev in revision)
611
610
 
612
611
 
613
612
class cmd_add(Command):
614
 
    __doc__ = """Add specified files or directories.
 
613
    """Add specified files or directories.
615
614
 
616
615
    In non-recursive mode, all the named items are added, regardless
617
616
    of whether they were previously ignored.  A warning is given if
682
681
                should_print=(not is_quiet()))
683
682
 
684
683
        if base_tree:
685
 
            self.add_cleanup(base_tree.lock_read().unlock)
 
684
            base_tree.lock_read()
 
685
            self.add_cleanup(base_tree.unlock)
686
686
        tree, file_list = tree_files_for_add(file_list)
687
687
        added, ignored = tree.smart_add(file_list, not
688
688
            no_recurse, action=action, save=not dry_run)
696
696
 
697
697
 
698
698
class cmd_mkdir(Command):
699
 
    __doc__ = """Create a new versioned directory.
 
699
    """Create a new versioned directory.
700
700
 
701
701
    This is equivalent to creating the directory and then adding it.
702
702
    """
718
718
 
719
719
 
720
720
class cmd_relpath(Command):
721
 
    __doc__ = """Show path of a file relative to root"""
 
721
    """Show path of a file relative to root"""
722
722
 
723
723
    takes_args = ['filename']
724
724
    hidden = True
733
733
 
734
734
 
735
735
class cmd_inventory(Command):
736
 
    __doc__ = """Show inventory of the current working copy or a revision.
 
736
    """Show inventory of the current working copy or a revision.
737
737
 
738
738
    It is possible to limit the output to a particular entry
739
739
    type using the --kind option.  For example: --kind file.
760
760
 
761
761
        revision = _get_one_revision('inventory', revision)
762
762
        work_tree, file_list = tree_files(file_list)
763
 
        self.add_cleanup(work_tree.lock_read().unlock)
 
763
        work_tree.lock_read()
 
764
        self.add_cleanup(work_tree.unlock)
764
765
        if revision is not None:
765
766
            tree = revision.as_tree(work_tree.branch)
766
767
 
767
768
            extra_trees = [work_tree]
768
 
            self.add_cleanup(tree.lock_read().unlock)
 
769
            tree.lock_read()
 
770
            self.add_cleanup(tree.unlock)
769
771
        else:
770
772
            tree = work_tree
771
773
            extra_trees = []
792
794
 
793
795
 
794
796
class cmd_mv(Command):
795
 
    __doc__ = """Move or rename a file.
 
797
    """Move or rename a file.
796
798
 
797
799
    :Usage:
798
800
        bzr mv OLDNAME NEWNAME
831
833
        if len(names_list) < 2:
832
834
            raise errors.BzrCommandError("missing file argument")
833
835
        tree, rel_names = tree_files(names_list, canonicalize=False)
834
 
        self.add_cleanup(tree.lock_tree_write().unlock)
 
836
        tree.lock_tree_write()
 
837
        self.add_cleanup(tree.unlock)
835
838
        self._run(tree, names_list, rel_names, after)
836
839
 
837
840
    def run_auto(self, names_list, after, dry_run):
842
845
            raise errors.BzrCommandError('--after cannot be specified with'
843
846
                                         ' --auto.')
844
847
        work_tree, file_list = tree_files(names_list, default_branch='.')
845
 
        self.add_cleanup(work_tree.lock_tree_write().unlock)
 
848
        work_tree.lock_tree_write()
 
849
        self.add_cleanup(work_tree.unlock)
846
850
        rename_map.RenameMap.guess_renames(work_tree, dry_run)
847
851
 
848
852
    def _run(self, tree, names_list, rel_names, after):
927
931
 
928
932
 
929
933
class cmd_pull(Command):
930
 
    __doc__ = """Turn this branch into a mirror of another branch.
 
934
    """Turn this branch into a mirror of another branch.
931
935
 
932
936
    By default, this command only works on branches that have not diverged.
933
937
    Branches are considered diverged if the destination branch's most recent 
956
960
    takes_options = ['remember', 'overwrite', 'revision',
957
961
        custom_help('verbose',
958
962
            help='Show logs of pulled revisions.'),
959
 
        custom_help('directory',
 
963
        Option('directory',
960
964
            help='Branch to pull into, '
961
 
                 'rather than the one containing the working directory.'),
 
965
                 'rather than the one containing the working directory.',
 
966
            short_name='d',
 
967
            type=unicode,
 
968
            ),
962
969
        Option('local',
963
970
            help="Perform a local pull in a bound "
964
971
                 "branch.  Local pulls are not applied to "
979
986
        try:
980
987
            tree_to = WorkingTree.open_containing(directory)[0]
981
988
            branch_to = tree_to.branch
982
 
            self.add_cleanup(tree_to.lock_write().unlock)
 
989
            tree_to.lock_write()
 
990
            self.add_cleanup(tree_to.unlock)
983
991
        except errors.NoWorkingTree:
984
992
            tree_to = None
985
993
            branch_to = Branch.open_containing(directory)[0]
986
 
            self.add_cleanup(branch_to.lock_write().unlock)
 
994
            branch_to.lock_write()
 
995
            self.add_cleanup(branch_to.unlock)
987
996
 
988
997
        if local and not branch_to.get_bound_location():
989
998
            raise errors.LocalRequiresBoundBranch()
1020
1029
        else:
1021
1030
            branch_from = Branch.open(location,
1022
1031
                possible_transports=possible_transports)
1023
 
            self.add_cleanup(branch_from.lock_read().unlock)
 
1032
            branch_from.lock_read()
 
1033
            self.add_cleanup(branch_from.unlock)
1024
1034
 
1025
1035
            if branch_to.get_parent() is None or remember:
1026
1036
                branch_to.set_parent(branch_from.base)
1048
1058
 
1049
1059
 
1050
1060
class cmd_push(Command):
1051
 
    __doc__ = """Update a mirror of this branch.
 
1061
    """Update a mirror of this branch.
1052
1062
 
1053
1063
    The target branch will not have its working tree populated because this
1054
1064
    is both expensive, and is not supported on remote file systems.
1078
1088
        Option('create-prefix',
1079
1089
               help='Create the path leading up to the branch '
1080
1090
                    'if it does not already exist.'),
1081
 
        custom_help('directory',
 
1091
        Option('directory',
1082
1092
            help='Branch to push from, '
1083
 
                 'rather than the one containing the working directory.'),
 
1093
                 'rather than the one containing the working directory.',
 
1094
            short_name='d',
 
1095
            type=unicode,
 
1096
            ),
1084
1097
        Option('use-existing-dir',
1085
1098
               help='By default push will fail if the target'
1086
1099
                    ' directory exists, but does not already'
1119
1132
        else:
1120
1133
            revision_id = None
1121
1134
        if tree is not None and revision_id is None:
1122
 
            tree.check_changed_or_out_of_date(
1123
 
                strict, 'push_strict',
1124
 
                more_error='Use --no-strict to force the push.',
1125
 
                more_warning='Uncommitted changes will not be pushed.')
 
1135
            tree.warn_if_changed_or_out_of_date(
 
1136
                strict, 'push_strict', 'Use --no-strict to force the push.')
1126
1137
        # Get the stacked_on branch, if any
1127
1138
        if stacked_on is not None:
1128
1139
            stacked_on = urlutils.normalize_url(stacked_on)
1160
1171
 
1161
1172
 
1162
1173
class cmd_branch(Command):
1163
 
    __doc__ = """Create a new branch that is a copy of an existing branch.
 
1174
    """Create a new branch that is a copy of an existing branch.
1164
1175
 
1165
1176
    If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1166
1177
    be used.  In other words, "branch ../foo/bar" will attempt to create ./bar.
1206
1217
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1207
1218
            from_location)
1208
1219
        revision = _get_one_revision('branch', revision)
1209
 
        self.add_cleanup(br_from.lock_read().unlock)
 
1220
        br_from.lock_read()
 
1221
        self.add_cleanup(br_from.unlock)
1210
1222
        if revision is not None:
1211
1223
            revision_id = revision.as_revision_id(br_from)
1212
1224
        else:
1272
1284
 
1273
1285
 
1274
1286
class cmd_checkout(Command):
1275
 
    __doc__ = """Create a new checkout of an existing branch.
 
1287
    """Create a new checkout of an existing branch.
1276
1288
 
1277
1289
    If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1278
1290
    the branch found in '.'. This is useful if you have removed the working tree
1341
1353
 
1342
1354
 
1343
1355
class cmd_renames(Command):
1344
 
    __doc__ = """Show list of renamed files.
 
1356
    """Show list of renamed files.
1345
1357
    """
1346
1358
    # TODO: Option to show renames between two historical versions.
1347
1359
 
1352
1364
    @display_command
1353
1365
    def run(self, dir=u'.'):
1354
1366
        tree = WorkingTree.open_containing(dir)[0]
1355
 
        self.add_cleanup(tree.lock_read().unlock)
 
1367
        tree.lock_read()
 
1368
        self.add_cleanup(tree.unlock)
1356
1369
        new_inv = tree.inventory
1357
1370
        old_tree = tree.basis_tree()
1358
 
        self.add_cleanup(old_tree.lock_read().unlock)
 
1371
        old_tree.lock_read()
 
1372
        self.add_cleanup(old_tree.unlock)
1359
1373
        old_inv = old_tree.inventory
1360
1374
        renames = []
1361
1375
        iterator = tree.iter_changes(old_tree, include_unchanged=True)
1371
1385
 
1372
1386
 
1373
1387
class cmd_update(Command):
1374
 
    __doc__ = """Update a tree to have the latest code committed to its branch.
 
1388
    """Update a tree to have the latest code committed to its branch.
1375
1389
 
1376
1390
    This will perform a merge into the working tree, and may generate
1377
1391
    conflicts. If you have any local changes, you will still
1399
1413
        master = branch.get_master_branch(
1400
1414
            possible_transports=possible_transports)
1401
1415
        if master is not None:
 
1416
            tree.lock_write()
1402
1417
            branch_location = master.base
1403
 
            tree.lock_write()
1404
1418
        else:
 
1419
            tree.lock_tree_write()
1405
1420
            branch_location = tree.branch.base
1406
 
            tree.lock_tree_write()
1407
1421
        self.add_cleanup(tree.unlock)
1408
1422
        # get rid of the final '/' and be ready for display
1409
1423
        branch_location = urlutils.unescape_for_display(
1457
1471
 
1458
1472
 
1459
1473
class cmd_info(Command):
1460
 
    __doc__ = """Show information about a working tree, branch or repository.
 
1474
    """Show information about a working tree, branch or repository.
1461
1475
 
1462
1476
    This command will show all known locations and formats associated to the
1463
1477
    tree, branch or repository.
1501
1515
 
1502
1516
 
1503
1517
class cmd_remove(Command):
1504
 
    __doc__ = """Remove files or directories.
 
1518
    """Remove files or directories.
1505
1519
 
1506
1520
    This makes bzr stop tracking changes to the specified files. bzr will delete
1507
1521
    them if they can easily be recovered using revert. If no options or
1529
1543
        if file_list is not None:
1530
1544
            file_list = [f for f in file_list]
1531
1545
 
1532
 
        self.add_cleanup(tree.lock_write().unlock)
 
1546
        tree.lock_write()
 
1547
        self.add_cleanup(tree.unlock)
1533
1548
        # Heuristics should probably all move into tree.remove_smart or
1534
1549
        # some such?
1535
1550
        if new:
1554
1569
 
1555
1570
 
1556
1571
class cmd_file_id(Command):
1557
 
    __doc__ = """Print file_id of a particular file or directory.
 
1572
    """Print file_id of a particular file or directory.
1558
1573
 
1559
1574
    The file_id is assigned when the file is first added and remains the
1560
1575
    same through all revisions where the file exists, even when it is
1576
1591
 
1577
1592
 
1578
1593
class cmd_file_path(Command):
1579
 
    __doc__ = """Print path of file_ids to a file or directory.
 
1594
    """Print path of file_ids to a file or directory.
1580
1595
 
1581
1596
    This prints one line for each directory down to the target,
1582
1597
    starting at the branch root.
1598
1613
 
1599
1614
 
1600
1615
class cmd_reconcile(Command):
1601
 
    __doc__ = """Reconcile bzr metadata in a branch.
 
1616
    """Reconcile bzr metadata in a branch.
1602
1617
 
1603
1618
    This can correct data mismatches that may have been caused by
1604
1619
    previous ghost operations or bzr upgrades. You should only
1626
1641
 
1627
1642
 
1628
1643
class cmd_revision_history(Command):
1629
 
    __doc__ = """Display the list of revision ids on a branch."""
 
1644
    """Display the list of revision ids on a branch."""
1630
1645
 
1631
1646
    _see_also = ['log']
1632
1647
    takes_args = ['location?']
1642
1657
 
1643
1658
 
1644
1659
class cmd_ancestry(Command):
1645
 
    __doc__ = """List all revisions merged into this branch."""
 
1660
    """List all revisions merged into this branch."""
1646
1661
 
1647
1662
    _see_also = ['log', 'revision-history']
1648
1663
    takes_args = ['location?']
1667
1682
 
1668
1683
 
1669
1684
class cmd_init(Command):
1670
 
    __doc__ = """Make a directory into a versioned branch.
 
1685
    """Make a directory into a versioned branch.
1671
1686
 
1672
1687
    Use this to create an empty branch, or before importing an
1673
1688
    existing project.
1776
1791
 
1777
1792
 
1778
1793
class cmd_init_repository(Command):
1779
 
    __doc__ = """Create a shared repository for branches to share storage space.
 
1794
    """Create a shared repository for branches to share storage space.
1780
1795
 
1781
1796
    New branches created under the repository directory will store their
1782
1797
    revisions in the repository, not in the branch directory.  For branches
1836
1851
 
1837
1852
 
1838
1853
class cmd_diff(Command):
1839
 
    __doc__ = """Show differences in the working tree, between revisions or branches.
 
1854
    """Show differences in the working tree, between revisions or branches.
1840
1855
 
1841
1856
    If no arguments are given, all changes for the current tree are listed.
1842
1857
    If files are given, only the changes in those files are listed.
1977
1992
 
1978
1993
 
1979
1994
class cmd_deleted(Command):
1980
 
    __doc__ = """List files deleted in the working tree.
 
1995
    """List files deleted in the working tree.
1981
1996
    """
1982
1997
    # TODO: Show files deleted since a previous revision, or
1983
1998
    # between two revisions.
1986
2001
    # level of effort but possibly much less IO.  (Or possibly not,
1987
2002
    # if the directories are very large...)
1988
2003
    _see_also = ['status', 'ls']
1989
 
    takes_options = ['directory', 'show-ids']
 
2004
    takes_options = ['show-ids']
1990
2005
 
1991
2006
    @display_command
1992
 
    def run(self, show_ids=False, directory=u'.'):
1993
 
        tree = WorkingTree.open_containing(directory)[0]
1994
 
        self.add_cleanup(tree.lock_read().unlock)
 
2007
    def run(self, show_ids=False):
 
2008
        tree = WorkingTree.open_containing(u'.')[0]
 
2009
        tree.lock_read()
 
2010
        self.add_cleanup(tree.unlock)
1995
2011
        old = tree.basis_tree()
1996
 
        self.add_cleanup(old.lock_read().unlock)
 
2012
        old.lock_read()
 
2013
        self.add_cleanup(old.unlock)
1997
2014
        for path, ie in old.inventory.iter_entries():
1998
2015
            if not tree.has_id(ie.file_id):
1999
2016
                self.outf.write(path)
2004
2021
 
2005
2022
 
2006
2023
class cmd_modified(Command):
2007
 
    __doc__ = """List files modified in working tree.
 
2024
    """List files modified in working tree.
2008
2025
    """
2009
2026
 
2010
2027
    hidden = True
2011
2028
    _see_also = ['status', 'ls']
2012
 
    takes_options = ['directory', 'null']
 
2029
    takes_options = [
 
2030
            Option('null',
 
2031
                   help='Write an ascii NUL (\\0) separator '
 
2032
                   'between files rather than a newline.')
 
2033
            ]
2013
2034
 
2014
2035
    @display_command
2015
 
    def run(self, null=False, directory=u'.'):
2016
 
        tree = WorkingTree.open_containing(directory)[0]
 
2036
    def run(self, null=False):
 
2037
        tree = WorkingTree.open_containing(u'.')[0]
2017
2038
        td = tree.changes_from(tree.basis_tree())
2018
2039
        for path, id, kind, text_modified, meta_modified in td.modified:
2019
2040
            if null:
2023
2044
 
2024
2045
 
2025
2046
class cmd_added(Command):
2026
 
    __doc__ = """List files added in working tree.
 
2047
    """List files added in working tree.
2027
2048
    """
2028
2049
 
2029
2050
    hidden = True
2030
2051
    _see_also = ['status', 'ls']
2031
 
    takes_options = ['directory', 'null']
 
2052
    takes_options = [
 
2053
            Option('null',
 
2054
                   help='Write an ascii NUL (\\0) separator '
 
2055
                   'between files rather than a newline.')
 
2056
            ]
2032
2057
 
2033
2058
    @display_command
2034
 
    def run(self, null=False, directory=u'.'):
2035
 
        wt = WorkingTree.open_containing(directory)[0]
2036
 
        self.add_cleanup(wt.lock_read().unlock)
 
2059
    def run(self, null=False):
 
2060
        wt = WorkingTree.open_containing(u'.')[0]
 
2061
        wt.lock_read()
 
2062
        self.add_cleanup(wt.unlock)
2037
2063
        basis = wt.basis_tree()
2038
 
        self.add_cleanup(basis.lock_read().unlock)
 
2064
        basis.lock_read()
 
2065
        self.add_cleanup(basis.unlock)
2039
2066
        basis_inv = basis.inventory
2040
2067
        inv = wt.inventory
2041
2068
        for file_id in inv:
2044
2071
            if inv.is_root(file_id) and len(basis_inv) == 0:
2045
2072
                continue
2046
2073
            path = inv.id2path(file_id)
2047
 
            if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
 
2074
            if not os.access(osutils.abspath(path), os.F_OK):
2048
2075
                continue
2049
2076
            if null:
2050
2077
                self.outf.write(path + '\0')
2053
2080
 
2054
2081
 
2055
2082
class cmd_root(Command):
2056
 
    __doc__ = """Show the tree root directory.
 
2083
    """Show the tree root directory.
2057
2084
 
2058
2085
    The root is the nearest enclosing directory with a .bzr control
2059
2086
    directory."""
2083
2110
 
2084
2111
 
2085
2112
class cmd_log(Command):
2086
 
    __doc__ = """Show historical log for a branch or subset of a branch.
 
2113
    """Show historical log for a branch or subset of a branch.
2087
2114
 
2088
2115
    log is bzr's default tool for exploring the history of a branch.
2089
2116
    The branch to use is taken from the first parameter. If no parameters
2250
2277
                   help='Show just the specified revision.'
2251
2278
                   ' See also "help revisionspec".'),
2252
2279
            'log-format',
2253
 
            RegistryOption('authors',
2254
 
                'What names to list as authors - first, all or committer.',
2255
 
                title='Authors',
2256
 
                lazy_registry=('bzrlib.log', 'author_list_registry'),
2257
 
            ),
2258
2280
            Option('levels',
2259
2281
                   short_name='n',
2260
2282
                   help='Number of levels to display - 0 for all, 1 for flat.',
2275
2297
                   help='Show changes made in each revision as a patch.'),
2276
2298
            Option('include-merges',
2277
2299
                   help='Show merged revisions like --levels 0 does.'),
2278
 
            Option('exclude-common-ancestry',
2279
 
                   help='Display only the revisions that are not part'
2280
 
                   ' of both ancestries (require -rX..Y)'
2281
 
                   )
2282
2300
            ]
2283
2301
    encoding_type = 'replace'
2284
2302
 
2294
2312
            message=None,
2295
2313
            limit=None,
2296
2314
            show_diff=False,
2297
 
            include_merges=False,
2298
 
            authors=None,
2299
 
            exclude_common_ancestry=False,
2300
 
            ):
 
2315
            include_merges=False):
2301
2316
        from bzrlib.log import (
2302
2317
            Logger,
2303
2318
            make_log_request_dict,
2304
2319
            _get_info_for_log_files,
2305
2320
            )
2306
2321
        direction = (forward and 'forward') or 'reverse'
2307
 
        if (exclude_common_ancestry
2308
 
            and (revision is None or len(revision) != 2)):
2309
 
            raise errors.BzrCommandError(
2310
 
                '--exclude-common-ancestry requires -r with two revisions')
2311
2322
        if include_merges:
2312
2323
            if levels is None:
2313
2324
                levels = 0
2329
2340
        if file_list:
2330
2341
            # find the file ids to log and check for directory filtering
2331
2342
            b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2332
 
                revision, file_list, self.add_cleanup)
 
2343
                revision, file_list)
 
2344
            self.add_cleanup(b.unlock)
2333
2345
            for relpath, file_id, kind in file_info_list:
2334
2346
                if file_id is None:
2335
2347
                    raise errors.BzrCommandError(
2353
2365
                location = '.'
2354
2366
            dir, relpath = bzrdir.BzrDir.open_containing(location)
2355
2367
            b = dir.open_branch()
2356
 
            self.add_cleanup(b.lock_read().unlock)
 
2368
            b.lock_read()
 
2369
            self.add_cleanup(b.unlock)
2357
2370
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2358
2371
 
2359
2372
        # Decide on the type of delta & diff filtering to use
2379
2392
                        show_timezone=timezone,
2380
2393
                        delta_format=get_verbosity_level(),
2381
2394
                        levels=levels,
2382
 
                        show_advice=levels is None,
2383
 
                        author_list_handler=authors)
 
2395
                        show_advice=levels is None)
2384
2396
 
2385
2397
        # Choose the algorithm for doing the logging. It's annoying
2386
2398
        # having multiple code paths like this but necessary until
2405
2417
            direction=direction, specific_fileids=file_ids,
2406
2418
            start_revision=rev1, end_revision=rev2, limit=limit,
2407
2419
            message_search=message, delta_type=delta_type,
2408
 
            diff_type=diff_type, _match_using_deltas=match_using_deltas,
2409
 
            exclude_common_ancestry=exclude_common_ancestry,
2410
 
            )
 
2420
            diff_type=diff_type, _match_using_deltas=match_using_deltas)
2411
2421
        Logger(b, rqst).show(lf)
2412
2422
 
2413
2423
 
2471
2481
 
2472
2482
 
2473
2483
class cmd_touching_revisions(Command):
2474
 
    __doc__ = """Return revision-ids which affected a particular file.
 
2484
    """Return revision-ids which affected a particular file.
2475
2485
 
2476
2486
    A more user-friendly interface is "bzr log FILE".
2477
2487
    """
2484
2494
        tree, relpath = WorkingTree.open_containing(filename)
2485
2495
        file_id = tree.path2id(relpath)
2486
2496
        b = tree.branch
2487
 
        self.add_cleanup(b.lock_read().unlock)
 
2497
        b.lock_read()
 
2498
        self.add_cleanup(b.unlock)
2488
2499
        touching_revs = log.find_touching_revisions(b, file_id)
2489
2500
        for revno, revision_id, what in touching_revs:
2490
2501
            self.outf.write("%6d %s\n" % (revno, what))
2491
2502
 
2492
2503
 
2493
2504
class cmd_ls(Command):
2494
 
    __doc__ = """List files in a tree.
 
2505
    """List files in a tree.
2495
2506
    """
2496
2507
 
2497
2508
    _see_also = ['status', 'cat']
2503
2514
                   help='Recurse into subdirectories.'),
2504
2515
            Option('from-root',
2505
2516
                   help='Print paths relative to the root of the branch.'),
2506
 
            Option('unknown', short_name='u',
2507
 
                help='Print unknown files.'),
 
2517
            Option('unknown', help='Print unknown files.'),
2508
2518
            Option('versioned', help='Print versioned files.',
2509
2519
                   short_name='V'),
2510
 
            Option('ignored', short_name='i',
2511
 
                help='Print ignored files.'),
2512
 
            Option('kind', short_name='k',
 
2520
            Option('ignored', help='Print ignored files.'),
 
2521
            Option('null',
 
2522
                   help='Write an ascii NUL (\\0) separator '
 
2523
                   'between files rather than a newline.'),
 
2524
            Option('kind',
2513
2525
                   help='List entries of a particular kind: file, directory, symlink.',
2514
2526
                   type=unicode),
2515
 
            'null',
2516
2527
            'show-ids',
2517
 
            'directory',
2518
2528
            ]
2519
2529
    @display_command
2520
2530
    def run(self, revision=None, verbose=False,
2521
2531
            recursive=False, from_root=False,
2522
2532
            unknown=False, versioned=False, ignored=False,
2523
 
            null=False, kind=None, show_ids=False, path=None, directory=None):
 
2533
            null=False, kind=None, show_ids=False, path=None):
2524
2534
 
2525
2535
        if kind and kind not in ('file', 'directory', 'symlink'):
2526
2536
            raise errors.BzrCommandError('invalid kind specified')
2538
2548
                raise errors.BzrCommandError('cannot specify both --from-root'
2539
2549
                                             ' and PATH')
2540
2550
            fs_path = path
2541
 
        tree, branch, relpath = \
2542
 
            _open_directory_or_containing_tree_or_branch(fs_path, directory)
 
2551
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
2552
            fs_path)
2543
2553
 
2544
2554
        # Calculate the prefix to use
2545
2555
        prefix = None
2560
2570
                view_str = views.view_display_str(view_files)
2561
2571
                note("Ignoring files outside view. View is %s" % view_str)
2562
2572
 
2563
 
        self.add_cleanup(tree.lock_read().unlock)
 
2573
        tree.lock_read()
 
2574
        self.add_cleanup(tree.unlock)
2564
2575
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2565
2576
            from_dir=relpath, recursive=recursive):
2566
2577
            # Apply additional masking
2608
2619
 
2609
2620
 
2610
2621
class cmd_unknowns(Command):
2611
 
    __doc__ = """List unknown files.
 
2622
    """List unknown files.
2612
2623
    """
2613
2624
 
2614
2625
    hidden = True
2615
2626
    _see_also = ['ls']
2616
 
    takes_options = ['directory']
2617
2627
 
2618
2628
    @display_command
2619
 
    def run(self, directory=u'.'):
2620
 
        for f in WorkingTree.open_containing(directory)[0].unknowns():
 
2629
    def run(self):
 
2630
        for f in WorkingTree.open_containing(u'.')[0].unknowns():
2621
2631
            self.outf.write(osutils.quotefn(f) + '\n')
2622
2632
 
2623
2633
 
2624
2634
class cmd_ignore(Command):
2625
 
    __doc__ = """Ignore specified files or patterns.
 
2635
    """Ignore specified files or patterns.
2626
2636
 
2627
2637
    See ``bzr help patterns`` for details on the syntax of patterns.
2628
2638
 
2637
2647
    using this command or directly by using an editor, be sure to commit
2638
2648
    it.
2639
2649
    
2640
 
    Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
2641
 
    the global ignore file can be found in the application data directory as
2642
 
    C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
2643
 
    Global ignores are not touched by this command. The global ignore file
2644
 
    can be edited directly using an editor.
2645
 
 
2646
2650
    Patterns prefixed with '!' are exceptions to ignore patterns and take
2647
2651
    precedence over regular ignores.  Such exceptions are used to specify
2648
2652
    files that should be versioned which would otherwise be ignored.
2688
2692
 
2689
2693
    _see_also = ['status', 'ignored', 'patterns']
2690
2694
    takes_args = ['name_pattern*']
2691
 
    takes_options = ['directory',
2692
 
        Option('default-rules',
2693
 
               help='Display the default ignore rules that bzr uses.')
 
2695
    takes_options = [
 
2696
        Option('old-default-rules',
 
2697
               help='Write out the ignore rules bzr < 0.9 always used.')
2694
2698
        ]
2695
2699
 
2696
 
    def run(self, name_pattern_list=None, default_rules=None,
2697
 
            directory=u'.'):
 
2700
    def run(self, name_pattern_list=None, old_default_rules=None):
2698
2701
        from bzrlib import ignores
2699
 
        if default_rules is not None:
2700
 
            # dump the default rules and exit
2701
 
            for pattern in ignores.USER_DEFAULTS:
 
2702
        if old_default_rules is not None:
 
2703
            # dump the rules and exit
 
2704
            for pattern in ignores.OLD_DEFAULTS:
2702
2705
                self.outf.write("%s\n" % pattern)
2703
2706
            return
2704
2707
        if not name_pattern_list:
2705
2708
            raise errors.BzrCommandError("ignore requires at least one "
2706
 
                "NAME_PATTERN or --default-rules.")
 
2709
                                  "NAME_PATTERN or --old-default-rules")
2707
2710
        name_pattern_list = [globbing.normalize_pattern(p)
2708
2711
                             for p in name_pattern_list]
2709
2712
        for name_pattern in name_pattern_list:
2711
2714
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
2712
2715
                raise errors.BzrCommandError(
2713
2716
                    "NAME_PATTERN should not be an absolute path")
2714
 
        tree, relpath = WorkingTree.open_containing(directory)
 
2717
        tree, relpath = WorkingTree.open_containing(u'.')
2715
2718
        ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2716
2719
        ignored = globbing.Globster(name_pattern_list)
2717
2720
        matches = []
2731
2734
 
2732
2735
 
2733
2736
class cmd_ignored(Command):
2734
 
    __doc__ = """List ignored files and the patterns that matched them.
 
2737
    """List ignored files and the patterns that matched them.
2735
2738
 
2736
2739
    List all the ignored files and the ignore pattern that caused the file to
2737
2740
    be ignored.
2743
2746
 
2744
2747
    encoding_type = 'replace'
2745
2748
    _see_also = ['ignore', 'ls']
2746
 
    takes_options = ['directory']
2747
2749
 
2748
2750
    @display_command
2749
 
    def run(self, directory=u'.'):
2750
 
        tree = WorkingTree.open_containing(directory)[0]
2751
 
        self.add_cleanup(tree.lock_read().unlock)
 
2751
    def run(self):
 
2752
        tree = WorkingTree.open_containing(u'.')[0]
 
2753
        tree.lock_read()
 
2754
        self.add_cleanup(tree.unlock)
2752
2755
        for path, file_class, kind, file_id, entry in tree.list_files():
2753
2756
            if file_class != 'I':
2754
2757
                continue
2758
2761
 
2759
2762
 
2760
2763
class cmd_lookup_revision(Command):
2761
 
    __doc__ = """Lookup the revision-id from a revision-number
 
2764
    """Lookup the revision-id from a revision-number
2762
2765
 
2763
2766
    :Examples:
2764
2767
        bzr lookup-revision 33
2765
2768
    """
2766
2769
    hidden = True
2767
2770
    takes_args = ['revno']
2768
 
    takes_options = ['directory']
2769
2771
 
2770
2772
    @display_command
2771
 
    def run(self, revno, directory=u'.'):
 
2773
    def run(self, revno):
2772
2774
        try:
2773
2775
            revno = int(revno)
2774
2776
        except ValueError:
2775
2777
            raise errors.BzrCommandError("not a valid revision-number: %r"
2776
2778
                                         % revno)
2777
 
        revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
 
2779
        revid = WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2778
2780
        self.outf.write("%s\n" % revid)
2779
2781
 
2780
2782
 
2781
2783
class cmd_export(Command):
2782
 
    __doc__ = """Export current or past revision to a destination directory or archive.
 
2784
    """Export current or past revision to a destination directory or archive.
2783
2785
 
2784
2786
    If no revision is specified this exports the last committed revision.
2785
2787
 
2807
2809
      =================       =========================
2808
2810
    """
2809
2811
    takes_args = ['dest', 'branch_or_subdir?']
2810
 
    takes_options = ['directory',
 
2812
    takes_options = [
2811
2813
        Option('format',
2812
2814
               help="Type of file to export to.",
2813
2815
               type=unicode),
2822
2824
                    'revision in which it was changed.'),
2823
2825
        ]
2824
2826
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2825
 
        root=None, filters=False, per_file_timestamps=False, directory=u'.'):
 
2827
        root=None, filters=False, per_file_timestamps=False):
2826
2828
        from bzrlib.export import export
2827
2829
 
2828
2830
        if branch_or_subdir is None:
2829
 
            tree = WorkingTree.open_containing(directory)[0]
 
2831
            tree = WorkingTree.open_containing(u'.')[0]
2830
2832
            b = tree.branch
2831
2833
            subdir = None
2832
2834
        else:
2842
2844
 
2843
2845
 
2844
2846
class cmd_cat(Command):
2845
 
    __doc__ = """Write the contents of a file as of a given revision to standard output.
 
2847
    """Write the contents of a file as of a given revision to standard output.
2846
2848
 
2847
2849
    If no revision is nominated, the last revision is used.
2848
2850
 
2851
2853
    """
2852
2854
 
2853
2855
    _see_also = ['ls']
2854
 
    takes_options = ['directory',
 
2856
    takes_options = [
2855
2857
        Option('name-from-revision', help='The path name in the old tree.'),
2856
2858
        Option('filters', help='Apply content filters to display the '
2857
2859
                'convenience form.'),
2862
2864
 
2863
2865
    @display_command
2864
2866
    def run(self, filename, revision=None, name_from_revision=False,
2865
 
            filters=False, directory=None):
 
2867
            filters=False):
2866
2868
        if revision is not None and len(revision) != 1:
2867
2869
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
2868
2870
                                         " one revision specifier")
2869
2871
        tree, branch, relpath = \
2870
 
            _open_directory_or_containing_tree_or_branch(filename, directory)
2871
 
        self.add_cleanup(branch.lock_read().unlock)
 
2872
            bzrdir.BzrDir.open_containing_tree_or_branch(filename)
 
2873
        branch.lock_read()
 
2874
        self.add_cleanup(branch.unlock)
2872
2875
        return self._run(tree, branch, relpath, filename, revision,
2873
2876
                         name_from_revision, filters)
2874
2877
 
2877
2880
        if tree is None:
2878
2881
            tree = b.basis_tree()
2879
2882
        rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2880
 
        self.add_cleanup(rev_tree.lock_read().unlock)
 
2883
        rev_tree.lock_read()
 
2884
        self.add_cleanup(rev_tree.unlock)
2881
2885
 
2882
2886
        old_file_id = rev_tree.path2id(relpath)
2883
2887
 
2926
2930
 
2927
2931
 
2928
2932
class cmd_local_time_offset(Command):
2929
 
    __doc__ = """Show the offset in seconds from GMT to local time."""
 
2933
    """Show the offset in seconds from GMT to local time."""
2930
2934
    hidden = True
2931
2935
    @display_command
2932
2936
    def run(self):
2935
2939
 
2936
2940
 
2937
2941
class cmd_commit(Command):
2938
 
    __doc__ = """Commit changes into a new revision.
 
2942
    """Commit changes into a new revision.
2939
2943
 
2940
2944
    An explanatory message needs to be given for each commit. This is
2941
2945
    often done by using the --message option (getting the message from the
3049
3053
                         "the master branch until a normal commit "
3050
3054
                         "is performed."
3051
3055
                    ),
3052
 
             Option('show-diff', short_name='p',
 
3056
             Option('show-diff',
3053
3057
                    help='When no message is supplied, show the diff along'
3054
3058
                    ' with the status summary in the message editor.'),
3055
3059
             ]
3145
3149
        def get_message(commit_obj):
3146
3150
            """Callback to get commit message"""
3147
3151
            if file:
3148
 
                f = codecs.open(file, 'rt', osutils.get_user_encoding())
3149
 
                try:
3150
 
                    my_message = f.read()
3151
 
                finally:
3152
 
                    f.close()
 
3152
                my_message = codecs.open(
 
3153
                    file, 'rt', osutils.get_user_encoding()).read()
3153
3154
            elif message is not None:
3154
3155
                my_message = message
3155
3156
            else:
3204
3205
 
3205
3206
 
3206
3207
class cmd_check(Command):
3207
 
    __doc__ = """Validate working tree structure, branch consistency and repository history.
 
3208
    """Validate working tree structure, branch consistency and repository history.
3208
3209
 
3209
3210
    This command checks various invariants about branch and repository storage
3210
3211
    to detect data corruption or bzr bugs.
3274
3275
 
3275
3276
 
3276
3277
class cmd_upgrade(Command):
3277
 
    __doc__ = """Upgrade branch storage to current format.
 
3278
    """Upgrade branch storage to current format.
3278
3279
 
3279
3280
    The check command or bzr developers may sometimes advise you to run
3280
3281
    this command. When the default format has changed you may also be warned
3298
3299
 
3299
3300
 
3300
3301
class cmd_whoami(Command):
3301
 
    __doc__ = """Show or set bzr user id.
 
3302
    """Show or set bzr user id.
3302
3303
 
3303
3304
    :Examples:
3304
3305
        Show the email of the current user::
3348
3349
 
3349
3350
 
3350
3351
class cmd_nick(Command):
3351
 
    __doc__ = """Print or set the branch nickname.
 
3352
    """Print or set the branch nickname.
3352
3353
 
3353
3354
    If unset, the tree root directory name is used as the nickname.
3354
3355
    To print the current nickname, execute with no argument.
3359
3360
 
3360
3361
    _see_also = ['info']
3361
3362
    takes_args = ['nickname?']
3362
 
    takes_options = ['directory']
3363
 
    def run(self, nickname=None, directory=u'.'):
3364
 
        branch = Branch.open_containing(directory)[0]
 
3363
    def run(self, nickname=None):
 
3364
        branch = Branch.open_containing(u'.')[0]
3365
3365
        if nickname is None:
3366
3366
            self.printme(branch)
3367
3367
        else:
3373
3373
 
3374
3374
 
3375
3375
class cmd_alias(Command):
3376
 
    __doc__ = """Set/unset and display aliases.
 
3376
    """Set/unset and display aliases.
3377
3377
 
3378
3378
    :Examples:
3379
3379
        Show the current aliases::
3443
3443
 
3444
3444
 
3445
3445
class cmd_selftest(Command):
3446
 
    __doc__ = """Run internal test suite.
 
3446
    """Run internal test suite.
3447
3447
 
3448
3448
    If arguments are given, they are regular expressions that say which tests
3449
3449
    should run.  Tests matching any expression are run, and other tests are
3590
3590
                raise errors.BzrCommandError("subunit not available. subunit "
3591
3591
                    "needs to be installed to use --subunit.")
3592
3592
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3593
 
            # On Windows, disable automatic conversion of '\n' to '\r\n' in
3594
 
            # stdout, which would corrupt the subunit stream. 
3595
 
            # FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3596
 
            # following code can be deleted when it's sufficiently deployed
3597
 
            # -- vila/mgz 20100514
3598
 
            if (sys.platform == "win32"
3599
 
                and getattr(sys.stdout, 'fileno', None) is not None):
3600
 
                import msvcrt
3601
 
                msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3602
3593
        if parallel:
3603
3594
            self.additional_selftest_args.setdefault(
3604
3595
                'suite_decorators', []).append(parallel)
3635
3626
 
3636
3627
 
3637
3628
class cmd_version(Command):
3638
 
    __doc__ = """Show version of bzr."""
 
3629
    """Show version of bzr."""
3639
3630
 
3640
3631
    encoding_type = 'replace'
3641
3632
    takes_options = [
3652
3643
 
3653
3644
 
3654
3645
class cmd_rocks(Command):
3655
 
    __doc__ = """Statement of optimism."""
 
3646
    """Statement of optimism."""
3656
3647
 
3657
3648
    hidden = True
3658
3649
 
3662
3653
 
3663
3654
 
3664
3655
class cmd_find_merge_base(Command):
3665
 
    __doc__ = """Find and print a base revision for merging two branches."""
 
3656
    """Find and print a base revision for merging two branches."""
3666
3657
    # TODO: Options to specify revisions on either side, as if
3667
3658
    #       merging only part of the history.
3668
3659
    takes_args = ['branch', 'other']
3674
3665
 
3675
3666
        branch1 = Branch.open_containing(branch)[0]
3676
3667
        branch2 = Branch.open_containing(other)[0]
3677
 
        self.add_cleanup(branch1.lock_read().unlock)
3678
 
        self.add_cleanup(branch2.lock_read().unlock)
 
3668
        branch1.lock_read()
 
3669
        self.add_cleanup(branch1.unlock)
 
3670
        branch2.lock_read()
 
3671
        self.add_cleanup(branch2.unlock)
3679
3672
        last1 = ensure_null(branch1.last_revision())
3680
3673
        last2 = ensure_null(branch2.last_revision())
3681
3674
 
3686
3679
 
3687
3680
 
3688
3681
class cmd_merge(Command):
3689
 
    __doc__ = """Perform a three-way merge.
 
3682
    """Perform a three-way merge.
3690
3683
 
3691
3684
    The source of the merge can be specified either in the form of a branch,
3692
3685
    or in the form of a path to a file containing a merge directive generated
3775
3768
                ' completely merged into the source, pull from the'
3776
3769
                ' source rather than merging.  When this happens,'
3777
3770
                ' you do not need to commit the result.'),
3778
 
        custom_help('directory',
 
3771
        Option('directory',
3779
3772
               help='Branch to merge into, '
3780
 
                    'rather than the one containing the working directory.'),
 
3773
                    'rather than the one containing the working directory.',
 
3774
               short_name='d',
 
3775
               type=unicode,
 
3776
               ),
3781
3777
        Option('preview', help='Instead of merging, show a diff of the'
3782
3778
               ' merge.'),
3783
3779
        Option('interactive', help='Select changes interactively.',
3816
3812
            unversioned_filter=tree.is_ignored, view_info=view_info)
3817
3813
        pb = ui.ui_factory.nested_progress_bar()
3818
3814
        self.add_cleanup(pb.finished)
3819
 
        self.add_cleanup(tree.lock_write().unlock)
 
3815
        tree.lock_write()
 
3816
        self.add_cleanup(tree.unlock)
3820
3817
        if location is not None:
3821
3818
            try:
3822
3819
                mergeable = bundle.read_mergeable_from_url(location,
4043
4040
 
4044
4041
 
4045
4042
class cmd_remerge(Command):
4046
 
    __doc__ = """Redo a merge.
 
4043
    """Redo a merge.
4047
4044
 
4048
4045
    Use this if you want to try a different merge technique while resolving
4049
4046
    conflicts.  Some merge techniques are better than others, and remerge
4078
4075
        if merge_type is None:
4079
4076
            merge_type = _mod_merge.Merge3Merger
4080
4077
        tree, file_list = tree_files(file_list)
4081
 
        self.add_cleanup(tree.lock_write().unlock)
 
4078
        tree.lock_write()
 
4079
        self.add_cleanup(tree.unlock)
4082
4080
        parents = tree.get_parent_ids()
4083
4081
        if len(parents) != 2:
4084
4082
            raise errors.BzrCommandError("Sorry, remerge only works after normal"
4137
4135
 
4138
4136
 
4139
4137
class cmd_revert(Command):
4140
 
    __doc__ = """Revert files to a previous revision.
 
4138
    """Revert files to a previous revision.
4141
4139
 
4142
4140
    Giving a list of files will revert only those files.  Otherwise, all files
4143
4141
    will be reverted.  If the revision is not specified with '--revision', the
4194
4192
    def run(self, revision=None, no_backup=False, file_list=None,
4195
4193
            forget_merges=None):
4196
4194
        tree, file_list = tree_files(file_list)
4197
 
        self.add_cleanup(tree.lock_tree_write().unlock)
 
4195
        tree.lock_write()
 
4196
        self.add_cleanup(tree.unlock)
4198
4197
        if forget_merges:
4199
4198
            tree.set_parent_ids(tree.get_parent_ids()[:1])
4200
4199
        else:
4208
4207
 
4209
4208
 
4210
4209
class cmd_assert_fail(Command):
4211
 
    __doc__ = """Test reporting of assertion failures"""
 
4210
    """Test reporting of assertion failures"""
4212
4211
    # intended just for use in testing
4213
4212
 
4214
4213
    hidden = True
4218
4217
 
4219
4218
 
4220
4219
class cmd_help(Command):
4221
 
    __doc__ = """Show help on a command or other topic.
 
4220
    """Show help on a command or other topic.
4222
4221
    """
4223
4222
 
4224
4223
    _see_also = ['topics']
4237
4236
 
4238
4237
 
4239
4238
class cmd_shell_complete(Command):
4240
 
    __doc__ = """Show appropriate completions for context.
 
4239
    """Show appropriate completions for context.
4241
4240
 
4242
4241
    For a list of all available commands, say 'bzr shell-complete'.
4243
4242
    """
4252
4251
 
4253
4252
 
4254
4253
class cmd_missing(Command):
4255
 
    __doc__ = """Show unmerged/unpulled revisions between two branches.
 
4254
    """Show unmerged/unpulled revisions between two branches.
4256
4255
 
4257
4256
    OTHER_BRANCH may be local or remote.
4258
4257
 
4336
4335
            restrict = 'remote'
4337
4336
 
4338
4337
        local_branch = Branch.open_containing(u".")[0]
4339
 
        self.add_cleanup(local_branch.lock_read().unlock)
 
4338
        local_branch.lock_read()
 
4339
        self.add_cleanup(local_branch.unlock)
4340
4340
 
4341
4341
        parent = local_branch.get_parent()
4342
4342
        if other_branch is None:
4353
4353
        if remote_branch.base == local_branch.base:
4354
4354
            remote_branch = local_branch
4355
4355
        else:
4356
 
            self.add_cleanup(remote_branch.lock_read().unlock)
 
4356
            remote_branch.lock_read()
 
4357
            self.add_cleanup(remote_branch.unlock)
4357
4358
 
4358
4359
        local_revid_range = _revision_range_to_revid_range(
4359
4360
            _get_revision_range(my_revision, local_branch,
4414
4415
            message("Branches are up to date.\n")
4415
4416
        self.cleanup_now()
4416
4417
        if not status_code and parent is None and other_branch is not None:
4417
 
            self.add_cleanup(local_branch.lock_write().unlock)
 
4418
            local_branch.lock_write()
 
4419
            self.add_cleanup(local_branch.unlock)
4418
4420
            # handle race conditions - a parent might be set while we run.
4419
4421
            if local_branch.get_parent() is None:
4420
4422
                local_branch.set_parent(remote_branch.base)
4422
4424
 
4423
4425
 
4424
4426
class cmd_pack(Command):
4425
 
    __doc__ = """Compress the data within a repository.
4426
 
 
4427
 
    This operation compresses the data within a bazaar repository. As
4428
 
    bazaar supports automatic packing of repository, this operation is
4429
 
    normally not required to be done manually.
4430
 
 
4431
 
    During the pack operation, bazaar takes a backup of existing repository
4432
 
    data, i.e. pack files. This backup is eventually removed by bazaar
4433
 
    automatically when it is safe to do so. To save disk space by removing
4434
 
    the backed up pack files, the --clean-obsolete-packs option may be
4435
 
    used.
4436
 
 
4437
 
    Warning: If you use --clean-obsolete-packs and your machine crashes
4438
 
    during or immediately after repacking, you may be left with a state
4439
 
    where the deletion has been written to disk but the new packs have not
4440
 
    been. In this case the repository may be unusable.
4441
 
    """
 
4427
    """Compress the data within a repository."""
4442
4428
 
4443
4429
    _see_also = ['repositories']
4444
4430
    takes_args = ['branch_or_repo?']
4445
 
    takes_options = [
4446
 
        Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4447
 
        ]
4448
4431
 
4449
 
    def run(self, branch_or_repo='.', clean_obsolete_packs=False):
 
4432
    def run(self, branch_or_repo='.'):
4450
4433
        dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4451
4434
        try:
4452
4435
            branch = dir.open_branch()
4453
4436
            repository = branch.repository
4454
4437
        except errors.NotBranchError:
4455
4438
            repository = dir.open_repository()
4456
 
        repository.pack(clean_obsolete_packs=clean_obsolete_packs)
 
4439
        repository.pack()
4457
4440
 
4458
4441
 
4459
4442
class cmd_plugins(Command):
4460
 
    __doc__ = """List the installed plugins.
 
4443
    """List the installed plugins.
4461
4444
 
4462
4445
    This command displays the list of installed plugins including
4463
4446
    version of plugin and a short description of each.
4502
4485
 
4503
4486
 
4504
4487
class cmd_testament(Command):
4505
 
    __doc__ = """Show testament (signing-form) of a revision."""
 
4488
    """Show testament (signing-form) of a revision."""
4506
4489
    takes_options = [
4507
4490
            'revision',
4508
4491
            Option('long', help='Produce long-format testament.'),
4520
4503
            b = Branch.open_containing(branch)[0]
4521
4504
        else:
4522
4505
            b = Branch.open(branch)
4523
 
        self.add_cleanup(b.lock_read().unlock)
 
4506
        b.lock_read()
 
4507
        self.add_cleanup(b.unlock)
4524
4508
        if revision is None:
4525
4509
            rev_id = b.last_revision()
4526
4510
        else:
4533
4517
 
4534
4518
 
4535
4519
class cmd_annotate(Command):
4536
 
    __doc__ = """Show the origin of each line in a file.
 
4520
    """Show the origin of each line in a file.
4537
4521
 
4538
4522
    This prints out the given file with an annotation on the left side
4539
4523
    indicating which revision, author and date introduced the change.
4550
4534
                     Option('long', help='Show commit date in annotations.'),
4551
4535
                     'revision',
4552
4536
                     'show-ids',
4553
 
                     'directory',
4554
4537
                     ]
4555
4538
    encoding_type = 'exact'
4556
4539
 
4557
4540
    @display_command
4558
4541
    def run(self, filename, all=False, long=False, revision=None,
4559
 
            show_ids=False, directory=None):
 
4542
            show_ids=False):
4560
4543
        from bzrlib.annotate import annotate_file, annotate_file_tree
4561
4544
        wt, branch, relpath = \
4562
 
            _open_directory_or_containing_tree_or_branch(filename, directory)
 
4545
            bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4563
4546
        if wt is not None:
4564
 
            self.add_cleanup(wt.lock_read().unlock)
 
4547
            wt.lock_read()
 
4548
            self.add_cleanup(wt.unlock)
4565
4549
        else:
4566
 
            self.add_cleanup(branch.lock_read().unlock)
 
4550
            branch.lock_read()
 
4551
            self.add_cleanup(branch.unlock)
4567
4552
        tree = _get_one_revision_tree('annotate', revision, branch=branch)
4568
 
        self.add_cleanup(tree.lock_read().unlock)
 
4553
        tree.lock_read()
 
4554
        self.add_cleanup(tree.unlock)
4569
4555
        if wt is not None:
4570
4556
            file_id = wt.path2id(relpath)
4571
4557
        else:
4584
4570
 
4585
4571
 
4586
4572
class cmd_re_sign(Command):
4587
 
    __doc__ = """Create a digital signature for an existing revision."""
 
4573
    """Create a digital signature for an existing revision."""
4588
4574
    # TODO be able to replace existing ones.
4589
4575
 
4590
4576
    hidden = True # is this right ?
4591
4577
    takes_args = ['revision_id*']
4592
 
    takes_options = ['directory', 'revision']
 
4578
    takes_options = ['revision']
4593
4579
 
4594
 
    def run(self, revision_id_list=None, revision=None, directory=u'.'):
 
4580
    def run(self, revision_id_list=None, revision=None):
4595
4581
        if revision_id_list is not None and revision is not None:
4596
4582
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4597
4583
        if revision_id_list is None and revision is None:
4598
4584
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4599
 
        b = WorkingTree.open_containing(directory)[0].branch
4600
 
        self.add_cleanup(b.lock_write().unlock)
 
4585
        b = WorkingTree.open_containing(u'.')[0].branch
 
4586
        b.lock_write()
 
4587
        self.add_cleanup(b.unlock)
4601
4588
        return self._run(b, revision_id_list, revision)
4602
4589
 
4603
4590
    def _run(self, b, revision_id_list, revision):
4649
4636
 
4650
4637
 
4651
4638
class cmd_bind(Command):
4652
 
    __doc__ = """Convert the current branch into a checkout of the supplied branch.
4653
 
    If no branch is supplied, rebind to the last bound location.
 
4639
    """Convert the current branch into a checkout of the supplied branch.
4654
4640
 
4655
4641
    Once converted into a checkout, commits must succeed on the master branch
4656
4642
    before they will be applied to the local branch.
4662
4648
 
4663
4649
    _see_also = ['checkouts', 'unbind']
4664
4650
    takes_args = ['location?']
4665
 
    takes_options = ['directory']
 
4651
    takes_options = []
4666
4652
 
4667
 
    def run(self, location=None, directory=u'.'):
4668
 
        b, relpath = Branch.open_containing(directory)
 
4653
    def run(self, location=None):
 
4654
        b, relpath = Branch.open_containing(u'.')
4669
4655
        if location is None:
4670
4656
            try:
4671
4657
                location = b.get_old_bound_location()
4690
4676
 
4691
4677
 
4692
4678
class cmd_unbind(Command):
4693
 
    __doc__ = """Convert the current checkout into a regular branch.
 
4679
    """Convert the current checkout into a regular branch.
4694
4680
 
4695
4681
    After unbinding, the local branch is considered independent and subsequent
4696
4682
    commits will be local only.
4698
4684
 
4699
4685
    _see_also = ['checkouts', 'bind']
4700
4686
    takes_args = []
4701
 
    takes_options = ['directory']
 
4687
    takes_options = []
4702
4688
 
4703
 
    def run(self, directory=u'.'):
4704
 
        b, relpath = Branch.open_containing(directory)
 
4689
    def run(self):
 
4690
        b, relpath = Branch.open_containing(u'.')
4705
4691
        if not b.unbind():
4706
4692
            raise errors.BzrCommandError('Local branch is not bound')
4707
4693
 
4708
4694
 
4709
4695
class cmd_uncommit(Command):
4710
 
    __doc__ = """Remove the last committed revision.
 
4696
    """Remove the last committed revision.
4711
4697
 
4712
4698
    --verbose will print out what is being removed.
4713
4699
    --dry-run will go through all the motions, but not actually
4753
4739
            b = control.open_branch()
4754
4740
 
4755
4741
        if tree is not None:
4756
 
            self.add_cleanup(tree.lock_write().unlock)
 
4742
            tree.lock_write()
 
4743
            self.add_cleanup(tree.unlock)
4757
4744
        else:
4758
 
            self.add_cleanup(b.lock_write().unlock)
 
4745
            b.lock_write()
 
4746
            self.add_cleanup(b.unlock)
4759
4747
        return self._run(b, tree, dry_run, verbose, revision, force, local=local)
4760
4748
 
4761
4749
    def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
4813
4801
 
4814
4802
 
4815
4803
class cmd_break_lock(Command):
4816
 
    __doc__ = """Break a dead lock on a repository, branch or working directory.
 
4804
    """Break a dead lock on a repository, branch or working directory.
4817
4805
 
4818
4806
    CAUTION: Locks should only be broken when you are sure that the process
4819
4807
    holding the lock has been stopped.
4838
4826
 
4839
4827
 
4840
4828
class cmd_wait_until_signalled(Command):
4841
 
    __doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
 
4829
    """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4842
4830
 
4843
4831
    This just prints a line to signal when it is ready, then blocks on stdin.
4844
4832
    """
4852
4840
 
4853
4841
 
4854
4842
class cmd_serve(Command):
4855
 
    __doc__ = """Run the bzr server."""
 
4843
    """Run the bzr server."""
4856
4844
 
4857
4845
    aliases = ['server']
4858
4846
 
4869
4857
                    'result in a dynamically allocated port.  The default port '
4870
4858
                    'depends on the protocol.',
4871
4859
               type=str),
4872
 
        custom_help('directory',
4873
 
               help='Serve contents of this directory.'),
 
4860
        Option('directory',
 
4861
               help='Serve contents of this directory.',
 
4862
               type=unicode),
4874
4863
        Option('allow-writes',
4875
4864
               help='By default the server is a readonly server.  Supplying '
4876
4865
                    '--allow-writes enables write access to the contents of '
4917
4906
 
4918
4907
 
4919
4908
class cmd_join(Command):
4920
 
    __doc__ = """Combine a tree into its containing tree.
 
4909
    """Combine a tree into its containing tree.
4921
4910
 
4922
4911
    This command requires the target tree to be in a rich-root format.
4923
4912
 
4963
4952
 
4964
4953
 
4965
4954
class cmd_split(Command):
4966
 
    __doc__ = """Split a subdirectory of a tree into a separate tree.
 
4955
    """Split a subdirectory of a tree into a separate tree.
4967
4956
 
4968
4957
    This command will produce a target tree in a format that supports
4969
4958
    rich roots, like 'rich-root' or 'rich-root-pack'.  These formats cannot be
4989
4978
 
4990
4979
 
4991
4980
class cmd_merge_directive(Command):
4992
 
    __doc__ = """Generate a merge directive for auto-merge tools.
 
4981
    """Generate a merge directive for auto-merge tools.
4993
4982
 
4994
4983
    A directive requests a merge to be performed, and also provides all the
4995
4984
    information necessary to do so.  This means it must either include a
5088
5077
 
5089
5078
 
5090
5079
class cmd_send(Command):
5091
 
    __doc__ = """Mail or create a merge-directive for submitting changes.
 
5080
    """Mail or create a merge-directive for submitting changes.
5092
5081
 
5093
5082
    A merge directive provides many things needed for requesting merges:
5094
5083
 
5128
5117
    given, in which case it is sent to a file.
5129
5118
 
5130
5119
    Mail is sent using your preferred mail program.  This should be transparent
5131
 
    on Windows (it uses MAPI).  On Unix, it requires the xdg-email utility.
 
5120
    on Windows (it uses MAPI).  On Linux, it requires the xdg-email utility.
5132
5121
    If the preferred client can't be found (or used), your editor will be used.
5133
5122
 
5134
5123
    To use a specific mail program, set the mail_client configuration option.
5205
5194
 
5206
5195
 
5207
5196
class cmd_bundle_revisions(cmd_send):
5208
 
    __doc__ = """Create a merge-directive for submitting changes.
 
5197
    """Create a merge-directive for submitting changes.
5209
5198
 
5210
5199
    A merge directive provides many things needed for requesting merges:
5211
5200
 
5278
5267
 
5279
5268
 
5280
5269
class cmd_tag(Command):
5281
 
    __doc__ = """Create, remove or modify a tag naming a revision.
 
5270
    """Create, remove or modify a tag naming a revision.
5282
5271
 
5283
5272
    Tags give human-meaningful names to revisions.  Commands that take a -r
5284
5273
    (--revision) option can be given -rtag:X, where X is any previously
5305
5294
        Option('delete',
5306
5295
            help='Delete this tag rather than placing it.',
5307
5296
            ),
5308
 
        custom_help('directory',
5309
 
            help='Branch in which to place the tag.'),
 
5297
        Option('directory',
 
5298
            help='Branch in which to place the tag.',
 
5299
            short_name='d',
 
5300
            type=unicode,
 
5301
            ),
5310
5302
        Option('force',
5311
5303
            help='Replace existing tags.',
5312
5304
            ),
5320
5312
            revision=None,
5321
5313
            ):
5322
5314
        branch, relpath = Branch.open_containing(directory)
5323
 
        self.add_cleanup(branch.lock_write().unlock)
 
5315
        branch.lock_write()
 
5316
        self.add_cleanup(branch.unlock)
5324
5317
        if delete:
5325
5318
            if tag_name is None:
5326
5319
                raise errors.BzrCommandError("No tag specified to delete.")
5347
5340
 
5348
5341
 
5349
5342
class cmd_tags(Command):
5350
 
    __doc__ = """List tags.
 
5343
    """List tags.
5351
5344
 
5352
5345
    This command shows a table of tag names and the revisions they reference.
5353
5346
    """
5354
5347
 
5355
5348
    _see_also = ['tag']
5356
5349
    takes_options = [
5357
 
        custom_help('directory',
5358
 
            help='Branch whose tags should be displayed.'),
 
5350
        Option('directory',
 
5351
            help='Branch whose tags should be displayed.',
 
5352
            short_name='d',
 
5353
            type=unicode,
 
5354
            ),
5359
5355
        RegistryOption.from_kwargs('sort',
5360
5356
            'Sort tags by different criteria.', title='Sorting',
5361
5357
            alpha='Sort tags lexicographically (default).',
5378
5374
        if not tags:
5379
5375
            return
5380
5376
 
5381
 
        self.add_cleanup(branch.lock_read().unlock)
 
5377
        branch.lock_read()
 
5378
        self.add_cleanup(branch.unlock)
5382
5379
        if revision:
5383
5380
            graph = branch.repository.get_graph()
5384
5381
            rev1, rev2 = _get_revision_range(revision, branch, self.name())
5417
5414
 
5418
5415
 
5419
5416
class cmd_reconfigure(Command):
5420
 
    __doc__ = """Reconfigure the type of a bzr directory.
 
5417
    """Reconfigure the type of a bzr directory.
5421
5418
 
5422
5419
    A target configuration must be specified.
5423
5420
 
5508
5505
 
5509
5506
 
5510
5507
class cmd_switch(Command):
5511
 
    __doc__ = """Set the branch of a checkout and update.
 
5508
    """Set the branch of a checkout and update.
5512
5509
 
5513
5510
    For lightweight checkouts, this changes the branch being referenced.
5514
5511
    For heavyweight checkouts, this checks that there are no local commits
5604
5601
 
5605
5602
 
5606
5603
class cmd_view(Command):
5607
 
    __doc__ = """Manage filtered views.
 
5604
    """Manage filtered views.
5608
5605
 
5609
5606
    Views provide a mask over the tree so that users can focus on
5610
5607
    a subset of a tree when doing their work. After creating a view,
5758
5755
 
5759
5756
 
5760
5757
class cmd_hooks(Command):
5761
 
    __doc__ = """Show hooks."""
 
5758
    """Show hooks."""
5762
5759
 
5763
5760
    hidden = True
5764
5761
 
5778
5775
 
5779
5776
 
5780
5777
class cmd_remove_branch(Command):
5781
 
    __doc__ = """Remove a branch.
 
5778
    """Remove a branch.
5782
5779
 
5783
5780
    This will remove the branch from the specified location but 
5784
5781
    will keep any working tree or repository in place.
5803
5800
        
5804
5801
 
5805
5802
class cmd_shelve(Command):
5806
 
    __doc__ = """Temporarily set aside some changes from the current tree.
 
5803
    """Temporarily set aside some changes from the current tree.
5807
5804
 
5808
5805
    Shelve allows you to temporarily put changes you've made "on the shelf",
5809
5806
    ie. out of the way, until a later time when you can bring them back from
5862
5859
 
5863
5860
    def run_for_list(self):
5864
5861
        tree = WorkingTree.open_containing('.')[0]
5865
 
        self.add_cleanup(tree.lock_read().unlock)
 
5862
        tree.lock_read()
 
5863
        self.add_cleanup(tree.unlock)
5866
5864
        manager = tree.get_shelf_manager()
5867
5865
        shelves = manager.active_shelves()
5868
5866
        if len(shelves) == 0:
5877
5875
 
5878
5876
 
5879
5877
class cmd_unshelve(Command):
5880
 
    __doc__ = """Restore shelved changes.
 
5878
    """Restore shelved changes.
5881
5879
 
5882
5880
    By default, the most recently shelved changes are restored. However if you
5883
5881
    specify a shelf by id those changes will be restored instead.  This works
5909
5907
 
5910
5908
 
5911
5909
class cmd_clean_tree(Command):
5912
 
    __doc__ = """Remove unwanted files from working tree.
 
5910
    """Remove unwanted files from working tree.
5913
5911
 
5914
5912
    By default, only unknown files, not ignored files, are deleted.  Versioned
5915
5913
    files are never deleted.
5923
5921
 
5924
5922
    To check what clean-tree will do, use --dry-run.
5925
5923
    """
5926
 
    takes_options = ['directory',
5927
 
                     Option('ignored', help='Delete all ignored files.'),
 
5924
    takes_options = [Option('ignored', help='Delete all ignored files.'),
5928
5925
                     Option('detritus', help='Delete conflict files, merge'
5929
5926
                            ' backups, and failed selftest dirs.'),
5930
5927
                     Option('unknown',
5933
5930
                            ' deleting them.'),
5934
5931
                     Option('force', help='Do not prompt before deleting.')]
5935
5932
    def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5936
 
            force=False, directory=u'.'):
 
5933
            force=False):
5937
5934
        from bzrlib.clean_tree import clean_tree
5938
5935
        if not (unknown or ignored or detritus):
5939
5936
            unknown = True
5940
5937
        if dry_run:
5941
5938
            force = True
5942
 
        clean_tree(directory, unknown=unknown, ignored=ignored,
5943
 
                   detritus=detritus, dry_run=dry_run, no_prompt=force)
 
5939
        clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
 
5940
                   dry_run=dry_run, no_prompt=force)
5944
5941
 
5945
5942
 
5946
5943
class cmd_reference(Command):
5947
 
    __doc__ = """list, view and set branch locations for nested trees.
 
5944
    """list, view and set branch locations for nested trees.
5948
5945
 
5949
5946
    If no arguments are provided, lists the branch locations for nested trees.
5950
5947
    If one argument is provided, display the branch location for that tree.