/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/commands.py

  • Committer: Martin Pool
  • Date: 2005-08-29 01:25:00 UTC
  • Revision ID: mbp@sourcefrog.net-20050829012500-36f2d20363be4a53
* move bzr-specific code from testsweet into bzrlib.selftest

* logging from within test suites is now done using python logging, so
  the regular .bzr.log is not cluttered and the results can be easily
  seen if the test fails

* don't capture stdout/stderr while running tests, instead let it leak
  through so that we can see places where the library is doing its own
  output and should be fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
# TODO: probably should say which arguments are candidates for glob
21
21
# expansion on windows and do that at the command level.
22
22
 
 
23
# TODO: Help messages for options.
 
24
 
 
25
# TODO: Define arguments by objects, rather than just using names.
 
26
# Those objects can specify the expected type of the argument, which
 
27
# would help with validation and shell completion.
 
28
 
 
29
 
23
30
import sys
24
31
import os
25
32
 
26
33
import bzrlib
 
34
import bzrlib.trace
27
35
from bzrlib.trace import mutter, note, log_error, warning
28
36
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
29
37
from bzrlib.branch import find_branch
141
149
        raise BzrCommandError(msg)
142
150
    
143
151
 
 
152
def get_merge_type(typestring):
 
153
    """Attempt to find the merge class/factory associated with a string."""
 
154
    from merge import merge_types
 
155
    try:
 
156
        return merge_types[typestring][0]
 
157
    except KeyError:
 
158
        templ = '%s%%7s: %%s' % (' '*12)
 
159
        lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
 
160
        type_list = '\n'.join(lines)
 
161
        msg = "No known merge type %s. Supported types are:\n%s" %\
 
162
            (typestring, type_list)
 
163
        raise BzrCommandError(msg)
 
164
    
 
165
 
144
166
 
145
167
def _get_cmd_dict(plugins_override=True):
146
168
    d = {}
696
718
                    msg = "The branch %s has no revision %d." % (from_location,
697
719
                                                                 revno)
698
720
                    raise BzrCommandError(msg)
699
 
            
 
721
 
700
722
            merge((to_location, -1), (to_location, 0), this_dir=to_location,
701
723
                  check_clean=False, ignore_zero=True)
702
724
            from_location = pull_loc(br_from)
837
859
    If files are listed, only the changes in those files are listed.
838
860
    Otherwise, all changes for the tree are listed.
839
861
 
840
 
    TODO: Given two revision arguments, show the difference between them.
841
 
 
842
862
    TODO: Allow diff across branches.
843
863
 
844
864
    TODO: Option to use external diff command; could be GNU diff, wdiff,
853
873
          deleted files.
854
874
 
855
875
    TODO: This probably handles non-Unix newlines poorly.
 
876
 
 
877
    examples:
 
878
        bzr diff
 
879
        bzr diff -r1
 
880
        bzr diff -r1:2
856
881
    """
857
882
    
858
883
    takes_args = ['file*']
871
896
        else:
872
897
            b = find_branch('.')
873
898
 
874
 
        # TODO: Make show_diff support taking 2 arguments
875
 
        base_rev = None
876
899
        if revision is not None:
877
 
            if len(revision) != 1:
878
 
                raise BzrCommandError('bzr diff --revision takes exactly one revision identifier')
879
 
            base_rev = revision[0]
880
 
    
881
 
        show_diff(b, base_rev, specific_files=file_list,
882
 
                  external_diff_options=diff_options)
883
 
 
 
900
            if len(revision) == 1:
 
901
                show_diff(b, revision[0], specific_files=file_list,
 
902
                          external_diff_options=diff_options)
 
903
            elif len(revision) == 2:
 
904
                show_diff(b, revision[0], specific_files=file_list,
 
905
                          external_diff_options=diff_options,
 
906
                          revision2=revision[1])
 
907
            else:
 
908
                raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
 
909
        else:
 
910
            show_diff(b, None, specific_files=file_list,
 
911
                      external_diff_options=diff_options)
884
912
 
885
913
        
886
914
 
967
995
    """
968
996
 
969
997
    takes_args = ['filename?']
970
 
    takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision','long', 'message']
 
998
    takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision',
 
999
                     'long', 'message', 'short',]
971
1000
    
972
1001
    def run(self, filename=None, timezone='original',
973
1002
            verbose=False,
975
1004
            forward=False,
976
1005
            revision=None,
977
1006
            message=None,
978
 
            long=False):
 
1007
            long=False,
 
1008
            short=False):
979
1009
        from bzrlib.branch import find_branch
980
1010
        from bzrlib.log import log_formatter, show_log
981
1011
        import codecs
1015
1045
        # in e.g. the default C locale.
1016
1046
        outf = codecs.getwriter(bzrlib.user_encoding)(sys.stdout, errors='replace')
1017
1047
 
1018
 
        if long:
 
1048
        if not short:
1019
1049
            log_format = 'long'
1020
1050
        else:
1021
1051
            log_format = 'short'
1315
1345
 
1316
1346
    def run(self, dir='.'):
1317
1347
        from bzrlib.check import check
 
1348
 
1318
1349
        check(find_branch(dir))
1319
1350
 
1320
1351
 
1321
 
 
1322
1352
class cmd_scan_cache(Command):
1323
1353
    hidden = True
1324
1354
    def run(self):
1359
1389
    takes_options = ['email']
1360
1390
    
1361
1391
    def run(self, email=False):
 
1392
        try:
 
1393
            b = bzrlib.branch.find_branch('.')
 
1394
        except:
 
1395
            b = None
 
1396
        
1362
1397
        if email:
1363
 
            print bzrlib.osutils.user_email()
 
1398
            print bzrlib.osutils.user_email(b)
1364
1399
        else:
1365
 
            print bzrlib.osutils.username()
 
1400
            print bzrlib.osutils.username(b)
1366
1401
 
1367
1402
 
1368
1403
class cmd_selftest(Command):
1370
1405
    hidden = True
1371
1406
    takes_options = ['verbose']
1372
1407
    def run(self, verbose=False):
 
1408
        import bzrlib.ui
1373
1409
        from bzrlib.selftest import selftest
1374
 
        return int(not selftest(verbose=verbose))
 
1410
 
 
1411
        # we don't want progress meters from the tests to go to the
 
1412
        # real output; and we don't want log messages cluttering up
 
1413
        # the real logs.
 
1414
 
 
1415
        save_ui = bzrlib.ui.ui_factory
 
1416
        bzrlib.trace.info('running tests...')
 
1417
        try:
 
1418
            bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
 
1419
            result = selftest(verbose=verbose)
 
1420
            if result:
 
1421
                bzrlib.trace.info('tests passed')
 
1422
            else:
 
1423
                bzrlib.trace.info('tests failed')
 
1424
            return int(not result)
 
1425
        finally:
 
1426
            bzrlib.ui.ui_factory = save_ui
1375
1427
 
1376
1428
 
1377
1429
class cmd_version(Command):
1432
1484
 
1433
1485
 
1434
1486
 
 
1487
class cmd_find_merge_base(Command):
 
1488
    """Find and print a base revision for merging two branches.
 
1489
 
 
1490
    TODO: Options to specify revisions on either side, as if
 
1491
          merging only part of the history.
 
1492
    """
 
1493
    takes_args = ['branch', 'other']
 
1494
    hidden = True
 
1495
    
 
1496
    def run(self, branch, other):
 
1497
        branch1 = find_branch(branch)
 
1498
        branch2 = find_branch(other)
 
1499
 
 
1500
        base_revno, base_revid = branch1.common_ancestor(branch2)
 
1501
 
 
1502
        if base_revno is None:
 
1503
            raise bzrlib.errors.UnrelatedBranches()
 
1504
 
 
1505
        print 'merge base is revision %s' % base_revid
 
1506
        print ' r%-6d in %s' % (base_revno, branch)
 
1507
 
 
1508
        other_revno = branch2.revision_id_to_revno(base_revid)
 
1509
        
 
1510
        print ' r%-6d in %s' % (other_revno, other)
 
1511
 
 
1512
 
 
1513
 
1435
1514
class cmd_merge(Command):
1436
 
    """Perform a three-way merge of trees.
1437
 
    
1438
 
    The SPEC parameters are working tree or revision specifiers.  Working trees
1439
 
    are specified using standard paths or urls.  No component of a directory
1440
 
    path may begin with '@'.
1441
 
    
1442
 
    Working tree examples: '.', '..', 'foo@', but NOT 'foo/@bar'
1443
 
 
1444
 
    Revisions are specified using a dirname/@revno pair, where dirname is the
1445
 
    branch directory and revno is the revision within that branch.  If no revno
1446
 
    is specified, the latest revision is used.
1447
 
 
1448
 
    Revision examples: './@127', 'foo/@', '../@1'
1449
 
 
1450
 
    The OTHER_SPEC parameter is required.  If the BASE_SPEC parameter is
1451
 
    not supplied, the common ancestor of OTHER_SPEC the current branch is used
1452
 
    as the BASE.
1453
 
 
 
1515
    """Perform a three-way merge.
 
1516
    
 
1517
    The branch is the branch you will merge from.  By default, it will merge
 
1518
    the latest revision.  If you specify a revision, that revision will be
 
1519
    merged.  If you specify two revisions, the first will be used as a BASE, 
 
1520
    and the second one as OTHER.  Revision numbers are always relative to the
 
1521
    specified branch.
 
1522
    
 
1523
    Examples:
 
1524
 
 
1525
    To merge the latest revision from bzr.dev
 
1526
    bzr merge ../bzr.dev
 
1527
 
 
1528
    To merge changes up to and including revision 82 from bzr.dev
 
1529
    bzr merge -r 82 ../bzr.dev
 
1530
 
 
1531
    To merge the changes introduced by 82, without previous changes:
 
1532
    bzr merge -r 81..82 ../bzr.dev
 
1533
    
1454
1534
    merge refuses to run if there are any uncommitted changes, unless
1455
1535
    --force is given.
1456
1536
    """
1457
 
    takes_args = ['other_spec', 'base_spec?']
1458
 
    takes_options = ['force', 'merge-type']
 
1537
    takes_args = ['branch?']
 
1538
    takes_options = ['revision', 'force', 'merge-type']
1459
1539
 
1460
 
    def run(self, other_spec, base_spec=None, force=False, merge_type=None):
 
1540
    def run(self, branch='.', revision=None, force=False, 
 
1541
            merge_type=None):
1461
1542
        from bzrlib.merge import merge
1462
1543
        from bzrlib.merge_core import ApplyMerge3
1463
1544
        if merge_type is None:
1464
1545
            merge_type = ApplyMerge3
1465
 
        merge(parse_spec(other_spec), parse_spec(base_spec),
1466
 
              check_clean=(not force), merge_type=merge_type)
 
1546
 
 
1547
        if revision is None or len(revision) < 1:
 
1548
            base = (None, None)
 
1549
            other = (branch, -1)
 
1550
        else:
 
1551
            if len(revision) == 1:
 
1552
                other = (branch, revision[0])
 
1553
                base = (None, None)
 
1554
            else:
 
1555
                assert len(revision) == 2
 
1556
                if None in revision:
 
1557
                    raise BzrCommandError(
 
1558
                        "Merge doesn't permit that revision specifier.")
 
1559
                base = (branch, revision[0])
 
1560
                other = (branch, revision[1])
 
1561
            
 
1562
        merge(other, base, check_clean=(not force), merge_type=merge_type)
1467
1563
 
1468
1564
 
1469
1565
class cmd_revert(Command):
1504
1600
    """Show help on a command or other topic.
1505
1601
 
1506
1602
    For a list of all available commands, say 'bzr help commands'."""
 
1603
    takes_options = ['long']
1507
1604
    takes_args = ['topic?']
1508
1605
    aliases = ['?']
1509
1606
    
1510
 
    def run(self, topic=None):
 
1607
    def run(self, topic=None, long=False):
1511
1608
        import help
 
1609
        if topic is None and long:
 
1610
            topic = "commands"
1512
1611
        help.help(topic)
1513
1612
 
1514
1613
 
 
1614
class cmd_shell_complete(Command):
 
1615
    """Show appropriate completions for context.
 
1616
 
 
1617
    For a list of all available commands, say 'bzr shell-complete'."""
 
1618
    takes_args = ['context?']
 
1619
    aliases = ['s-c']
 
1620
    hidden = True
 
1621
    
 
1622
    def run(self, context=None):
 
1623
        import shellcomplete
 
1624
        shellcomplete.shellcomplete(context)
 
1625
 
 
1626
 
 
1627
class cmd_missing(Command):
 
1628
    """What is missing in this branch relative to other branch.
 
1629
    """
 
1630
    takes_args = ['remote?']
 
1631
    aliases = ['mis', 'miss']
 
1632
    # We don't have to add quiet to the list, because 
 
1633
    # unknown options are parsed as booleans
 
1634
    takes_options = ['verbose', 'quiet']
 
1635
 
 
1636
    def run(self, remote=None, verbose=False, quiet=False):
 
1637
        from bzrlib.branch import find_branch, DivergedBranches
 
1638
        from bzrlib.errors import BzrCommandError
 
1639
        from bzrlib.missing import get_parent, show_missing
 
1640
 
 
1641
        if verbose and quiet:
 
1642
            raise BzrCommandError('Cannot pass both quiet and verbose')
 
1643
 
 
1644
        b = find_branch('.')
 
1645
        parent = get_parent(b)
 
1646
        if remote is None:
 
1647
            if parent is None:
 
1648
                raise BzrCommandError("No missing location known or specified.")
 
1649
            else:
 
1650
                if not quiet:
 
1651
                    print "Using last location: %s" % parent
 
1652
                remote = parent
 
1653
        elif parent is None:
 
1654
            # We only update x-pull if it did not exist, missing should not change the parent
 
1655
            b.controlfile('x-pull', 'wb').write(remote + '\n')
 
1656
        br_remote = find_branch(remote)
 
1657
 
 
1658
        return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
 
1659
 
1515
1660
 
1516
1661
 
1517
1662
class cmd_plugins(Command):
1546
1691
    'no-recurse':             None,
1547
1692
    'profile':                None,
1548
1693
    'revision':               _parse_revision_str,
 
1694
    'short':                  None,
1549
1695
    'show-ids':               None,
1550
1696
    'timezone':               str,
1551
1697
    'verbose':                None,
1776
1922
        return 0
1777
1923
    
1778
1924
    if not args:
1779
 
        print >>sys.stderr, "please try 'bzr help' for help"
1780
 
        return 1
 
1925
        from bzrlib.help import help
 
1926
        help(None)
 
1927
        return 0
1781
1928
    
1782
1929
    cmd = str(args.pop(0))
1783
1930
 
1822
1969
        return cmd_class(cmdopts, cmdargs).status 
1823
1970
 
1824
1971
 
1825
 
def _report_exception(summary, quiet=False):
1826
 
    import traceback
1827
 
    
1828
 
    log_error('bzr: ' + summary)
1829
 
    bzrlib.trace.log_exception()
1830
 
 
1831
 
    if os.environ.get('BZR_DEBUG'):
1832
 
        traceback.print_exc()
1833
 
 
1834
 
    if not quiet:
1835
 
        sys.stderr.write('\n')
1836
 
        tb = sys.exc_info()[2]
1837
 
        exinfo = traceback.extract_tb(tb)
1838
 
        if exinfo:
1839
 
            sys.stderr.write('  at %s:%d in %s()\n' % exinfo[-1][:3])
1840
 
        sys.stderr.write('  see ~/.bzr.log for debug information\n')
1841
 
 
1842
 
 
1843
 
 
1844
1972
def main(argv):
 
1973
    import bzrlib.ui
1845
1974
    
1846
 
    bzrlib.trace.open_tracefile(argv)
 
1975
    bzrlib.trace.log_startup(argv)
 
1976
 
 
1977
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
1847
1978
 
1848
1979
    try:
1849
1980
        try:
1850
 
            try:
1851
 
                return run_bzr(argv[1:])
1852
 
            finally:
1853
 
                # do this here inside the exception wrappers to catch EPIPE
1854
 
                sys.stdout.flush()
1855
 
        except BzrError, e:
1856
 
            quiet = isinstance(e, (BzrCommandError))
1857
 
            _report_exception('error: ' + str(e), quiet=quiet)
1858
 
            if len(e.args) > 1:
1859
 
                for h in e.args[1]:
1860
 
                    # some explanation or hints
1861
 
                    log_error('  ' + h)
1862
 
            return 1
1863
 
        except AssertionError, e:
1864
 
            msg = 'assertion failed'
1865
 
            if str(e):
1866
 
                msg += ': ' + str(e)
1867
 
            _report_exception(msg)
1868
 
            return 2
1869
 
        except KeyboardInterrupt, e:
1870
 
            _report_exception('interrupted', quiet=True)
1871
 
            return 2
1872
 
        except Exception, e:
1873
 
            import errno
1874
 
            quiet = False
1875
 
            if (isinstance(e, IOError) 
1876
 
                and hasattr(e, 'errno')
1877
 
                and e.errno == errno.EPIPE):
1878
 
                quiet = True
1879
 
                msg = 'broken pipe'
1880
 
            else:
1881
 
                msg = str(e).rstrip('\n')
1882
 
            _report_exception(msg, quiet)
1883
 
            return 2
1884
 
    finally:
1885
 
        bzrlib.trace.close_trace()
 
1981
            return run_bzr(argv[1:])
 
1982
        finally:
 
1983
            # do this here inside the exception wrappers to catch EPIPE
 
1984
            sys.stdout.flush()
 
1985
    except BzrCommandError, e:
 
1986
        # command line syntax error, etc
 
1987
        log_error(str(e))
 
1988
        return 1
 
1989
    except BzrError, e:
 
1990
        bzrlib.trace.log_exception()
 
1991
        return 1
 
1992
    except AssertionError, e:
 
1993
        bzrlib.trace.log_exception('assertion failed: ' + str(e))
 
1994
        return 3
 
1995
    except KeyboardInterrupt, e:
 
1996
        bzrlib.trace.note('interrupted')
 
1997
        return 2
 
1998
    except Exception, e:
 
1999
        import errno
 
2000
        if (isinstance(e, IOError) 
 
2001
            and hasattr(e, 'errno')
 
2002
            and e.errno == errno.EPIPE):
 
2003
            bzrlib.trace.note('broken pipe')
 
2004
            return 2
 
2005
        else:
 
2006
            bzrlib.trace.log_exception()
 
2007
            return 2
1886
2008
 
1887
2009
 
1888
2010
if __name__ == '__main__':