/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: Robert Collins
  • Date: 2005-08-25 07:48:27 UTC
  • mto: (974.1.50) (1185.1.10) (1092.3.1)
  • mto: This revision was merged to the branch mainline in revision 1139.
  • Revision ID: robertc@robertcollins.net-20050825074826-dfdf6cecb8020b93
unbreak weavebench

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
 
141
148
        raise BzrCommandError(msg)
142
149
    
143
150
 
 
151
def get_merge_type(typestring):
 
152
    """Attempt to find the merge class/factory associated with a string."""
 
153
    from merge import merge_types
 
154
    try:
 
155
        return merge_types[typestring][0]
 
156
    except KeyError:
 
157
        templ = '%s%%7s: %%s' % (' '*12)
 
158
        lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
 
159
        type_list = '\n'.join(lines)
 
160
        msg = "No known merge type %s. Supported types are:\n%s" %\
 
161
            (typestring, type_list)
 
162
        raise BzrCommandError(msg)
 
163
    
 
164
 
144
165
 
145
166
def _get_cmd_dict(plugins_override=True):
146
167
    d = {}
445
466
    takes_options = ['verbose', 'no-recurse']
446
467
    
447
468
    def run(self, file_list, verbose=False, no_recurse=False):
448
 
        from bzrlib.add import smart_add
449
 
        smart_add(file_list, verbose, not no_recurse)
 
469
        from bzrlib.add import smart_add, _PrintAddCallback
 
470
        smart_add(file_list, verbose, not no_recurse,
 
471
                  callback=_PrintAddCallback)
450
472
 
451
473
 
452
474
 
590
612
        import tempfile
591
613
        from shutil import rmtree
592
614
        import errno
 
615
        from bzrlib.branch import pull_loc
593
616
        
594
617
        br_to = find_branch('.')
595
618
        stored_loc = None
642
665
    aliases = ['get', 'clone']
643
666
 
644
667
    def run(self, from_location, to_location=None, revision=None):
 
668
        from bzrlib.branch import copy_branch, find_cached_branch
 
669
        import tempfile
645
670
        import errno
646
 
        from bzrlib.merge import merge
647
 
        from bzrlib.branch import DivergedBranches, \
648
 
             find_cached_branch, Branch
649
671
        from shutil import rmtree
650
 
        from meta_store import CachedStore
651
 
        import tempfile
652
672
        cache_root = tempfile.mkdtemp()
653
 
 
654
 
        if revision is None:
655
 
            revision = [None]
656
 
        elif len(revision) > 1:
657
 
            raise BzrCommandError('bzr branch --revision takes exactly 1 revision value')
658
 
 
659
673
        try:
 
674
            if revision is None:
 
675
                revision = [None]
 
676
            elif len(revision) > 1:
 
677
                raise BzrCommandError(
 
678
                    'bzr branch --revision takes exactly 1 revision value')
660
679
            try:
661
680
                br_from = find_cached_branch(from_location, cache_root)
662
681
            except OSError, e:
665
684
                                          ' exist.' % to_location)
666
685
                else:
667
686
                    raise
668
 
 
669
687
            if to_location is None:
670
688
                to_location = os.path.basename(from_location.rstrip("/\\"))
671
 
 
672
689
            try:
673
690
                os.mkdir(to_location)
674
691
            except OSError, e:
680
697
                                          to_location)
681
698
                else:
682
699
                    raise
683
 
            br_to = Branch(to_location, init=True)
684
 
 
685
 
            br_to.set_root_id(br_from.get_root_id())
686
 
 
687
 
            if revision:
688
 
                if revision[0] is None:
689
 
                    revno = br_from.revno()
690
 
                else:
691
 
                    revno, rev_id = br_from.get_revision_info(revision[0])
692
 
                try:
693
 
                    br_to.update_revisions(br_from, stop_revision=revno)
694
 
                except bzrlib.errors.NoSuchRevision:
695
 
                    rmtree(to_location)
696
 
                    msg = "The branch %s has no revision %d." % (from_location,
697
 
                                                                 revno)
698
 
                    raise BzrCommandError(msg)
699
 
            
700
 
            merge((to_location, -1), (to_location, 0), this_dir=to_location,
701
 
                  check_clean=False, ignore_zero=True)
702
 
            from_location = pull_loc(br_from)
703
 
            br_to.controlfile("x-pull", "wb").write(from_location + "\n")
 
700
            try:
 
701
                copy_branch(br_from, to_location, revision[0])
 
702
            except bzrlib.errors.NoSuchRevision:
 
703
                rmtree(to_location)
 
704
                msg = "The branch %s has no revision %d." % (from_location, revision[0])
 
705
                raise BzrCommandError(msg)
704
706
        finally:
705
707
            rmtree(cache_root)
706
708
 
707
709
 
708
 
def pull_loc(branch):
709
 
    # TODO: Should perhaps just make attribute be 'base' in
710
 
    # RemoteBranch and Branch?
711
 
    if hasattr(branch, "baseurl"):
712
 
        return branch.baseurl
713
 
    else:
714
 
        return branch.base
715
 
 
716
 
 
717
 
 
718
710
class cmd_renames(Command):
719
711
    """Show list of renamed files.
720
712
 
837
829
    If files are listed, only the changes in those files are listed.
838
830
    Otherwise, all changes for the tree are listed.
839
831
 
840
 
    TODO: Given two revision arguments, show the difference between them.
841
 
 
842
832
    TODO: Allow diff across branches.
843
833
 
844
834
    TODO: Option to use external diff command; could be GNU diff, wdiff,
853
843
          deleted files.
854
844
 
855
845
    TODO: This probably handles non-Unix newlines poorly.
 
846
 
 
847
    examples:
 
848
        bzr diff
 
849
        bzr diff -r1
 
850
        bzr diff -r1:2
856
851
    """
857
852
    
858
853
    takes_args = ['file*']
871
866
        else:
872
867
            b = find_branch('.')
873
868
 
874
 
        # TODO: Make show_diff support taking 2 arguments
875
 
        base_rev = None
876
869
        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
 
 
 
870
            if len(revision) == 1:
 
871
                show_diff(b, revision[0], specific_files=file_list,
 
872
                          external_diff_options=diff_options)
 
873
            elif len(revision) == 2:
 
874
                show_diff(b, revision[0], specific_files=file_list,
 
875
                          external_diff_options=diff_options,
 
876
                          revision2=revision[1])
 
877
            else:
 
878
                raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
 
879
        else:
 
880
            show_diff(b, None, specific_files=file_list,
 
881
                      external_diff_options=diff_options)
884
882
 
885
883
        
886
884
 
967
965
    """
968
966
 
969
967
    takes_args = ['filename?']
970
 
    takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision','long', 'message']
 
968
    takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision',
 
969
                     'long', 'message', 'short',]
971
970
    
972
971
    def run(self, filename=None, timezone='original',
973
972
            verbose=False,
975
974
            forward=False,
976
975
            revision=None,
977
976
            message=None,
978
 
            long=False):
 
977
            long=False,
 
978
            short=False):
979
979
        from bzrlib.branch import find_branch
980
980
        from bzrlib.log import log_formatter, show_log
981
981
        import codecs
1015
1015
        # in e.g. the default C locale.
1016
1016
        outf = codecs.getwriter(bzrlib.user_encoding)(sys.stdout, errors='replace')
1017
1017
 
1018
 
        if long:
 
1018
        if not short:
1019
1019
            log_format = 'long'
1020
1020
        else:
1021
1021
            log_format = 'short'
1315
1315
 
1316
1316
    def run(self, dir='.'):
1317
1317
        from bzrlib.check import check
 
1318
 
1318
1319
        check(find_branch(dir))
1319
1320
 
1320
1321
 
1321
 
 
1322
1322
class cmd_scan_cache(Command):
1323
1323
    hidden = True
1324
1324
    def run(self):
1359
1359
    takes_options = ['email']
1360
1360
    
1361
1361
    def run(self, email=False):
 
1362
        try:
 
1363
            b = bzrlib.branch.find_branch('.')
 
1364
        except:
 
1365
            b = None
 
1366
        
1362
1367
        if email:
1363
 
            print bzrlib.osutils.user_email()
 
1368
            print bzrlib.osutils.user_email(b)
1364
1369
        else:
1365
 
            print bzrlib.osutils.username()
 
1370
            print bzrlib.osutils.username(b)
1366
1371
 
1367
1372
 
1368
1373
class cmd_selftest(Command):
1369
1374
    """Run internal test suite"""
1370
1375
    hidden = True
1371
 
    takes_options = ['verbose']
1372
 
    def run(self, verbose=False):
 
1376
    takes_options = ['verbose', 'pattern']
 
1377
    def run(self, verbose=False, pattern=".*"):
 
1378
        import bzrlib.ui
1373
1379
        from bzrlib.selftest import selftest
1374
 
        return int(not selftest(verbose=verbose))
 
1380
        # we don't want progress meters from the tests to go to the
 
1381
        # real output.
 
1382
        save_ui = bzrlib.ui.ui_factory
 
1383
        try:
 
1384
            bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
 
1385
            return int(not selftest(verbose=verbose, pattern=pattern))
 
1386
        finally:
 
1387
            bzrlib.ui.ui_factory = save_ui
1375
1388
 
1376
1389
 
1377
1390
class cmd_version(Command):
1432
1445
 
1433
1446
 
1434
1447
 
 
1448
class cmd_find_merge_base(Command):
 
1449
    """Find and print a base revision for merging two branches.
 
1450
 
 
1451
    TODO: Options to specify revisions on either side, as if
 
1452
          merging only part of the history.
 
1453
    """
 
1454
    takes_args = ['branch', 'other']
 
1455
    hidden = True
 
1456
    
 
1457
    def run(self, branch, other):
 
1458
        branch1 = find_branch(branch)
 
1459
        branch2 = find_branch(other)
 
1460
 
 
1461
        base_revno, base_revid = branch1.common_ancestor(branch2)
 
1462
 
 
1463
        if base_revno is None:
 
1464
            raise bzrlib.errors.UnrelatedBranches()
 
1465
 
 
1466
        print 'merge base is revision %s' % base_revid
 
1467
        print ' r%-6d in %s' % (base_revno, branch)
 
1468
 
 
1469
        other_revno = branch2.revision_id_to_revno(base_revid)
 
1470
        
 
1471
        print ' r%-6d in %s' % (other_revno, other)
 
1472
 
 
1473
 
 
1474
 
1435
1475
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
 
 
 
1476
    """Perform a three-way merge.
 
1477
    
 
1478
    The branch is the branch you will merge from.  By default, it will merge
 
1479
    the latest revision.  If you specify a revision, that revision will be
 
1480
    merged.  If you specify two revisions, the first will be used as a BASE, 
 
1481
    and the second one as OTHER.  Revision numbers are always relative to the
 
1482
    specified branch.
 
1483
    
 
1484
    Examples:
 
1485
 
 
1486
    To merge the latest revision from bzr.dev
 
1487
    bzr merge ../bzr.dev
 
1488
 
 
1489
    To merge changes up to and including revision 82 from bzr.dev
 
1490
    bzr merge -r 82 ../bzr.dev
 
1491
 
 
1492
    To merge the changes introduced by 82, without previous changes:
 
1493
    bzr merge -r 81..82 ../bzr.dev
 
1494
    
1454
1495
    merge refuses to run if there are any uncommitted changes, unless
1455
1496
    --force is given.
1456
1497
    """
1457
 
    takes_args = ['other_spec', 'base_spec?']
1458
 
    takes_options = ['force', 'merge-type']
 
1498
    takes_args = ['branch?']
 
1499
    takes_options = ['revision', 'force', 'merge-type']
1459
1500
 
1460
 
    def run(self, other_spec, base_spec=None, force=False, merge_type=None):
 
1501
    def run(self, branch='.', revision=None, force=False, 
 
1502
            merge_type=None):
1461
1503
        from bzrlib.merge import merge
1462
1504
        from bzrlib.merge_core import ApplyMerge3
1463
1505
        if merge_type is None:
1464
1506
            merge_type = ApplyMerge3
1465
 
        merge(parse_spec(other_spec), parse_spec(base_spec),
1466
 
              check_clean=(not force), merge_type=merge_type)
 
1507
 
 
1508
        if revision is None or len(revision) < 1:
 
1509
            base = (None, None)
 
1510
            other = (branch, -1)
 
1511
        else:
 
1512
            if len(revision) == 1:
 
1513
                other = (branch, revision[0])
 
1514
                base = (None, None)
 
1515
            else:
 
1516
                assert len(revision) == 2
 
1517
                if None in revision:
 
1518
                    raise BzrCommandError(
 
1519
                        "Merge doesn't permit that revision specifier.")
 
1520
                base = (branch, revision[0])
 
1521
                other = (branch, revision[1])
 
1522
            
 
1523
        merge(other, base, check_clean=(not force), merge_type=merge_type)
1467
1524
 
1468
1525
 
1469
1526
class cmd_revert(Command):
1504
1561
    """Show help on a command or other topic.
1505
1562
 
1506
1563
    For a list of all available commands, say 'bzr help commands'."""
 
1564
    takes_options = ['long']
1507
1565
    takes_args = ['topic?']
1508
1566
    aliases = ['?']
1509
1567
    
1510
 
    def run(self, topic=None):
 
1568
    def run(self, topic=None, long=False):
1511
1569
        import help
 
1570
        if topic is None and long:
 
1571
            topic = "commands"
1512
1572
        help.help(topic)
1513
1573
 
1514
1574
 
 
1575
class cmd_shell_complete(Command):
 
1576
    """Show appropriate completions for context.
 
1577
 
 
1578
    For a list of all available commands, say 'bzr shell-complete'."""
 
1579
    takes_args = ['context?']
 
1580
    aliases = ['s-c']
 
1581
    hidden = True
 
1582
    
 
1583
    def run(self, context=None):
 
1584
        import shellcomplete
 
1585
        shellcomplete.shellcomplete(context)
 
1586
 
 
1587
 
 
1588
class cmd_missing(Command):
 
1589
    """What is missing in this branch relative to other branch.
 
1590
    """
 
1591
    takes_args = ['remote?']
 
1592
    aliases = ['mis', 'miss']
 
1593
    # We don't have to add quiet to the list, because 
 
1594
    # unknown options are parsed as booleans
 
1595
    takes_options = ['verbose', 'quiet']
 
1596
 
 
1597
    def run(self, remote=None, verbose=False, quiet=False):
 
1598
        from bzrlib.branch import find_branch, DivergedBranches
 
1599
        from bzrlib.errors import BzrCommandError
 
1600
        from bzrlib.missing import get_parent, show_missing
 
1601
 
 
1602
        if verbose and quiet:
 
1603
            raise BzrCommandError('Cannot pass both quiet and verbose')
 
1604
 
 
1605
        b = find_branch('.')
 
1606
        parent = get_parent(b)
 
1607
        if remote is None:
 
1608
            if parent is None:
 
1609
                raise BzrCommandError("No missing location known or specified.")
 
1610
            else:
 
1611
                if not quiet:
 
1612
                    print "Using last location: %s" % parent
 
1613
                remote = parent
 
1614
        elif parent is None:
 
1615
            # We only update x-pull if it did not exist, missing should not change the parent
 
1616
            b.controlfile('x-pull', 'wb').write(remote + '\n')
 
1617
        br_remote = find_branch(remote)
 
1618
 
 
1619
        return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
 
1620
 
1515
1621
 
1516
1622
 
1517
1623
class cmd_plugins(Command):
1546
1652
    'no-recurse':             None,
1547
1653
    'profile':                None,
1548
1654
    'revision':               _parse_revision_str,
 
1655
    'short':                  None,
1549
1656
    'show-ids':               None,
1550
1657
    'timezone':               str,
1551
1658
    'verbose':                None,
1557
1664
    'root':                   str,
1558
1665
    'no-backup':              None,
1559
1666
    'merge-type':             get_merge_type,
 
1667
    'pattern':                str,
1560
1668
    }
1561
1669
 
1562
1670
SHORT_OPTIONS = {
1776
1884
        return 0
1777
1885
    
1778
1886
    if not args:
1779
 
        print >>sys.stderr, "please try 'bzr help' for help"
1780
 
        return 1
 
1887
        from bzrlib.help import help
 
1888
        help(None)
 
1889
        return 0
1781
1890
    
1782
1891
    cmd = str(args.pop(0))
1783
1892
 
1822
1931
        return cmd_class(cmdopts, cmdargs).status 
1823
1932
 
1824
1933
 
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
1934
def main(argv):
 
1935
    import bzrlib.ui
1845
1936
    
1846
1937
    bzrlib.trace.open_tracefile(argv)
1847
1938
 
 
1939
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
 
1940
 
1848
1941
    try:
1849
1942
        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()
 
1943
            return run_bzr(argv[1:])
 
1944
        finally:
 
1945
            # do this here inside the exception wrappers to catch EPIPE
 
1946
            sys.stdout.flush()
 
1947
    except BzrCommandError, e:
 
1948
        # command line syntax error, etc
 
1949
        log_error(str(e))
 
1950
        return 1
 
1951
    except BzrError, e:
 
1952
        bzrlib.trace.log_exception()
 
1953
        return 1
 
1954
    except AssertionError, e:
 
1955
        bzrlib.trace.log_exception('assertion failed: ' + str(e))
 
1956
        return 3
 
1957
    except KeyboardInterrupt, e:
 
1958
        bzrlib.trace.note('interrupted')
 
1959
        return 2
 
1960
    except Exception, e:
 
1961
        import errno
 
1962
        if (isinstance(e, IOError) 
 
1963
            and hasattr(e, 'errno')
 
1964
            and e.errno == errno.EPIPE):
 
1965
            bzrlib.trace.note('broken pipe')
 
1966
            return 2
 
1967
        else:
 
1968
            bzrlib.trace.log_exception()
 
1969
            return 2
1886
1970
 
1887
1971
 
1888
1972
if __name__ == '__main__':