/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 04:17:33 UTC
  • Revision ID: mbp@sourcefrog.net-20050829041732-675d3efcd9fd1875
- check command writes output through logging not direct
  to stdout

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 = {}
446
468
    
447
469
    def run(self, file_list, verbose=False, no_recurse=False):
448
470
        from bzrlib.add import smart_add
449
 
        smart_add(file_list, verbose, not no_recurse)
 
471
 
 
472
        recurse = not no_recurse
 
473
        for path, kind, file_id in smart_add(file_list, verbose, recurse):
 
474
            print 'added', path
450
475
 
451
476
 
452
477
 
464
489
            os.mkdir(d)
465
490
            if not b:
466
491
                b = find_branch(d)
467
 
            b.add([d], verbose=True)
 
492
            b.add([d])
 
493
            print 'added', d
468
494
 
469
495
 
470
496
class cmd_relpath(Command):
696
722
                    msg = "The branch %s has no revision %d." % (from_location,
697
723
                                                                 revno)
698
724
                    raise BzrCommandError(msg)
699
 
            
 
725
 
700
726
            merge((to_location, -1), (to_location, 0), this_dir=to_location,
701
727
                  check_clean=False, ignore_zero=True)
702
728
            from_location = pull_loc(br_from)
837
863
    If files are listed, only the changes in those files are listed.
838
864
    Otherwise, all changes for the tree are listed.
839
865
 
840
 
    TODO: Given two revision arguments, show the difference between them.
841
 
 
842
866
    TODO: Allow diff across branches.
843
867
 
844
868
    TODO: Option to use external diff command; could be GNU diff, wdiff,
853
877
          deleted files.
854
878
 
855
879
    TODO: This probably handles non-Unix newlines poorly.
 
880
 
 
881
    examples:
 
882
        bzr diff
 
883
        bzr diff -r1
 
884
        bzr diff -r1:2
856
885
    """
857
886
    
858
887
    takes_args = ['file*']
871
900
        else:
872
901
            b = find_branch('.')
873
902
 
874
 
        # TODO: Make show_diff support taking 2 arguments
875
 
        base_rev = None
876
903
        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
 
 
 
904
            if len(revision) == 1:
 
905
                show_diff(b, revision[0], specific_files=file_list,
 
906
                          external_diff_options=diff_options)
 
907
            elif len(revision) == 2:
 
908
                show_diff(b, revision[0], specific_files=file_list,
 
909
                          external_diff_options=diff_options,
 
910
                          revision2=revision[1])
 
911
            else:
 
912
                raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
 
913
        else:
 
914
            show_diff(b, None, specific_files=file_list,
 
915
                      external_diff_options=diff_options)
884
916
 
885
917
        
886
918
 
967
999
    """
968
1000
 
969
1001
    takes_args = ['filename?']
970
 
    takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision','long', 'message']
 
1002
    takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision',
 
1003
                     'long', 'message', 'short',]
971
1004
    
972
1005
    def run(self, filename=None, timezone='original',
973
1006
            verbose=False,
975
1008
            forward=False,
976
1009
            revision=None,
977
1010
            message=None,
978
 
            long=False):
 
1011
            long=False,
 
1012
            short=False):
979
1013
        from bzrlib.branch import find_branch
980
1014
        from bzrlib.log import log_formatter, show_log
981
1015
        import codecs
1015
1049
        # in e.g. the default C locale.
1016
1050
        outf = codecs.getwriter(bzrlib.user_encoding)(sys.stdout, errors='replace')
1017
1051
 
1018
 
        if long:
 
1052
        if not short:
1019
1053
            log_format = 'long'
1020
1054
        else:
1021
1055
            log_format = 'short'
1315
1349
 
1316
1350
    def run(self, dir='.'):
1317
1351
        from bzrlib.check import check
 
1352
 
1318
1353
        check(find_branch(dir))
1319
1354
 
1320
1355
 
1321
 
 
1322
1356
class cmd_scan_cache(Command):
1323
1357
    hidden = True
1324
1358
    def run(self):
1343
1377
class cmd_upgrade(Command):
1344
1378
    """Upgrade branch storage to current format.
1345
1379
 
1346
 
    This should normally be used only after the check command tells
1347
 
    you to run it.
 
1380
    The check command or bzr developers may sometimes advise you to run
 
1381
    this command.
1348
1382
    """
1349
1383
    takes_args = ['dir?']
1350
1384
 
1359
1393
    takes_options = ['email']
1360
1394
    
1361
1395
    def run(self, email=False):
 
1396
        try:
 
1397
            b = bzrlib.branch.find_branch('.')
 
1398
        except:
 
1399
            b = None
 
1400
        
1362
1401
        if email:
1363
 
            print bzrlib.osutils.user_email()
 
1402
            print bzrlib.osutils.user_email(b)
1364
1403
        else:
1365
 
            print bzrlib.osutils.username()
 
1404
            print bzrlib.osutils.username(b)
1366
1405
 
1367
1406
 
1368
1407
class cmd_selftest(Command):
1370
1409
    hidden = True
1371
1410
    takes_options = ['verbose']
1372
1411
    def run(self, verbose=False):
 
1412
        import bzrlib.ui
1373
1413
        from bzrlib.selftest import selftest
1374
 
        return int(not selftest(verbose=verbose))
 
1414
 
 
1415
        # we don't want progress meters from the tests to go to the
 
1416
        # real output; and we don't want log messages cluttering up
 
1417
        # the real logs.
 
1418
 
 
1419
        save_ui = bzrlib.ui.ui_factory
 
1420
        bzrlib.trace.info('running tests...')
 
1421
        try:
 
1422
            bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
 
1423
            result = selftest(verbose=verbose)
 
1424
            if result:
 
1425
                bzrlib.trace.info('tests passed')
 
1426
            else:
 
1427
                bzrlib.trace.info('tests failed')
 
1428
            return int(not result)
 
1429
        finally:
 
1430
            bzrlib.ui.ui_factory = save_ui
1375
1431
 
1376
1432
 
1377
1433
class cmd_version(Command):
1432
1488
 
1433
1489
 
1434
1490
 
 
1491
class cmd_find_merge_base(Command):
 
1492
    """Find and print a base revision for merging two branches.
 
1493
 
 
1494
    TODO: Options to specify revisions on either side, as if
 
1495
          merging only part of the history.
 
1496
    """
 
1497
    takes_args = ['branch', 'other']
 
1498
    hidden = True
 
1499
    
 
1500
    def run(self, branch, other):
 
1501
        branch1 = find_branch(branch)
 
1502
        branch2 = find_branch(other)
 
1503
 
 
1504
        base_revno, base_revid = branch1.common_ancestor(branch2)
 
1505
 
 
1506
        if base_revno is None:
 
1507
            raise bzrlib.errors.UnrelatedBranches()
 
1508
 
 
1509
        print 'merge base is revision %s' % base_revid
 
1510
        print ' r%-6d in %s' % (base_revno, branch)
 
1511
 
 
1512
        other_revno = branch2.revision_id_to_revno(base_revid)
 
1513
        
 
1514
        print ' r%-6d in %s' % (other_revno, other)
 
1515
 
 
1516
 
 
1517
 
1435
1518
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
 
 
 
1519
    """Perform a three-way merge.
 
1520
    
 
1521
    The branch is the branch you will merge from.  By default, it will merge
 
1522
    the latest revision.  If you specify a revision, that revision will be
 
1523
    merged.  If you specify two revisions, the first will be used as a BASE, 
 
1524
    and the second one as OTHER.  Revision numbers are always relative to the
 
1525
    specified branch.
 
1526
    
 
1527
    Examples:
 
1528
 
 
1529
    To merge the latest revision from bzr.dev
 
1530
    bzr merge ../bzr.dev
 
1531
 
 
1532
    To merge changes up to and including revision 82 from bzr.dev
 
1533
    bzr merge -r 82 ../bzr.dev
 
1534
 
 
1535
    To merge the changes introduced by 82, without previous changes:
 
1536
    bzr merge -r 81..82 ../bzr.dev
 
1537
    
1454
1538
    merge refuses to run if there are any uncommitted changes, unless
1455
1539
    --force is given.
1456
1540
    """
1457
 
    takes_args = ['other_spec', 'base_spec?']
1458
 
    takes_options = ['force', 'merge-type']
 
1541
    takes_args = ['branch?']
 
1542
    takes_options = ['revision', 'force', 'merge-type']
1459
1543
 
1460
 
    def run(self, other_spec, base_spec=None, force=False, merge_type=None):
 
1544
    def run(self, branch='.', revision=None, force=False, 
 
1545
            merge_type=None):
1461
1546
        from bzrlib.merge import merge
1462
1547
        from bzrlib.merge_core import ApplyMerge3
1463
1548
        if merge_type is None:
1464
1549
            merge_type = ApplyMerge3
1465
 
        merge(parse_spec(other_spec), parse_spec(base_spec),
1466
 
              check_clean=(not force), merge_type=merge_type)
 
1550
 
 
1551
        if revision is None or len(revision) < 1:
 
1552
            base = (None, None)
 
1553
            other = (branch, -1)
 
1554
        else:
 
1555
            if len(revision) == 1:
 
1556
                other = (branch, revision[0])
 
1557
                base = (None, None)
 
1558
            else:
 
1559
                assert len(revision) == 2
 
1560
                if None in revision:
 
1561
                    raise BzrCommandError(
 
1562
                        "Merge doesn't permit that revision specifier.")
 
1563
                base = (branch, revision[0])
 
1564
                other = (branch, revision[1])
 
1565
            
 
1566
        merge(other, base, check_clean=(not force), merge_type=merge_type)
1467
1567
 
1468
1568
 
1469
1569
class cmd_revert(Command):
1504
1604
    """Show help on a command or other topic.
1505
1605
 
1506
1606
    For a list of all available commands, say 'bzr help commands'."""
 
1607
    takes_options = ['long']
1507
1608
    takes_args = ['topic?']
1508
1609
    aliases = ['?']
1509
1610
    
1510
 
    def run(self, topic=None):
 
1611
    def run(self, topic=None, long=False):
1511
1612
        import help
 
1613
        if topic is None and long:
 
1614
            topic = "commands"
1512
1615
        help.help(topic)
1513
1616
 
1514
1617
 
 
1618
class cmd_shell_complete(Command):
 
1619
    """Show appropriate completions for context.
 
1620
 
 
1621
    For a list of all available commands, say 'bzr shell-complete'."""
 
1622
    takes_args = ['context?']
 
1623
    aliases = ['s-c']
 
1624
    hidden = True
 
1625
    
 
1626
    def run(self, context=None):
 
1627
        import shellcomplete
 
1628
        shellcomplete.shellcomplete(context)
 
1629
 
 
1630
 
 
1631
class cmd_missing(Command):
 
1632
    """What is missing in this branch relative to other branch.
 
1633
    """
 
1634
    takes_args = ['remote?']
 
1635
    aliases = ['mis', 'miss']
 
1636
    # We don't have to add quiet to the list, because 
 
1637
    # unknown options are parsed as booleans
 
1638
    takes_options = ['verbose', 'quiet']
 
1639
 
 
1640
    def run(self, remote=None, verbose=False, quiet=False):
 
1641
        from bzrlib.branch import find_branch, DivergedBranches
 
1642
        from bzrlib.errors import BzrCommandError
 
1643
        from bzrlib.missing import get_parent, show_missing
 
1644
 
 
1645
        if verbose and quiet:
 
1646
            raise BzrCommandError('Cannot pass both quiet and verbose')
 
1647
 
 
1648
        b = find_branch('.')
 
1649
        parent = get_parent(b)
 
1650
        if remote is None:
 
1651
            if parent is None:
 
1652
                raise BzrCommandError("No missing location known or specified.")
 
1653
            else:
 
1654
                if not quiet:
 
1655
                    print "Using last location: %s" % parent
 
1656
                remote = parent
 
1657
        elif parent is None:
 
1658
            # We only update x-pull if it did not exist, missing should not change the parent
 
1659
            b.controlfile('x-pull', 'wb').write(remote + '\n')
 
1660
        br_remote = find_branch(remote)
 
1661
 
 
1662
        return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
 
1663
 
1515
1664
 
1516
1665
 
1517
1666
class cmd_plugins(Command):
1546
1695
    'no-recurse':             None,
1547
1696
    'profile':                None,
1548
1697
    'revision':               _parse_revision_str,
 
1698
    'short':                  None,
1549
1699
    'show-ids':               None,
1550
1700
    'timezone':               str,
1551
1701
    'verbose':                None,
1776
1926
        return 0
1777
1927
    
1778
1928
    if not args:
1779
 
        print >>sys.stderr, "please try 'bzr help' for help"
1780
 
        return 1
 
1929
        from bzrlib.help import help
 
1930
        help(None)
 
1931
        return 0
1781
1932
    
1782
1933
    cmd = str(args.pop(0))
1783
1934
 
1822
1973
        return cmd_class(cmdopts, cmdargs).status 
1823
1974
 
1824
1975
 
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
1976
def main(argv):
 
1977
    import bzrlib.ui
1845
1978
    
1846
 
    bzrlib.trace.open_tracefile(argv)
 
1979
    bzrlib.trace.log_startup(argv)
 
1980
 
 
1981
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
1847
1982
 
1848
1983
    try:
1849
1984
        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()
 
1985
            return run_bzr(argv[1:])
 
1986
        finally:
 
1987
            # do this here inside the exception wrappers to catch EPIPE
 
1988
            sys.stdout.flush()
 
1989
    except BzrCommandError, e:
 
1990
        # command line syntax error, etc
 
1991
        log_error(str(e))
 
1992
        return 1
 
1993
    except BzrError, e:
 
1994
        bzrlib.trace.log_exception()
 
1995
        return 1
 
1996
    except AssertionError, e:
 
1997
        bzrlib.trace.log_exception('assertion failed: ' + str(e))
 
1998
        return 3
 
1999
    except KeyboardInterrupt, e:
 
2000
        bzrlib.trace.note('interrupted')
 
2001
        return 2
 
2002
    except Exception, e:
 
2003
        import errno
 
2004
        if (isinstance(e, IOError) 
 
2005
            and hasattr(e, 'errno')
 
2006
            and e.errno == errno.EPIPE):
 
2007
            bzrlib.trace.note('broken pipe')
 
2008
            return 2
 
2009
        else:
 
2010
            bzrlib.trace.log_exception()
 
2011
            return 2
1886
2012
 
1887
2013
 
1888
2014
if __name__ == '__main__':