~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

Merge in format-5 work - release bzr 0.1rc1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
import bzrlib
22
22
import bzrlib.trace
23
23
from bzrlib.trace import mutter, note, log_error, warning
24
 
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
 
24
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
25
25
from bzrlib.branch import Branch
26
26
from bzrlib import BZRDIR
27
27
from bzrlib.commands import Command
70
70
    # relative to a revision, or between revisions
71
71
 
72
72
    takes_args = ['file*']
73
 
    takes_options = ['all', 'show-ids', 'revision']
 
73
    takes_options = ['all', 'show-ids']
74
74
    aliases = ['st', 'stat']
75
75
    
76
76
    def run(self, all=False, show_ids=False, file_list=None, revision=None):
372
372
 
373
373
    To retrieve the branch as of a particular revision, supply the --revision
374
374
    parameter, as in "branch foo/bar -r 5".
 
375
 
 
376
    --basis is to speed up branching from remote branches.  When specified, it
 
377
    copies all the file-contents, inventory and revision data from the basis
 
378
    branch before copying anything from the remote branch.
375
379
    """
376
380
    takes_args = ['from_location', 'to_location?']
377
 
    takes_options = ['revision']
 
381
    takes_options = ['revision', 'basis']
378
382
    aliases = ['get', 'clone']
379
383
 
380
 
    def run(self, from_location, to_location=None, revision=None):
381
 
        from bzrlib.branch import copy_branch
 
384
    def run(self, from_location, to_location=None, revision=None, basis=None):
 
385
        from bzrlib.clone import copy_branch
382
386
        import tempfile
383
387
        import errno
384
388
        from shutil import rmtree
398
402
                else:
399
403
                    raise
400
404
            br_from.setup_caching(cache_root)
 
405
            if basis is not None:
 
406
                basis_branch = Branch.open_containing(basis)
 
407
            else:
 
408
                basis_branch = None
401
409
            if len(revision) == 1 and revision[0] is not None:
402
 
                revno = revision[0].in_history(br_from)[0]
 
410
                revision_id = revision[0].in_history(br_from)[1]
403
411
            else:
404
 
                revno = None
 
412
                revision_id = None
405
413
            if to_location is None:
406
414
                to_location = os.path.basename(from_location.rstrip("/\\"))
407
415
            try:
416
424
                else:
417
425
                    raise
418
426
            try:
419
 
                copy_branch(br_from, to_location, revno)
 
427
                copy_branch(br_from, to_location, revision_id, basis_branch)
420
428
            except bzrlib.errors.NoSuchRevision:
421
429
                rmtree(to_location)
422
430
                msg = "The branch %s has no revision %d." % (from_location, revision[0])
423
431
                raise BzrCommandError(msg)
 
432
            except bzrlib.errors.UnlistableBranch:
 
433
                msg = "The branch %s cannot be used as a --basis"
424
434
        finally:
425
435
            rmtree(cache_root)
426
436
 
513
523
            print patchid
514
524
 
515
525
 
 
526
class cmd_ancestry(Command):
 
527
    """List all revisions merged into this branch."""
 
528
    hidden = True
 
529
    def run(self):
 
530
        b = find_branch('.')
 
531
        for revision_id in b.get_ancestry(b.last_revision()):
 
532
            print revision_id
 
533
 
 
534
 
516
535
class cmd_directories(Command):
517
536
    """Display list of versioned directories in this branch."""
518
537
    def run(self):
537
556
        bzr commit -m 'imported project'
538
557
    """
539
558
    def run(self):
540
 
        from bzrlib.branch import Branch
541
559
        Branch.initialize('.')
542
560
 
543
561
 
633
651
        b = Branch.open_containing('.')
634
652
        td = compare_trees(b.basis_tree(), b.working_tree())
635
653
 
636
 
        for path, id, kind in td.modified:
 
654
        for path, id, kind, text_modified, meta_modified in td.modified:
637
655
            print path
638
656
 
639
657
 
677
695
 
678
696
    --message allows you to give a regular expression, which will be evaluated
679
697
    so that only matching entries will be displayed.
680
 
 
681
 
    TODO: Make --revision support uuid: and hash: [future tag:] notation.
682
 
  
683
698
    """
684
699
 
 
700
    # TODO: Make --revision support uuid: and hash: [future tag:] notation.
 
701
 
685
702
    takes_args = ['filename?']
686
703
    takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision',
687
704
                     'long', 'message', 'short',]
778
795
            tree = b.working_tree()
779
796
        else:
780
797
            tree = b.revision_tree(revision.in_history(b).rev_id)
781
 
 
782
 
        for fp, fc, kind, fid in tree.list_files():
 
798
        for fp, fc, kind, fid, entry in tree.list_files():
783
799
            if verbose:
784
 
                if kind == 'directory':
785
 
                    kindch = '/'
786
 
                elif kind == 'file':
787
 
                    kindch = ''
788
 
                else:
789
 
                    kindch = '???'
790
 
 
 
800
                kindch = entry.kind_character()
791
801
                print '%-8s %s%s' % (fc, fp, kindch)
792
802
            else:
793
803
                print fp
867
877
    See also: bzr ignore"""
868
878
    def run(self):
869
879
        tree = Branch.open_containing('.').working_tree()
870
 
        for path, file_class, kind, file_id in tree.list_files():
 
880
        for path, file_class, kind, file_id, entry in tree.list_files():
871
881
            if file_class != 'I':
872
882
                continue
873
883
            ## XXX: Slightly inefficient since this was already calculated
911
921
        import os.path
912
922
        b = Branch.open_containing('.')
913
923
        if revision is None:
914
 
            rev_id = b.last_patch()
 
924
            rev_id = b.last_revision()
915
925
        else:
916
926
            if len(revision) != 1:
917
927
                raise BzrError('bzr export --revision takes exactly 1 argument')
918
928
            rev_id = revision[0].in_history(b).rev_id
919
929
        t = b.revision_tree(rev_id)
920
 
        root, ext = os.path.splitext(dest)
 
930
        arg_root, ext = os.path.splitext(os.path.basename(dest))
 
931
        if ext in ('.gz', '.bz2'):
 
932
            new_root, new_ext = os.path.splitext(arg_root)
 
933
            if new_ext == '.tar':
 
934
                arg_root = new_root
 
935
                ext = new_ext + ext
 
936
        if root is None:
 
937
            root = arg_root
921
938
        if not format:
922
939
            if ext in (".tar",):
923
940
                format = "tar"
924
 
            elif ext in (".gz", ".tgz"):
 
941
            elif ext in (".tar.gz", ".tgz"):
925
942
                format = "tgz"
926
 
            elif ext in (".bz2", ".tbz2"):
 
943
            elif ext in (".tar.bz2", ".tbz2"):
927
944
                format = "tbz2"
928
945
            else:
929
946
                format = "dir"
975
992
    aliases = ['ci', 'checkin']
976
993
 
977
994
    # TODO: Give better message for -s, --summary, used by tla people
 
995
 
 
996
    # XXX: verbose currently does nothing
978
997
    
979
998
    def run(self, message=None, file=None, verbose=True, selected_list=None,
980
999
            unchanged=False):
987
1006
        if selected_list:
988
1007
            selected_list = [b.relpath(s) for s in selected_list]
989
1008
            
990
 
        if not message and not file:
 
1009
        if message is None and not file:
991
1010
            catcher = StringIO()
992
1011
            show_status(b, specific_files=selected_list,
993
1012
                        to_file=catcher)
994
1013
            message = edit_commit_message(catcher.getvalue())
995
 
            
 
1014
 
996
1015
            if message is None:
997
1016
                raise BzrCommandError("please specify a commit message"
998
1017
                                      " with either --message or --file")
1003
1022
            import codecs
1004
1023
            message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1005
1024
 
 
1025
        if message == "":
 
1026
                raise BzrCommandError("empty commit message specified")
 
1027
            
1006
1028
        try:
1007
 
            b.commit(message, verbose=verbose,
 
1029
            b.commit(message,
1008
1030
                     specific_files=selected_list,
1009
1031
                     allow_pointless=unchanged)
1010
1032
        except PointlessCommit:
1053
1075
 
1054
1076
    The check command or bzr developers may sometimes advise you to run
1055
1077
    this command.
 
1078
 
 
1079
    This version of this command upgrades from the full-text storage
 
1080
    used by bzr 0.0.8 and earlier to the weave format (v5).
1056
1081
    """
1057
1082
    takes_args = ['dir?']
1058
1083
 
1059
1084
    def run(self, dir='.'):
1060
1085
        from bzrlib.upgrade import upgrade
1061
 
        upgrade(Branch.open_containing(dir))
1062
 
 
 
1086
        upgrade(dir)
1063
1087
 
1064
1088
 
1065
1089
class cmd_whoami(Command):
1069
1093
    def run(self, email=False):
1070
1094
        try:
1071
1095
            b = bzrlib.branch.Branch.open_containing('.')
1072
 
        except:
 
1096
        except NotBranchError:
1073
1097
            b = None
1074
1098
        
1075
1099
        if email:
1079
1103
 
1080
1104
 
1081
1105
class cmd_selftest(Command):
1082
 
    """Run internal test suite"""
 
1106
    """Run internal test suite.
 
1107
    
 
1108
    This creates temporary test directories in the working directory,
 
1109
    but not existing data is affected.  These directories are deleted
 
1110
    if the tests pass, or left behind to help in debugging if they
 
1111
    fail.
 
1112
    
 
1113
    If arguments are given, they are regular expressions that say
 
1114
    which tests should run."""
 
1115
    # TODO: --list should give a list of all available tests
1083
1116
    hidden = True
 
1117
    takes_args = ['testnames*']
1084
1118
    takes_options = ['verbose', 'pattern']
1085
 
    def run(self, verbose=False, pattern=".*"):
 
1119
    def run(self, testnames_list=None, verbose=False, pattern=".*"):
1086
1120
        import bzrlib.ui
1087
1121
        from bzrlib.selftest import selftest
1088
1122
        # we don't want progress meters from the tests to go to the
1092
1126
        bzrlib.trace.info('running tests...')
1093
1127
        try:
1094
1128
            bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1095
 
            result = selftest(verbose=verbose, pattern=pattern)
 
1129
            result = selftest(verbose=verbose, 
 
1130
                              pattern=pattern,
 
1131
                              testnames=testnames_list)
1096
1132
            if result:
1097
1133
                bzrlib.trace.info('tests passed')
1098
1134
            else:
1146
1182
        history_1 = branch1.revision_history()
1147
1183
        history_2 = branch2.revision_history()
1148
1184
 
1149
 
        last1 = branch1.last_patch()
1150
 
        last2 = branch2.last_patch()
 
1185
        last1 = branch1.last_revision()
 
1186
        last2 = branch2.last_revision()
1151
1187
 
1152
1188
        source = MultipleRevisionSources(branch1, branch2)
1153
1189
        
1217
1253
                if None in revision:
1218
1254
                    raise BzrCommandError(
1219
1255
                        "Merge doesn't permit that revision specifier.")
1220
 
                from bzrlib.branch import Branch
1221
1256
                b = Branch.open(branch)
1222
1257
 
1223
1258
                base = [branch, revision[0].in_history(b).revno]
1248
1283
 
1249
1284
    def run(self, revision=None, no_backup=False, file_list=None):
1250
1285
        from bzrlib.merge import merge
1251
 
        from bzrlib.branch import Branch
1252
1286
        from bzrlib.commands import parse_spec
1253
1287
 
1254
1288
        if file_list is not None:
1305
1339
        shellcomplete.shellcomplete(context)
1306
1340
 
1307
1341
 
 
1342
class cmd_fetch(Command):
 
1343
    """Copy in history from another branch but don't merge it.
 
1344
 
 
1345
    This is an internal method used for pull and merge."""
 
1346
    hidden = True
 
1347
    takes_args = ['from_branch', 'to_branch']
 
1348
    def run(self, from_branch, to_branch):
 
1349
        from bzrlib.fetch import Fetcher
 
1350
        from bzrlib.branch import Branch
 
1351
        from_b = Branch(from_branch)
 
1352
        to_b = Branch(to_branch)
 
1353
        Fetcher(to_b, from_b)
 
1354
        
 
1355
 
 
1356
 
1308
1357
class cmd_missing(Command):
1309
1358
    """What is missing in this branch relative to other branch.
1310
1359
    """
 
1360
    # TODO: rewrite this in terms of ancestry so that it shows only
 
1361
    # unmerged things
 
1362
    
1311
1363
    takes_args = ['remote?']
1312
1364
    aliases = ['mis', 'miss']
1313
1365
    # We don't have to add quiet to the list, because 
1335
1387
            # should not change the parent
1336
1388
            b.set_parent(remote)
1337
1389
        br_remote = Branch.open_containing(remote)
1338
 
 
1339
1390
        return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
1340
1391
 
1341
1392
 
1342
 
 
1343
1393
class cmd_plugins(Command):
1344
1394
    """List plugins"""
1345
1395
    hidden = True