~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

[merge] from robert and fix up tests

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
import os
20
20
 
21
21
import bzrlib
22
 
import bzrlib.trace
23
 
from bzrlib.trace import mutter, note, log_error, warning
 
22
from bzrlib import BZRDIR
 
23
from bzrlib.commands import Command
 
24
from bzrlib.branch import Branch
24
25
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
25
26
from bzrlib.errors import DivergedBranches
26
 
from bzrlib.branch import Branch
27
 
from bzrlib import BZRDIR
28
 
from bzrlib.commands import Command
29
27
from bzrlib.option import Option
 
28
from bzrlib.revisionspec import RevisionSpec
 
29
import bzrlib.trace
 
30
from bzrlib.trace import mutter, note, log_error, warning
30
31
from bzrlib.workingtree import WorkingTree
31
32
 
32
33
 
78
79
    
79
80
    def run(self, all=False, show_ids=False, file_list=None, revision=None):
80
81
        if file_list:
81
 
            b = Branch.open_containing(file_list[0])
82
 
            tree = WorkingTree(b.base, b)
83
 
            file_list = [tree.relpath(x) for x in file_list]
84
 
            # special case: only one path was given and it's the root
85
 
            # of the branch
86
 
            if file_list == ['']:
 
82
            b, relpath = Branch.open_containing(file_list[0])
 
83
            if relpath == '' and len(file_list) == 1:
87
84
                file_list = None
 
85
            else:
 
86
                # generate relative paths.
 
87
                # note that if this is a remote branch, we would want
 
88
                # relpath against the transport. RBC 20051018
 
89
                tree = WorkingTree(b.base, b)
 
90
                file_list = [tree.relpath(x) for x in file_list]
88
91
        else:
89
 
            b = Branch.open_containing('.')
 
92
            b = Branch.open_containing('.')[0]
90
93
            
91
94
        from bzrlib.status import show_status
92
95
        show_status(b, show_unchanged=all, show_ids=show_ids,
105
108
    takes_options = ['revision']
106
109
    
107
110
    def run(self, revision_id=None, revision=None):
108
 
        from bzrlib.revisionspec import RevisionSpec
109
111
 
110
112
        if revision_id is not None and revision is not None:
111
113
            raise BzrCommandError('You can only supply one of revision_id or --revision')
112
114
        if revision_id is None and revision is None:
113
115
            raise BzrCommandError('You must supply either --revision or a revision_id')
114
 
        b = Branch.open_containing('.')
 
116
        b = Branch.open_containing('.')[0]
115
117
        if revision_id is not None:
116
118
            sys.stdout.write(b.get_revision_xml_file(revision_id).read())
117
119
        elif revision is not None:
127
129
 
128
130
    This is equal to the number of revisions on this branch."""
129
131
    def run(self):
130
 
        print Branch.open_containing('.').revno()
 
132
        print Branch.open_containing('.')[0].revno()
131
133
 
132
134
 
133
135
class cmd_revision_info(Command):
137
139
    takes_args = ['revision_info*']
138
140
    takes_options = ['revision']
139
141
    def run(self, revision=None, revision_info_list=[]):
140
 
        from bzrlib.revisionspec import RevisionSpec
141
142
 
142
143
        revs = []
143
144
        if revision is not None:
148
149
        if len(revs) == 0:
149
150
            raise BzrCommandError('You must supply a revision identifier')
150
151
 
151
 
        b = Branch.open_containing('.')
 
152
        b = Branch.open_containing('.')[0]
152
153
 
153
154
        for rev in revs:
154
155
            revinfo = rev.in_history(b)
206
207
        for d in dir_list:
207
208
            os.mkdir(d)
208
209
            if not b:
209
 
                b = Branch.open_containing(d)
 
210
                b = Branch.open_containing(d)[0]
210
211
            b.add([d])
211
212
            print 'added', d
212
213
 
217
218
    hidden = True
218
219
    
219
220
    def run(self, filename):
220
 
        branch = Branch.open_containing(filename)
221
 
        print WorkingTree(branch.base, branch).relpath(filename)
 
221
        branch, relpath = Branch.open_containing(filename)
 
222
        print relpath
222
223
 
223
224
 
224
225
class cmd_inventory(Command):
226
227
    takes_options = ['revision', 'show-ids']
227
228
    
228
229
    def run(self, revision=None, show_ids=False):
229
 
        b = Branch.open_containing('.')
 
230
        b = Branch.open_containing('.')[0]
230
231
        if revision is None:
231
232
            inv = b.read_working_inventory()
232
233
        else:
252
253
    """
253
254
    takes_args = ['source$', 'dest']
254
255
    def run(self, source_list, dest):
255
 
        b = Branch.open_containing('.')
 
256
        b = Branch.open_containing('.')[0]
256
257
 
257
258
        # TODO: glob expansion on windows?
258
259
        tree = WorkingTree(b.base, b)
276
277
    takes_args = ['from_name', 'to_name']
277
278
    
278
279
    def run(self, from_name, to_name):
279
 
        b = Branch.open_containing('.')
 
280
        b = Branch.open_containing('.')[0]
280
281
        tree = WorkingTree(b.base, b)
281
282
        b.rename_one(tree.relpath(from_name), tree.relpath(to_name))
282
283
 
298
299
    def run(self, names_list):
299
300
        if len(names_list) < 2:
300
301
            raise BzrCommandError("missing file argument")
301
 
        b = Branch.open_containing(names_list[0])
 
302
        b = Branch.open_containing(names_list[0])[0]
302
303
        tree = WorkingTree(b.base, b)
303
304
        rel_names = [tree.relpath(x) for x in names_list]
304
305
        
339
340
        from shutil import rmtree
340
341
        import errno
341
342
        
342
 
        br_to = Branch.open_containing('.')
 
343
        br_to = Branch.open_containing('.')[0]
343
344
        stored_loc = br_to.get_parent()
344
345
        if location is None:
345
346
            if stored_loc is None:
411
412
        try:
412
413
            br_from.setup_caching(cache_root)
413
414
            if basis is not None:
414
 
                basis_branch = Branch.open_containing(basis)
 
415
                basis_branch = Branch.open_containing(basis)[0]
415
416
            else:
416
417
                basis_branch = None
417
418
            if len(revision) == 1 and revision[0] is not None:
453
454
    takes_args = ['dir?']
454
455
 
455
456
    def run(self, dir='.'):
456
 
        b = Branch.open_containing(dir)
 
457
        b = Branch.open_containing(dir)[0]
457
458
        old_inv = b.basis_tree().inventory
458
459
        new_inv = b.read_working_inventory()
459
460
 
469
470
    
470
471
    def run(self, branch=None):
471
472
        import info
472
 
        b = Branch.open_containing(branch)
 
473
        b = Branch.open_containing(branch)[0]
473
474
        info.show_info(b)
474
475
 
475
476
 
484
485
    aliases = ['rm']
485
486
    
486
487
    def run(self, file_list, verbose=False):
487
 
        b = Branch.open_containing(file_list[0])
 
488
        b = Branch.open_containing(file_list[0])[0]
488
489
        tree = WorkingTree(b.base, b)
489
 
        b.remove([tree.relpath(f) for f in file_list], verbose=verbose)
 
490
        tree.remove([tree.relpath(f) for f in file_list], verbose=verbose)
490
491
 
491
492
 
492
493
class cmd_file_id(Command):
499
500
    hidden = True
500
501
    takes_args = ['filename']
501
502
    def run(self, filename):
502
 
        b = Branch.open_containing(filename)
503
 
        tree = WorkingTree(b.base, b)
504
 
        i = b.inventory.path2id(tree.relpath(filename))
 
503
        b, relpath = Branch.open_containing(filename)
 
504
        i = b.inventory.path2id(relpath)
505
505
        if i == None:
506
506
            raise BzrError("%r is not a versioned file" % filename)
507
507
        else:
516
516
    hidden = True
517
517
    takes_args = ['filename']
518
518
    def run(self, filename):
519
 
        b = Branch.open_containing(filename)
 
519
        b, relpath = Branch.open_containing(filename)
520
520
        inv = b.inventory
521
 
        tree = WorkingTree(b.base, b)
522
 
        fid = inv.path2id(tree.relpath(filename))
 
521
        fid = inv.path2id(relpath)
523
522
        if fid == None:
524
523
            raise BzrError("%r is not a versioned file" % filename)
525
524
        for fip in inv.get_idpath(fid):
530
529
    """Display list of revision ids on this branch."""
531
530
    hidden = True
532
531
    def run(self):
533
 
        for patchid in Branch.open_containing('.').revision_history():
 
532
        for patchid in Branch.open_containing('.')[0].revision_history():
534
533
            print patchid
535
534
 
536
535
 
546
545
class cmd_directories(Command):
547
546
    """Display list of versioned directories in this branch."""
548
547
    def run(self):
549
 
        for name, ie in Branch.open_containing('.').read_working_inventory().directories():
 
548
        for name, ie in Branch.open_containing('.')[0].read_working_inventory().directories():
550
549
            if name == '':
551
550
                print '.'
552
551
            else:
603
602
        from bzrlib.diff import show_diff
604
603
 
605
604
        if file_list:
606
 
            b = Branch.open_containing(file_list[0])
 
605
            b = Branch.open_containing(file_list[0])[0]
607
606
            tree = WorkingTree(b.base, b)
608
607
            file_list = [tree.relpath(f) for f in file_list]
609
608
            if file_list == ['']:
610
609
                # just pointing to top-of-tree
611
610
                file_list = None
612
611
        else:
613
 
            b = Branch.open_containing('.')
 
612
            b = Branch.open_containing('.')[0]
614
613
 
615
614
        if revision is not None:
616
615
            if len(revision) == 1:
639
638
    # level of effort but possibly much less IO.  (Or possibly not,
640
639
    # if the directories are very large...)
641
640
    def run(self, show_ids=False):
642
 
        b = Branch.open_containing('.')
 
641
        b = Branch.open_containing('.')[0]
643
642
        old = b.basis_tree()
644
643
        new = b.working_tree()
645
644
        for path, ie in old.inventory.iter_entries():
656
655
    def run(self):
657
656
        from bzrlib.delta import compare_trees
658
657
 
659
 
        b = Branch.open_containing('.')
 
658
        b = Branch.open_containing('.')[0]
660
659
        td = compare_trees(b.basis_tree(), b.working_tree())
661
660
 
662
661
        for path, id, kind, text_modified, meta_modified in td.modified:
668
667
    """List files added in working tree."""
669
668
    hidden = True
670
669
    def run(self):
671
 
        b = Branch.open_containing('.')
 
670
        b = Branch.open_containing('.')[0]
672
671
        wt = b.working_tree()
673
672
        basis_inv = b.basis_tree().inventory
674
673
        inv = wt.inventory
690
689
    takes_args = ['filename?']
691
690
    def run(self, filename=None):
692
691
        """Print the branch root."""
693
 
        b = Branch.open_containing(filename)
 
692
        b = Branch.open_containing(filename)[0]
694
693
        print b.base
695
694
 
696
695
 
733
732
        direction = (forward and 'forward') or 'reverse'
734
733
        
735
734
        if filename:
736
 
            b = Branch.open_containing(filename)
737
 
            tree = WorkingTree(b.base, b)
738
 
            fp = tree.relpath(filename)
739
 
            if fp:
 
735
            b, fp = Branch.open_containing(filename)
 
736
            if fp != '':
740
737
                file_id = b.read_working_inventory().path2id(fp)
741
738
            else:
742
739
                file_id = None  # points to branch root
743
740
        else:
744
 
            b = Branch.open_containing('.')
 
741
            b, relpath = Branch.open_containing('.')
745
742
            file_id = None
746
743
 
747
744
        if revision is None:
794
791
    hidden = True
795
792
    takes_args = ["filename"]
796
793
    def run(self, filename):
797
 
        b = Branch.open_containing(filename)
 
794
        b, relpath = Branch.open_containing(filename)[0]
798
795
        inv = b.read_working_inventory()
799
 
        tree = WorkingTree(b.base, b)
800
 
        file_id = inv.path2id(tree.relpath(filename))
 
796
        file_id = inv.path2id(relpath)
801
797
        for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
802
798
            print "%6d %s" % (revno, what)
803
799
 
808
804
    # TODO: Take a revision or remote path and list that tree instead.
809
805
    hidden = True
810
806
    def run(self, revision=None, verbose=False):
811
 
        b = Branch.open_containing('.')
 
807
        b, relpath = Branch.open_containing('.')[0]
812
808
        if revision == None:
813
809
            tree = b.working_tree()
814
810
        else:
826
822
    """List unknown files."""
827
823
    def run(self):
828
824
        from bzrlib.osutils import quotefn
829
 
        for f in Branch.open_containing('.').unknowns():
 
825
        for f in Branch.open_containing('.')[0].unknowns():
830
826
            print quotefn(f)
831
827
 
832
828
 
856
852
        from bzrlib.atomicfile import AtomicFile
857
853
        import os.path
858
854
 
859
 
        b = Branch.open_containing('.')
 
855
        b, relpath = Branch.open_containing('.')
860
856
        ifn = b.abspath('.bzrignore')
861
857
 
862
858
        if os.path.exists(ifn):
896
892
 
897
893
    See also: bzr ignore"""
898
894
    def run(self):
899
 
        tree = Branch.open_containing('.').working_tree()
 
895
        tree = Branch.open_containing('.')[0].working_tree()
900
896
        for path, file_class, kind, file_id, entry in tree.list_files():
901
897
            if file_class != 'I':
902
898
                continue
920
916
        except ValueError:
921
917
            raise BzrCommandError("not a valid revision-number: %r" % revno)
922
918
 
923
 
        print Branch.open_containing('.').get_rev_id(revno)
 
919
        print Branch.open_containing('.')[0].get_rev_id(revno)
924
920
 
925
921
 
926
922
class cmd_export(Command):
939
935
    takes_options = ['revision', 'format', 'root']
940
936
    def run(self, dest, revision=None, format=None, root=None):
941
937
        import os.path
942
 
        b = Branch.open_containing('.')
 
938
        b = Branch.open_containing('.')[0]
943
939
        if revision is None:
944
940
            rev_id = b.last_revision()
945
941
        else:
978
974
            raise BzrCommandError("bzr cat requires a revision number")
979
975
        elif len(revision) != 1:
980
976
            raise BzrCommandError("bzr cat --revision takes exactly one number")
981
 
        b = Branch.open_containing('.')
982
 
        tree = WorkingTree(b.base, b)
983
 
        b.print_file(tree.relpath(filename), revision[0].in_history(b).revno)
 
977
        b, relpath = Branch.open_containing(filename)
 
978
        b.print_file(relpath, revision[0].in_history(b).revno)
984
979
 
985
980
 
986
981
class cmd_local_time_offset(Command):
1034
1029
        from bzrlib.status import show_status
1035
1030
        from cStringIO import StringIO
1036
1031
 
1037
 
        b = Branch.open_containing('.')
 
1032
        b = Branch.open_containing('.')[0]
1038
1033
        tree = WorkingTree(b.base, b)
1039
1034
        if selected_list:
1040
1035
            selected_list = [tree.relpath(s) for s in selected_list]
1084
1079
 
1085
1080
    def run(self, dir='.', verbose=False):
1086
1081
        from bzrlib.check import check
1087
 
        check(Branch.open_containing(dir), verbose)
 
1082
        check(Branch.open_containing(dir)[0], verbose)
1088
1083
 
1089
1084
 
1090
1085
class cmd_scan_cache(Command):
1129
1124
    
1130
1125
    def run(self, email=False):
1131
1126
        try:
1132
 
            b = bzrlib.branch.Branch.open_containing('.')
 
1127
            b = bzrlib.branch.Branch.open_containing('.')[0]
1133
1128
            config = bzrlib.config.BranchConfig(b)
1134
1129
        except NotBranchError:
1135
1130
            config = bzrlib.config.GlobalConfig()
1221
1216
    def run(self, branch, other):
1222
1217
        from bzrlib.revision import common_ancestor, MultipleRevisionSources
1223
1218
        
1224
 
        branch1 = Branch.open_containing(branch)
1225
 
        branch2 = Branch.open_containing(other)
 
1219
        branch1 = Branch.open_containing(branch)[0]
 
1220
        branch2 = Branch.open_containing(other)[0]
1226
1221
 
1227
1222
        history_1 = branch1.revision_history()
1228
1223
        history_2 = branch2.revision_history()
1286
1281
        if merge_type is None:
1287
1282
            merge_type = ApplyMerge3
1288
1283
        if branch is None:
1289
 
            branch = Branch.open_containing('.').get_parent()
 
1284
            branch = Branch.open_containing('.')[0].get_parent()
1290
1285
            if branch is None:
1291
1286
                raise BzrCommandError("No merge location known or specified.")
1292
1287
            else:
1343
1338
        elif len(revision) != 1:
1344
1339
            raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
1345
1340
        else:
1346
 
            b = Branch.open_containing('.')
 
1341
            b = Branch.open_containing('.')[0]
1347
1342
            revno = revision[0].in_history(b).revno
1348
1343
        merge(('.', revno), parse_spec('.'),
1349
1344
              check_clean=False,
1351
1346
              backup_files=not no_backup,
1352
1347
              file_list=file_list)
1353
1348
        if not file_list:
1354
 
            Branch.open_containing('.').set_pending_merges([])
 
1349
            Branch.open_containing('.')[0].set_pending_merges([])
1355
1350
 
1356
1351
 
1357
1352
class cmd_assert_fail(Command):
1423
1418
        if verbose and quiet:
1424
1419
            raise BzrCommandError('Cannot pass both quiet and verbose')
1425
1420
 
1426
 
        b = Branch.open_containing('.')
 
1421
        b = Branch.open_containing('.')[0]
1427
1422
        parent = b.get_parent()
1428
1423
        if remote is None:
1429
1424
            if parent is None:
1436
1431
            # We only update parent if it did not exist, missing
1437
1432
            # should not change the parent
1438
1433
            b.set_parent(remote)
1439
 
        br_remote = Branch.open_containing(remote)
 
1434
        br_remote = Branch.open_containing(remote)[0]
1440
1435
        return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
1441
1436
 
1442
1437
 
1465
1460
    takes_args = ['branch?']
1466
1461
    def run(self, branch='.', revision=None, long=False):
1467
1462
        from bzrlib.testament import Testament
1468
 
        b = Branch.open_containing(branch)
 
1463
        b = Branch.open_containing(branch)[0]
1469
1464
        b.lock_read()
1470
1465
        try:
1471
1466
            if revision is None:
1502
1497
 
1503
1498
    def run(self, filename, all=False, long=False):
1504
1499
        from bzrlib.annotate import annotate_file
1505
 
        b = Branch.open_containing(filename)
 
1500
        b, relpath = Branch.open_containing(filename)
1506
1501
        b.lock_read()
1507
1502
        try:
1508
1503
            tree = WorkingTree(b.base, b)
1509
 
            rp = tree.relpath(filename)
1510
1504
            tree = b.revision_tree(b.last_revision())
1511
 
            file_id = tree.inventory.path2id(rp)
 
1505
            file_id = tree.inventory.path2id(relpath)
1512
1506
            file_version = tree.inventory[file_id].revision
1513
1507
            annotate_file(b, file_version, file_id, long, all, sys.stdout)
1514
1508
        finally:
1515
1509
            b.unlock()
1516
1510
 
 
1511
 
 
1512
class cmd_re_sign(Command):
 
1513
    """Create a digital signature for an existing revision."""
 
1514
    # TODO be able to replace existing ones.
 
1515
 
 
1516
    hidden = True # is this right ?
 
1517
    takes_args = ['revision_id?']
 
1518
    takes_options = ['revision']
 
1519
    
 
1520
    def run(self, revision_id=None, revision=None):
 
1521
        import bzrlib.config as config
 
1522
        import bzrlib.gpg as gpg
 
1523
        if revision_id is not None and revision is not None:
 
1524
            raise BzrCommandError('You can only supply one of revision_id or --revision')
 
1525
        if revision_id is None and revision is None:
 
1526
            raise BzrCommandError('You must supply either --revision or a revision_id')
 
1527
        b = Branch.open_containing('.')[0]
 
1528
        gpg_strategy = gpg.GPGStrategy(config.BranchConfig(b))
 
1529
        if revision_id is not None:
 
1530
            b.sign_revision(revision_id, gpg_strategy)
 
1531
        elif revision is not None:
 
1532
            for rev in revision:
 
1533
                if rev is None:
 
1534
                    raise BzrCommandError('You cannot specify a NULL revision.')
 
1535
                revno, rev_id = rev.in_history(b)
 
1536
                b.sign_revision(rev_id, gpg_strategy)
 
1537
 
 
1538
 
1517
1539
# these get imported and then picked up by the scan for cmd_*
1518
1540
# TODO: Some more consistent way to split command definitions across files;
1519
1541
# we do need to load at least some information about them to know of