/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-26 00:10:48 UTC
  • Revision ID: mbp@sourcefrog.net-20050826001048-b84148d3ef567d0d
- fix bzr.dev branch url in tutorial
  thanks to madduck

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
        bzrlib.trace.disable_default_logging()
 
1418
        try:
 
1419
            bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
 
1420
            result = selftest(verbose=verbose)
 
1421
            if result:
 
1422
                bzrlib.trace.info('tests passed')
 
1423
            else:
 
1424
                bzrlib.trace.info('tests failed')
 
1425
            return int(not result)
 
1426
        finally:
 
1427
            bzrlib.trace.enable_default_logging()
 
1428
            bzrlib.ui.ui_factory = save_ui
1375
1429
 
1376
1430
 
1377
1431
class cmd_version(Command):
1432
1486
 
1433
1487
 
1434
1488
 
 
1489
class cmd_find_merge_base(Command):
 
1490
    """Find and print a base revision for merging two branches.
 
1491
 
 
1492
    TODO: Options to specify revisions on either side, as if
 
1493
          merging only part of the history.
 
1494
    """
 
1495
    takes_args = ['branch', 'other']
 
1496
    hidden = True
 
1497
    
 
1498
    def run(self, branch, other):
 
1499
        branch1 = find_branch(branch)
 
1500
        branch2 = find_branch(other)
 
1501
 
 
1502
        base_revno, base_revid = branch1.common_ancestor(branch2)
 
1503
 
 
1504
        if base_revno is None:
 
1505
            raise bzrlib.errors.UnrelatedBranches()
 
1506
 
 
1507
        print 'merge base is revision %s' % base_revid
 
1508
        print ' r%-6d in %s' % (base_revno, branch)
 
1509
 
 
1510
        other_revno = branch2.revision_id_to_revno(base_revid)
 
1511
        
 
1512
        print ' r%-6d in %s' % (other_revno, other)
 
1513
 
 
1514
 
 
1515
 
1435
1516
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
 
 
 
1517
    """Perform a three-way merge.
 
1518
    
 
1519
    The branch is the branch you will merge from.  By default, it will merge
 
1520
    the latest revision.  If you specify a revision, that revision will be
 
1521
    merged.  If you specify two revisions, the first will be used as a BASE, 
 
1522
    and the second one as OTHER.  Revision numbers are always relative to the
 
1523
    specified branch.
 
1524
    
 
1525
    Examples:
 
1526
 
 
1527
    To merge the latest revision from bzr.dev
 
1528
    bzr merge ../bzr.dev
 
1529
 
 
1530
    To merge changes up to and including revision 82 from bzr.dev
 
1531
    bzr merge -r 82 ../bzr.dev
 
1532
 
 
1533
    To merge the changes introduced by 82, without previous changes:
 
1534
    bzr merge -r 81..82 ../bzr.dev
 
1535
    
1454
1536
    merge refuses to run if there are any uncommitted changes, unless
1455
1537
    --force is given.
1456
1538
    """
1457
 
    takes_args = ['other_spec', 'base_spec?']
1458
 
    takes_options = ['force', 'merge-type']
 
1539
    takes_args = ['branch?']
 
1540
    takes_options = ['revision', 'force', 'merge-type']
1459
1541
 
1460
 
    def run(self, other_spec, base_spec=None, force=False, merge_type=None):
 
1542
    def run(self, branch='.', revision=None, force=False, 
 
1543
            merge_type=None):
1461
1544
        from bzrlib.merge import merge
1462
1545
        from bzrlib.merge_core import ApplyMerge3
1463
1546
        if merge_type is None:
1464
1547
            merge_type = ApplyMerge3
1465
 
        merge(parse_spec(other_spec), parse_spec(base_spec),
1466
 
              check_clean=(not force), merge_type=merge_type)
 
1548
 
 
1549
        if revision is None or len(revision) < 1:
 
1550
            base = (None, None)
 
1551
            other = (branch, -1)
 
1552
        else:
 
1553
            if len(revision) == 1:
 
1554
                other = (branch, revision[0])
 
1555
                base = (None, None)
 
1556
            else:
 
1557
                assert len(revision) == 2
 
1558
                if None in revision:
 
1559
                    raise BzrCommandError(
 
1560
                        "Merge doesn't permit that revision specifier.")
 
1561
                base = (branch, revision[0])
 
1562
                other = (branch, revision[1])
 
1563
            
 
1564
        merge(other, base, check_clean=(not force), merge_type=merge_type)
1467
1565
 
1468
1566
 
1469
1567
class cmd_revert(Command):
1504
1602
    """Show help on a command or other topic.
1505
1603
 
1506
1604
    For a list of all available commands, say 'bzr help commands'."""
 
1605
    takes_options = ['long']
1507
1606
    takes_args = ['topic?']
1508
1607
    aliases = ['?']
1509
1608
    
1510
 
    def run(self, topic=None):
 
1609
    def run(self, topic=None, long=False):
1511
1610
        import help
 
1611
        if topic is None and long:
 
1612
            topic = "commands"
1512
1613
        help.help(topic)
1513
1614
 
1514
1615
 
 
1616
class cmd_shell_complete(Command):
 
1617
    """Show appropriate completions for context.
 
1618
 
 
1619
    For a list of all available commands, say 'bzr shell-complete'."""
 
1620
    takes_args = ['context?']
 
1621
    aliases = ['s-c']
 
1622
    hidden = True
 
1623
    
 
1624
    def run(self, context=None):
 
1625
        import shellcomplete
 
1626
        shellcomplete.shellcomplete(context)
 
1627
 
 
1628
 
 
1629
class cmd_missing(Command):
 
1630
    """What is missing in this branch relative to other branch.
 
1631
    """
 
1632
    takes_args = ['remote?']
 
1633
    aliases = ['mis', 'miss']
 
1634
    # We don't have to add quiet to the list, because 
 
1635
    # unknown options are parsed as booleans
 
1636
    takes_options = ['verbose', 'quiet']
 
1637
 
 
1638
    def run(self, remote=None, verbose=False, quiet=False):
 
1639
        from bzrlib.branch import find_branch, DivergedBranches
 
1640
        from bzrlib.errors import BzrCommandError
 
1641
        from bzrlib.missing import get_parent, show_missing
 
1642
 
 
1643
        if verbose and quiet:
 
1644
            raise BzrCommandError('Cannot pass both quiet and verbose')
 
1645
 
 
1646
        b = find_branch('.')
 
1647
        parent = get_parent(b)
 
1648
        if remote is None:
 
1649
            if parent is None:
 
1650
                raise BzrCommandError("No missing location known or specified.")
 
1651
            else:
 
1652
                if not quiet:
 
1653
                    print "Using last location: %s" % parent
 
1654
                remote = parent
 
1655
        elif parent is None:
 
1656
            # We only update x-pull if it did not exist, missing should not change the parent
 
1657
            b.controlfile('x-pull', 'wb').write(remote + '\n')
 
1658
        br_remote = find_branch(remote)
 
1659
 
 
1660
        return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
 
1661
 
1515
1662
 
1516
1663
 
1517
1664
class cmd_plugins(Command):
1546
1693
    'no-recurse':             None,
1547
1694
    'profile':                None,
1548
1695
    'revision':               _parse_revision_str,
 
1696
    'short':                  None,
1549
1697
    'show-ids':               None,
1550
1698
    'timezone':               str,
1551
1699
    'verbose':                None,
1776
1924
        return 0
1777
1925
    
1778
1926
    if not args:
1779
 
        print >>sys.stderr, "please try 'bzr help' for help"
1780
 
        return 1
 
1927
        from bzrlib.help import help
 
1928
        help(None)
 
1929
        return 0
1781
1930
    
1782
1931
    cmd = str(args.pop(0))
1783
1932
 
1822
1971
        return cmd_class(cmdopts, cmdargs).status 
1823
1972
 
1824
1973
 
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
1974
def main(argv):
 
1975
    import bzrlib.ui
1845
1976
    
1846
 
    bzrlib.trace.open_tracefile(argv)
 
1977
    bzrlib.trace.log_startup(argv)
 
1978
 
 
1979
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
1847
1980
 
1848
1981
    try:
1849
1982
        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()
 
1983
            return run_bzr(argv[1:])
 
1984
        finally:
 
1985
            # do this here inside the exception wrappers to catch EPIPE
 
1986
            sys.stdout.flush()
 
1987
    except BzrCommandError, e:
 
1988
        # command line syntax error, etc
 
1989
        log_error(str(e))
 
1990
        return 1
 
1991
    except BzrError, e:
 
1992
        bzrlib.trace.log_exception()
 
1993
        return 1
 
1994
    except AssertionError, e:
 
1995
        bzrlib.trace.log_exception('assertion failed: ' + str(e))
 
1996
        return 3
 
1997
    except KeyboardInterrupt, e:
 
1998
        bzrlib.trace.note('interrupted')
 
1999
        return 2
 
2000
    except Exception, e:
 
2001
        import errno
 
2002
        if (isinstance(e, IOError) 
 
2003
            and hasattr(e, 'errno')
 
2004
            and e.errno == errno.EPIPE):
 
2005
            bzrlib.trace.note('broken pipe')
 
2006
            return 2
 
2007
        else:
 
2008
            bzrlib.trace.log_exception()
 
2009
            return 2
1886
2010
 
1887
2011
 
1888
2012
if __name__ == '__main__':