~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Robert Collins
  • Date: 2005-11-22 21:28:30 UTC
  • mfrom: (1185.33.32 bzr.dev)
  • Revision ID: robertc@robertcollins.net-20051122212830-885c284847f0b17b
Merge from mpool.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
from bzrlib import BZRDIR
27
27
from bzrlib.commands import Command, display_command
28
28
from bzrlib.branch import Branch
29
 
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
30
 
from bzrlib.errors import DivergedBranches, NoSuchFile, NoWorkingTree
 
29
from bzrlib.revision import common_ancestor
 
30
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError, 
 
31
                           NotBranchError, DivergedBranches, NotConflicted,
 
32
                           NoSuchFile, NoWorkingTree, FileInWrongBranch)
31
33
from bzrlib.option import Option
32
34
from bzrlib.revisionspec import RevisionSpec
33
35
import bzrlib.trace
36
38
 
37
39
 
38
40
def branch_files(file_list, default_branch='.'):
 
41
    try:
 
42
        return inner_branch_files(file_list, default_branch)
 
43
    except FileInWrongBranch, e:
 
44
        print file_list
 
45
        raise BzrCommandError("%s is not in the same branch as %s" %
 
46
                             (e.path, file_list[0]))
 
47
 
 
48
def inner_branch_files(file_list, default_branch='.'):
39
49
    """\
40
50
    Return a branch and list of branch-relative paths.
41
51
    If supplied file_list is empty or None, the branch default will be used,
55
65
        try:
56
66
            new_list.append(tree.relpath(filename))
57
67
        except NotBranchError:
58
 
            raise BzrCommandError("%s is not in the same branch as %s" % 
59
 
                                  (filename, file_list[0]))
 
68
            raise FileInWrongBranch(b, filename)
60
69
    return b, new_list
61
70
 
62
71
 
106
115
    that revision, or between two revisions if two are provided.
107
116
    """
108
117
    
109
 
    # XXX: FIXME: bzr status should accept a -r option to show changes
110
 
    # relative to a revision, or between revisions
111
 
 
112
118
    # TODO: --no-recurse, --recurse options
113
119
    
114
120
    takes_args = ['file*']
115
 
    takes_options = ['all', 'show-ids']
 
121
    takes_options = ['all', 'show-ids', 'revision']
116
122
    aliases = ['st', 'stat']
117
123
    
118
124
    @display_command
621
627
    @display_command
622
628
    def run(self, filename):
623
629
        b, relpath = Branch.open_containing(filename)
624
 
        i = b.inventory.path2id(relpath)
 
630
        i = b.working_tree().inventory.path2id(relpath)
625
631
        if i == None:
626
632
            raise BzrError("%r is not a versioned file" % filename)
627
633
        else:
738
744
    @display_command
739
745
    def run(self, revision=None, file_list=None, diff_options=None):
740
746
        from bzrlib.diff import show_diff
741
 
        
742
 
        b, file_list = branch_files(file_list)
 
747
        try:
 
748
            b, file_list = inner_branch_files(file_list)
 
749
            b2 = None
 
750
        except FileInWrongBranch:
 
751
            if len(file_list) != 2:
 
752
                raise BzrCommandError("Files are in different branches")
 
753
 
 
754
            b, file1 = Branch.open_containing(file_list[0])
 
755
            b2, file2 = Branch.open_containing(file_list[1])
 
756
            if file1 != "" or file2 != "":
 
757
                raise BzrCommandError("Files are in different branches")
 
758
            file_list = None
743
759
        if revision is not None:
 
760
            if b2 is not None:
 
761
                raise BzrCommandError("Can't specify -r with two branches")
744
762
            if len(revision) == 1:
745
763
                return show_diff(b, revision[0], specific_files=file_list,
746
764
                                 external_diff_options=diff_options)
752
770
                raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
753
771
        else:
754
772
            return show_diff(b, None, specific_files=file_list,
755
 
                             external_diff_options=diff_options)
 
773
                             external_diff_options=diff_options, b2=b2)
756
774
 
757
775
 
758
776
class cmd_deleted(Command):
887
905
        else:
888
906
            raise BzrCommandError('bzr log --revision takes one or two values.')
889
907
 
890
 
        if rev1 == 0:
891
 
            rev1 = None
892
 
        if rev2 == 0:
893
 
            rev2 = None
 
908
        # By this point, the revision numbers are converted to the +ve
 
909
        # form if they were supplied in the -ve form, so we can do
 
910
        # this comparison in relative safety
 
911
        if rev1 > rev2:
 
912
            (rev2, rev1) = (rev1, rev2)
894
913
 
895
914
        mutter('encoding log as %r', bzrlib.user_encoding)
896
915
 
1309
1328
        else:
1310
1329
            print config.username()
1311
1330
 
 
1331
class cmd_nick(Command):
 
1332
    """\
 
1333
    Print or set the branch nickname.  
 
1334
    If unset, the tree root directory name is used as the nickname
 
1335
    To print the current nickname, execute with no argument.  
 
1336
    """
 
1337
    takes_args = ['nickname?']
 
1338
    def run(self, nickname=None):
 
1339
        branch = Branch.open_containing('.')[0]
 
1340
        if nickname is None:
 
1341
            self.printme(branch)
 
1342
        else:
 
1343
            branch.nick = nickname
 
1344
 
 
1345
    @display_command
 
1346
    def printme(self, branch):
 
1347
        print branch.nick 
1312
1348
 
1313
1349
class cmd_selftest(Command):
1314
1350
    """Run internal test suite.
1316
1352
    This creates temporary test directories in the working directory,
1317
1353
    but not existing data is affected.  These directories are deleted
1318
1354
    if the tests pass, or left behind to help in debugging if they
1319
 
    fail.
 
1355
    fail and --keep-output is specified.
1320
1356
    
1321
1357
    If arguments are given, they are regular expressions that say
1322
1358
    which tests should run.
1326
1362
    takes_args = ['testspecs*']
1327
1363
    takes_options = ['verbose', 
1328
1364
                     Option('one', help='stop when one test fails'),
 
1365
                     Option('keep-output', 
 
1366
                            help='keep output directories when tests fail')
1329
1367
                    ]
1330
1368
 
1331
 
    def run(self, testspecs_list=None, verbose=False, one=False):
 
1369
    def run(self, testspecs_list=None, verbose=False, one=False,
 
1370
            keep_output=False):
1332
1371
        import bzrlib.ui
1333
1372
        from bzrlib.selftest import selftest
1334
1373
        # we don't want progress meters from the tests to go to the
1344
1383
                pattern = ".*"
1345
1384
            result = selftest(verbose=verbose, 
1346
1385
                              pattern=pattern,
1347
 
                              stop_on_failure=one)
 
1386
                              stop_on_failure=one, 
 
1387
                              keep_output=keep_output)
1348
1388
            if result:
1349
1389
                bzrlib.trace.info('tests passed')
1350
1390
            else:
1503
1543
            log_error(m)
1504
1544
 
1505
1545
 
 
1546
class cmd_remerge(Command):
 
1547
    """Redo a merge.
 
1548
    """
 
1549
    takes_args = ['file*']
 
1550
    takes_options = ['merge-type', 'reprocess',
 
1551
                     Option('show-base', help="Show base revision text in "
 
1552
                            "conflicts")]
 
1553
 
 
1554
    def run(self, file_list=None, merge_type=None, show_base=False,
 
1555
            reprocess=False):
 
1556
        from bzrlib.merge import merge_inner, transform_tree
 
1557
        from bzrlib.merge_core import ApplyMerge3
 
1558
        if merge_type is None:
 
1559
            merge_type = ApplyMerge3
 
1560
        b, file_list = branch_files(file_list)
 
1561
        b.lock_write()
 
1562
        try:
 
1563
            pending_merges = b.working_tree().pending_merges() 
 
1564
            if len(pending_merges) != 1:
 
1565
                raise BzrCommandError("Sorry, remerge only works after normal"
 
1566
                                      + " merges.  Not cherrypicking or"
 
1567
                                      + "multi-merges.")
 
1568
            this_tree = b.working_tree()
 
1569
            base_revision = common_ancestor(b.last_revision(), 
 
1570
                                            pending_merges[0], b)
 
1571
            base_tree = b.revision_tree(base_revision)
 
1572
            other_tree = b.revision_tree(pending_merges[0])
 
1573
            interesting_ids = None
 
1574
            if file_list is not None:
 
1575
                interesting_ids = set()
 
1576
                for filename in file_list:
 
1577
                    file_id = this_tree.path2id(filename)
 
1578
                    interesting_ids.add(file_id)
 
1579
                    if this_tree.kind(file_id) != "directory":
 
1580
                        continue
 
1581
                    
 
1582
                    for name, ie in this_tree.inventory.iter_entries(file_id):
 
1583
                        interesting_ids.add(ie.file_id)
 
1584
            transform_tree(this_tree, b.basis_tree(), interesting_ids)
 
1585
            if file_list is None:
 
1586
                restore_files = list(this_tree.iter_conflicts())
 
1587
            else:
 
1588
                restore_files = file_list
 
1589
            for filename in restore_files:
 
1590
                try:
 
1591
                    restore(this_tree.abspath(filename))
 
1592
                except NotConflicted:
 
1593
                    pass
 
1594
            conflicts =  merge_inner(b, other_tree, base_tree, 
 
1595
                                     interesting_ids = interesting_ids, 
 
1596
                                     other_rev_id=pending_merges[0], 
 
1597
                                     merge_type=merge_type, 
 
1598
                                     show_base=show_base,
 
1599
                                     reprocess=reprocess)
 
1600
        finally:
 
1601
            b.unlock()
 
1602
        if conflicts > 0:
 
1603
            return 1
 
1604
        else:
 
1605
            return 0
 
1606
 
1506
1607
class cmd_revert(Command):
1507
1608
    """Reverse all changes since the last commit.
1508
1609
 
1751
1852
# TODO: Some more consistent way to split command definitions across files;
1752
1853
# we do need to load at least some information about them to know of 
1753
1854
# aliases.
1754
 
from bzrlib.conflicts import cmd_resolve, cmd_conflicts
 
1855
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore