~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Robert Collins
  • Date: 2005-08-25 10:04:51 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-20050825100451-b01297285491ba46
make a default merge choose a sane base with branch.common_ancestor

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
 
459
466
    takes_options = ['verbose', 'no-recurse']
460
467
    
461
468
    def run(self, file_list, verbose=False, no_recurse=False):
462
 
        from bzrlib.add import smart_add
463
 
        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)
464
472
 
465
473
 
466
474
 
604
612
        import tempfile
605
613
        from shutil import rmtree
606
614
        import errno
 
615
        from bzrlib.branch import pull_loc
607
616
        
608
617
        br_to = find_branch('.')
609
618
        stored_loc = None
656
665
    aliases = ['get', 'clone']
657
666
 
658
667
    def run(self, from_location, to_location=None, revision=None):
 
668
        from bzrlib.branch import copy_branch, find_cached_branch
 
669
        import tempfile
659
670
        import errno
660
 
        from bzrlib.merge import merge
661
 
        from bzrlib.branch import DivergedBranches, \
662
 
             find_cached_branch, Branch
663
671
        from shutil import rmtree
664
 
        from meta_store import CachedStore
665
 
        import tempfile
666
672
        cache_root = tempfile.mkdtemp()
667
 
 
668
 
        if revision is None:
669
 
            revision = [None]
670
 
        elif len(revision) > 1:
671
 
            raise BzrCommandError('bzr branch --revision takes exactly 1 revision value')
672
 
 
673
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')
674
679
            try:
675
680
                br_from = find_cached_branch(from_location, cache_root)
676
681
            except OSError, e:
679
684
                                          ' exist.' % to_location)
680
685
                else:
681
686
                    raise
682
 
 
683
687
            if to_location is None:
684
688
                to_location = os.path.basename(from_location.rstrip("/\\"))
685
 
 
686
689
            try:
687
690
                os.mkdir(to_location)
688
691
            except OSError, e:
694
697
                                          to_location)
695
698
                else:
696
699
                    raise
697
 
            br_to = Branch(to_location, init=True)
698
 
 
699
 
            br_to.set_root_id(br_from.get_root_id())
700
 
 
701
 
            if revision:
702
 
                if revision[0] is None:
703
 
                    revno = br_from.revno()
704
 
                else:
705
 
                    revno, rev_id = br_from.get_revision_info(revision[0])
706
 
                try:
707
 
                    br_to.update_revisions(br_from, stop_revision=revno)
708
 
                except bzrlib.errors.NoSuchRevision:
709
 
                    rmtree(to_location)
710
 
                    msg = "The branch %s has no revision %d." % (from_location,
711
 
                                                                 revno)
712
 
                    raise BzrCommandError(msg)
713
 
            
714
 
            merge((to_location, -1), (to_location, 0), this_dir=to_location,
715
 
                  check_clean=False, ignore_zero=True)
716
 
            from_location = pull_loc(br_from)
717
 
            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)
718
706
        finally:
719
707
            rmtree(cache_root)
720
708
 
721
709
 
722
 
def pull_loc(branch):
723
 
    # TODO: Should perhaps just make attribute be 'base' in
724
 
    # RemoteBranch and Branch?
725
 
    if hasattr(branch, "baseurl"):
726
 
        return branch.baseurl
727
 
    else:
728
 
        return branch.base
729
 
 
730
 
 
731
 
 
732
710
class cmd_renames(Command):
733
711
    """Show list of renamed files.
734
712
 
1337
1315
 
1338
1316
    def run(self, dir='.'):
1339
1317
        from bzrlib.check import check
 
1318
 
1340
1319
        check(find_branch(dir))
1341
1320
 
1342
1321
 
1343
 
 
1344
1322
class cmd_scan_cache(Command):
1345
1323
    hidden = True
1346
1324
    def run(self):
1395
1373
class cmd_selftest(Command):
1396
1374
    """Run internal test suite"""
1397
1375
    hidden = True
1398
 
    takes_options = ['verbose']
1399
 
    def run(self, verbose=False):
 
1376
    takes_options = ['verbose', 'pattern']
 
1377
    def run(self, verbose=False, pattern=".*"):
 
1378
        import bzrlib.ui
1400
1379
        from bzrlib.selftest import selftest
1401
 
        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
1402
1388
 
1403
1389
 
1404
1390
class cmd_version(Command):
1459
1445
 
1460
1446
 
1461
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
 
1462
1475
class cmd_merge(Command):
1463
1476
    """Perform a three-way merge.
1464
1477
    
1548
1561
    """Show help on a command or other topic.
1549
1562
 
1550
1563
    For a list of all available commands, say 'bzr help commands'."""
 
1564
    takes_options = ['long']
1551
1565
    takes_args = ['topic?']
1552
1566
    aliases = ['?']
1553
1567
    
1554
 
    def run(self, topic=None):
 
1568
    def run(self, topic=None, long=False):
1555
1569
        import help
 
1570
        if topic is None and long:
 
1571
            topic = "commands"
1556
1572
        help.help(topic)
1557
1573
 
1558
1574
 
1603
1619
        return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
1604
1620
 
1605
1621
 
 
1622
 
1606
1623
class cmd_plugins(Command):
1607
1624
    """List plugins"""
1608
1625
    hidden = True
1647
1664
    'root':                   str,
1648
1665
    'no-backup':              None,
1649
1666
    'merge-type':             get_merge_type,
 
1667
    'pattern':                str,
1650
1668
    }
1651
1669
 
1652
1670
SHORT_OPTIONS = {
1866
1884
        return 0
1867
1885
    
1868
1886
    if not args:
1869
 
        print >>sys.stderr, "please try 'bzr help' for help"
1870
 
        return 1
 
1887
        from bzrlib.help import help
 
1888
        help(None)
 
1889
        return 0
1871
1890
    
1872
1891
    cmd = str(args.pop(0))
1873
1892
 
1912
1931
        return cmd_class(cmdopts, cmdargs).status 
1913
1932
 
1914
1933
 
1915
 
def _report_exception(summary, quiet=False):
1916
 
    import traceback
1917
 
    
1918
 
    log_error('bzr: ' + summary)
1919
 
    bzrlib.trace.log_exception()
1920
 
 
1921
 
    if os.environ.get('BZR_DEBUG'):
1922
 
        traceback.print_exc()
1923
 
 
1924
 
    if not quiet:
1925
 
        sys.stderr.write('\n')
1926
 
        tb = sys.exc_info()[2]
1927
 
        exinfo = traceback.extract_tb(tb)
1928
 
        if exinfo:
1929
 
            sys.stderr.write('  at %s:%d in %s()\n' % exinfo[-1][:3])
1930
 
        sys.stderr.write('  see ~/.bzr.log for debug information\n')
1931
 
 
1932
 
 
1933
 
 
1934
1934
def main(argv):
 
1935
    import bzrlib.ui
1935
1936
    
1936
1937
    bzrlib.trace.open_tracefile(argv)
1937
1938
 
 
1939
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
 
1940
 
1938
1941
    try:
1939
1942
        try:
1940
 
            try:
1941
 
                return run_bzr(argv[1:])
1942
 
            finally:
1943
 
                # do this here inside the exception wrappers to catch EPIPE
1944
 
                sys.stdout.flush()
1945
 
        except BzrError, e:
1946
 
            quiet = isinstance(e, (BzrCommandError))
1947
 
            _report_exception('error: ' + str(e), quiet=quiet)
1948
 
            if len(e.args) > 1:
1949
 
                for h in e.args[1]:
1950
 
                    # some explanation or hints
1951
 
                    log_error('  ' + h)
1952
 
            return 1
1953
 
        except AssertionError, e:
1954
 
            msg = 'assertion failed'
1955
 
            if str(e):
1956
 
                msg += ': ' + str(e)
1957
 
            _report_exception(msg)
1958
 
            return 2
1959
 
        except KeyboardInterrupt, e:
1960
 
            _report_exception('interrupted', quiet=True)
1961
 
            return 2
1962
 
        except Exception, e:
1963
 
            import errno
1964
 
            quiet = False
1965
 
            if (isinstance(e, IOError) 
1966
 
                and hasattr(e, 'errno')
1967
 
                and e.errno == errno.EPIPE):
1968
 
                quiet = True
1969
 
                msg = 'broken pipe'
1970
 
            else:
1971
 
                msg = str(e).rstrip('\n')
1972
 
            _report_exception(msg, quiet)
1973
 
            return 2
1974
 
    finally:
1975
 
        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
1976
1970
 
1977
1971
 
1978
1972
if __name__ == '__main__':