~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Martin Pool
  • Date: 2005-06-22 06:37:43 UTC
  • Revision ID: mbp@sourcefrog.net-20050622063743-e395f04c4db8977f
- move old blackbox code from testbzr into bzrlib.selftest.blackbox

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
import bzrlib
22
22
from bzrlib.trace import mutter, note, log_error
23
23
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
24
 
from bzrlib.branch import find_branch
25
 
from bzrlib import BZRDIR
 
24
from bzrlib.osutils import quotefn
 
25
from bzrlib import Branch, Inventory, InventoryEntry, BZRDIR, \
 
26
     format_date
26
27
 
27
28
 
28
29
plugin_cmds = {}
29
30
 
30
31
 
31
 
def register_command(cmd):
 
32
def register_plugin_command(cmd):
32
33
    "Utility function to help register a command"
33
34
    global plugin_cmds
34
35
    k = cmd.__name__
303
304
    
304
305
    def run(self, all=False, show_ids=False, file_list=None):
305
306
        if file_list:
306
 
            b = find_branch(file_list[0])
 
307
            b = Branch(file_list[0])
307
308
            file_list = [b.relpath(x) for x in file_list]
308
309
            # special case: only one path was given and it's the root
309
310
            # of the branch
310
311
            if file_list == ['']:
311
312
                file_list = None
312
313
        else:
313
 
            b = find_branch('.')
 
314
            b = Branch('.')
314
315
        import status
315
316
        status.show_status(b, show_unchanged=all, show_ids=show_ids,
316
317
                           specific_files=file_list)
323
324
    takes_args = ['revision_id']
324
325
    
325
326
    def run(self, revision_id):
326
 
        from bzrlib.xml import pack_xml
327
 
        pack_xml(find_branch('.').get_revision(revision_id), sys.stdout)
 
327
        Branch('.').get_revision(revision_id).write_xml(sys.stdout)
328
328
 
329
329
 
330
330
class cmd_revno(Command):
332
332
 
333
333
    This is equal to the number of revisions on this branch."""
334
334
    def run(self):
335
 
        print find_branch('.').revno()
 
335
        print Branch('.').revno()
336
336
 
337
337
    
338
338
class cmd_add(Command):
360
360
    takes_options = ['verbose', 'no-recurse']
361
361
    
362
362
    def run(self, file_list, verbose=False, no_recurse=False):
363
 
        from bzrlib.add import smart_add
364
 
        smart_add(file_list, verbose, not no_recurse)
365
 
 
366
 
 
367
 
 
368
 
class cmd_mkdir(Command):
369
 
    """Create a new versioned directory.
370
 
 
371
 
    This is equivalent to creating the directory and then adding it.
372
 
    """
373
 
    takes_args = ['dir+']
374
 
 
375
 
    def run(self, dir_list):
376
 
        b = None
377
 
        
378
 
        for d in dir_list:
379
 
            os.mkdir(d)
380
 
            if not b:
381
 
                b = find_branch(d)
382
 
            b.add([d], verbose=True)
 
363
        bzrlib.add.smart_add(file_list, verbose, not no_recurse)
383
364
 
384
365
 
385
366
class cmd_relpath(Command):
388
369
    hidden = True
389
370
    
390
371
    def run(self, filename):
391
 
        print find_branch(filename).relpath(filename)
 
372
        print Branch(filename).relpath(filename)
392
373
 
393
374
 
394
375
 
397
378
    takes_options = ['revision', 'show-ids']
398
379
    
399
380
    def run(self, revision=None, show_ids=False):
400
 
        b = find_branch('.')
 
381
        b = Branch('.')
401
382
        if revision == None:
402
383
            inv = b.read_working_inventory()
403
384
        else:
420
401
    """
421
402
    takes_args = ['source$', 'dest']
422
403
    def run(self, source_list, dest):
423
 
        b = find_branch('.')
 
404
        b = Branch('.')
424
405
 
425
406
        b.move([b.relpath(s) for s in source_list], b.relpath(dest))
426
407
 
442
423
    takes_args = ['from_name', 'to_name']
443
424
    
444
425
    def run(self, from_name, to_name):
445
 
        b = find_branch('.')
 
426
        b = Branch('.')
446
427
        b.rename_one(b.relpath(from_name), b.relpath(to_name))
447
428
 
448
429
 
467
448
 
468
449
    def run(self, location=None):
469
450
        from bzrlib.merge import merge
470
 
        import tempfile
471
 
        from shutil import rmtree
472
451
        import errno
473
452
        
474
 
        br_to = find_branch('.')
 
453
        br_to = Branch('.')
475
454
        stored_loc = None
476
455
        try:
477
456
            stored_loc = br_to.controlfile("x-pull", "rb").read().rstrip('\n')
478
457
        except IOError, e:
479
 
            if e.errno != errno.ENOENT:
 
458
            if errno == errno.ENOENT:
480
459
                raise
481
460
        if location is None:
482
461
            if stored_loc is None:
484
463
            else:
485
464
                print "Using last location: %s" % stored_loc
486
465
                location = stored_loc
487
 
        cache_root = tempfile.mkdtemp()
488
 
        from bzrlib.branch import DivergedBranches
 
466
        from branch import find_branch, DivergedBranches
489
467
        br_from = find_branch(location)
490
468
        location = pull_loc(br_from)
491
469
        old_revno = br_to.revno()
492
470
        try:
493
 
            from branch import find_cached_branch, DivergedBranches
494
 
            br_from = find_cached_branch(location, cache_root)
495
 
            location = pull_loc(br_from)
496
 
            old_revno = br_to.revno()
497
 
            try:
498
 
                br_to.update_revisions(br_from)
499
 
            except DivergedBranches:
500
 
                raise BzrCommandError("These branches have diverged."
501
 
                    "  Try merge.")
502
 
                
503
 
            merge(('.', -1), ('.', old_revno), check_clean=False)
504
 
            if location != stored_loc:
505
 
                br_to.controlfile("x-pull", "wb").write(location + "\n")
506
 
        finally:
507
 
            rmtree(cache_root)
 
471
            br_to.update_revisions(br_from)
 
472
        except DivergedBranches:
 
473
            raise BzrCommandError("These branches have diverged.  Try merge.")
 
474
            
 
475
        merge(('.', -1), ('.', old_revno), check_clean=False)
 
476
        if location != stored_loc:
 
477
            br_to.controlfile("x-pull", "wb").write(location + "\n")
508
478
 
509
479
 
510
480
 
523
493
    def run(self, from_location, to_location=None, revision=None):
524
494
        import errno
525
495
        from bzrlib.merge import merge
526
 
        from bzrlib.branch import DivergedBranches, NoSuchRevision, \
527
 
             find_cached_branch, Branch
 
496
        from branch import find_branch, DivergedBranches, NoSuchRevision
528
497
        from shutil import rmtree
529
 
        from meta_store import CachedStore
530
 
        import tempfile
531
 
        cache_root = tempfile.mkdtemp()
532
 
        try:
533
 
            try:
534
 
                br_from = find_cached_branch(from_location, cache_root)
535
 
            except OSError, e:
536
 
                if e.errno == errno.ENOENT:
537
 
                    raise BzrCommandError('Source location "%s" does not'
538
 
                                          ' exist.' % to_location)
539
 
                else:
540
 
                    raise
541
 
 
542
 
            if to_location is None:
543
 
                to_location = os.path.basename(from_location.rstrip("/\\"))
544
 
 
545
 
            try:
546
 
                os.mkdir(to_location)
547
 
            except OSError, e:
548
 
                if e.errno == errno.EEXIST:
549
 
                    raise BzrCommandError('Target directory "%s" already'
550
 
                                          ' exists.' % to_location)
551
 
                if e.errno == errno.ENOENT:
552
 
                    raise BzrCommandError('Parent of "%s" does not exist.' %
553
 
                                          to_location)
554
 
                else:
555
 
                    raise
556
 
            br_to = Branch(to_location, init=True)
557
 
 
558
 
            try:
559
 
                br_to.update_revisions(br_from, stop_revision=revision)
560
 
            except NoSuchRevision:
561
 
                rmtree(to_location)
562
 
                msg = "The branch %s has no revision %d." % (from_location,
563
 
                                                             revision)
564
 
                raise BzrCommandError(msg)
565
 
            merge((to_location, -1), (to_location, 0), this_dir=to_location,
566
 
                  check_clean=False, ignore_zero=True)
567
 
            from_location = pull_loc(br_from)
568
 
            br_to.controlfile("x-pull", "wb").write(from_location + "\n")
569
 
        finally:
570
 
            rmtree(cache_root)
 
498
        try:
 
499
            br_from = find_branch(from_location)
 
500
        except OSError, e:
 
501
            if e.errno == errno.ENOENT:
 
502
                raise BzrCommandError('Source location "%s" does not exist.' %
 
503
                                      to_location)
 
504
            else:
 
505
                raise
 
506
 
 
507
        if to_location is None:
 
508
            to_location = os.path.basename(from_location.rstrip("/\\"))
 
509
 
 
510
        try:
 
511
            os.mkdir(to_location)
 
512
        except OSError, e:
 
513
            if e.errno == errno.EEXIST:
 
514
                raise BzrCommandError('Target directory "%s" already exists.' %
 
515
                                      to_location)
 
516
            if e.errno == errno.ENOENT:
 
517
                raise BzrCommandError('Parent of "%s" does not exist.' %
 
518
                                      to_location)
 
519
            else:
 
520
                raise
 
521
        br_to = Branch(to_location, init=True)
 
522
 
 
523
        try:
 
524
            br_to.update_revisions(br_from, stop_revision=revision)
 
525
        except NoSuchRevision:
 
526
            rmtree(to_location)
 
527
            msg = "The branch %s has no revision %d." % (from_location,
 
528
                                                         revision)
 
529
            raise BzrCommandError(msg)
 
530
        merge((to_location, -1), (to_location, 0), this_dir=to_location,
 
531
              check_clean=False, ignore_zero=True)
 
532
        from_location = pull_loc(br_from)
 
533
        br_to.controlfile("x-pull", "wb").write(from_location + "\n")
571
534
 
572
535
 
573
536
def pull_loc(branch):
590
553
    takes_args = ['dir?']
591
554
 
592
555
    def run(self, dir='.'):
593
 
        b = find_branch(dir)
 
556
        b = Branch(dir)
594
557
        old_inv = b.basis_tree().inventory
595
558
        new_inv = b.read_working_inventory()
596
559
 
607
570
    def run(self, branch=None):
608
571
        import info
609
572
 
 
573
        from branch import find_branch
610
574
        b = find_branch(branch)
611
575
        info.show_info(b)
612
576
 
621
585
    takes_options = ['verbose']
622
586
    
623
587
    def run(self, file_list, verbose=False):
624
 
        b = find_branch(file_list[0])
 
588
        b = Branch(file_list[0])
625
589
        b.remove([b.relpath(f) for f in file_list], verbose=verbose)
626
590
 
627
591
 
635
599
    hidden = True
636
600
    takes_args = ['filename']
637
601
    def run(self, filename):
638
 
        b = find_branch(filename)
 
602
        b = Branch(filename)
639
603
        i = b.inventory.path2id(b.relpath(filename))
640
604
        if i == None:
641
605
            raise BzrError("%r is not a versioned file" % filename)
651
615
    hidden = True
652
616
    takes_args = ['filename']
653
617
    def run(self, filename):
654
 
        b = find_branch(filename)
 
618
        b = Branch(filename)
655
619
        inv = b.inventory
656
620
        fid = inv.path2id(b.relpath(filename))
657
621
        if fid == None:
664
628
    """Display list of revision ids on this branch."""
665
629
    hidden = True
666
630
    def run(self):
667
 
        for patchid in find_branch('.').revision_history():
 
631
        for patchid in Branch('.').revision_history():
668
632
            print patchid
669
633
 
670
634
 
671
635
class cmd_directories(Command):
672
636
    """Display list of versioned directories in this branch."""
673
637
    def run(self):
674
 
        for name, ie in find_branch('.').read_working_inventory().directories():
 
638
        for name, ie in Branch('.').read_working_inventory().directories():
675
639
            if name == '':
676
640
                print '.'
677
641
            else:
692
656
        bzr commit -m 'imported project'
693
657
    """
694
658
    def run(self):
695
 
        from bzrlib.branch import Branch
696
659
        Branch('.', init=True)
697
660
 
698
661
 
726
689
 
727
690
    def run(self, revision=None, file_list=None, diff_options=None):
728
691
        from bzrlib.diff import show_diff
 
692
        from bzrlib import find_branch
729
693
 
730
694
        if file_list:
731
695
            b = find_branch(file_list[0])
734
698
                # just pointing to top-of-tree
735
699
                file_list = None
736
700
        else:
737
 
            b = find_branch('.')
 
701
            b = Branch('.')
738
702
    
739
703
        show_diff(b, revision, specific_files=file_list,
740
704
                  external_diff_options=diff_options)
749
713
    TODO: Show files deleted since a previous revision, or between two revisions.
750
714
    """
751
715
    def run(self, show_ids=False):
752
 
        b = find_branch('.')
 
716
        b = Branch('.')
753
717
        old = b.basis_tree()
754
718
        new = b.working_tree()
755
719
 
771
735
    hidden = True
772
736
    def run(self):
773
737
        import statcache
774
 
        b = find_branch('.')
 
738
        b = Branch('.')
775
739
        inv = b.read_working_inventory()
776
740
        sc = statcache.update_cache(b, inv)
777
741
        basis = b.basis_tree()
797
761
    """List files added in working tree."""
798
762
    hidden = True
799
763
    def run(self):
800
 
        b = find_branch('.')
 
764
        b = Branch('.')
801
765
        wt = b.working_tree()
802
766
        basis_inv = b.basis_tree().inventory
803
767
        inv = wt.inventory
819
783
    takes_args = ['filename?']
820
784
    def run(self, filename=None):
821
785
        """Print the branch root."""
 
786
        from branch import find_branch
822
787
        b = find_branch(filename)
823
788
        print getattr(b, 'base', None) or getattr(b, 'baseurl')
824
789
 
842
807
            show_ids=False,
843
808
            forward=False,
844
809
            revision=None):
845
 
        from bzrlib.branch import find_branch
846
 
        from bzrlib.log import log_formatter, show_log
 
810
        from bzrlib import show_log, find_branch
847
811
        import codecs
848
812
 
849
813
        direction = (forward and 'forward') or 'reverse'
875
839
        # in e.g. the default C locale.
876
840
        outf = codecs.getwriter(bzrlib.user_encoding)(sys.stdout, errors='replace')
877
841
 
878
 
        lf = log_formatter('short',
879
 
                           show_ids=show_ids,
880
 
                           to_file=outf,
881
 
                           show_timezone=timezone)
882
 
 
883
 
        show_log(b,
884
 
                 lf,
885
 
                 file_id,
 
842
        show_log(b, file_id,
 
843
                 show_timezone=timezone,
886
844
                 verbose=verbose,
 
845
                 show_ids=show_ids,
 
846
                 to_file=outf,
887
847
                 direction=direction,
888
848
                 start_revision=revision[0],
889
849
                 end_revision=revision[1])
897
857
    hidden = True
898
858
    takes_args = ["filename"]
899
859
    def run(self, filename):
900
 
        b = find_branch(filename)
 
860
        b = Branch(filename)
901
861
        inv = b.read_working_inventory()
902
862
        file_id = inv.path2id(b.relpath(filename))
903
863
        for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
911
871
    """
912
872
    hidden = True
913
873
    def run(self, revision=None, verbose=False):
914
 
        b = find_branch('.')
 
874
        b = Branch('.')
915
875
        if revision == None:
916
876
            tree = b.working_tree()
917
877
        else:
935
895
class cmd_unknowns(Command):
936
896
    """List unknown files."""
937
897
    def run(self):
938
 
        from bzrlib.osutils import quotefn
939
 
        for f in find_branch('.').unknowns():
 
898
        for f in Branch('.').unknowns():
940
899
            print quotefn(f)
941
900
 
942
901
 
964
923
        from bzrlib.atomicfile import AtomicFile
965
924
        import os.path
966
925
 
967
 
        b = find_branch('.')
 
926
        b = Branch('.')
968
927
        ifn = b.abspath('.bzrignore')
969
928
 
970
929
        if os.path.exists(ifn):
1004
963
 
1005
964
    See also: bzr ignore"""
1006
965
    def run(self):
1007
 
        tree = find_branch('.').working_tree()
 
966
        tree = Branch('.').working_tree()
1008
967
        for path, file_class, kind, file_id in tree.list_files():
1009
968
            if file_class != 'I':
1010
969
                continue
1028
987
        except ValueError:
1029
988
            raise BzrCommandError("not a valid revision-number: %r" % revno)
1030
989
 
1031
 
        print find_branch('.').lookup_revision(revno)
 
990
        print Branch('.').lookup_revision(revno)
1032
991
 
1033
992
 
1034
993
class cmd_export(Command):
1042
1001
    takes_args = ['dest']
1043
1002
    takes_options = ['revision', 'format']
1044
1003
    def run(self, dest, revision=None, format='dir'):
1045
 
        b = find_branch('.')
 
1004
        b = Branch('.')
1046
1005
        if revision == None:
1047
1006
            rh = b.revision_history()[-1]
1048
1007
        else:
1060
1019
    def run(self, filename, revision=None):
1061
1020
        if revision == None:
1062
1021
            raise BzrCommandError("bzr cat requires a revision number")
1063
 
        b = find_branch('.')
 
1022
        b = Branch('.')
1064
1023
        b.print_file(b.relpath(filename), int(revision))
1065
1024
 
1066
1025
 
1093
1052
 
1094
1053
    def run(self, message=None, file=None, verbose=True, selected_list=None):
1095
1054
        from bzrlib.commit import commit
1096
 
        from bzrlib.osutils import get_text_message
1097
1055
 
1098
1056
        ## Warning: shadows builtin file()
1099
1057
        if not message and not file:
1100
 
            import cStringIO
1101
 
            stdout = sys.stdout
1102
 
            catcher = cStringIO.StringIO()
1103
 
            sys.stdout = catcher
1104
 
            cmd_status({"file_list":selected_list}, {})
1105
 
            info = catcher.getvalue()
1106
 
            sys.stdout = stdout
1107
 
            message = get_text_message(info)
1108
 
            
1109
 
            if message is None:
1110
 
                raise BzrCommandError("please specify a commit message",
1111
 
                                      ["use either --message or --file"])
 
1058
            raise BzrCommandError("please specify a commit message",
 
1059
                                  ["use either --message or --file"])
1112
1060
        elif message and file:
1113
1061
            raise BzrCommandError("please specify either --message or --file")
1114
1062
        
1116
1064
            import codecs
1117
1065
            message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1118
1066
 
1119
 
        b = find_branch('.')
 
1067
        b = Branch('.')
1120
1068
        commit(b, message, verbose=verbose, specific_files=selected_list)
1121
1069
 
1122
1070
 
1132
1080
    takes_args = ['dir?']
1133
1081
 
1134
1082
    def run(self, dir='.'):
1135
 
        from bzrlib.check import check
1136
 
        check(find_branch(dir))
 
1083
        import bzrlib.check
 
1084
        bzrlib.check.check(Branch(dir))
1137
1085
 
1138
1086
 
1139
1087
 
1147
1095
 
1148
1096
    def run(self, dir='.'):
1149
1097
        from bzrlib.upgrade import upgrade
1150
 
        upgrade(find_branch(dir))
 
1098
        upgrade(Branch(dir))
1151
1099
 
1152
1100
 
1153
1101
 
1253
1201
              check_clean=(not force))
1254
1202
 
1255
1203
 
1256
 
 
1257
1204
class cmd_revert(Command):
1258
 
    """Restore selected files from a previous revision.
1259
 
    """
1260
 
    takes_args = ['file+']
1261
 
    def run(self, file_list):
1262
 
        from bzrlib.branch import find_branch
1263
 
        
1264
 
        if not file_list:
1265
 
            file_list = ['.']
1266
 
            
1267
 
        b = find_branch(file_list[0])
1268
 
 
1269
 
        b.revert([b.relpath(f) for f in file_list])
1270
 
 
1271
 
 
1272
 
class cmd_merge_revert(Command):
1273
1205
    """Reverse all changes since the last commit.
1274
1206
 
1275
1207
    Only versioned files are affected.
1312
1244
    hidden = True
1313
1245
    def run(self):
1314
1246
        import statcache
1315
 
        b = find_branch('.')
 
1247
        b = Branch('.')
1316
1248
        statcache.update_cache(b.base, b.read_working_inventory())
1317
1249
 
1318
1250
 
1319
1251
 
1320
 
class cmd_plugins(Command):
1321
 
    """List plugins"""
1322
 
    hidden = True
1323
 
    def run(self):
1324
 
        import bzrlib.plugin
1325
 
        from pprint import pprint
1326
 
        pprint(bzrlib.plugin.all_plugins)
1327
 
 
1328
 
 
1329
 
 
1330
1252
# list of all available options; the rhs can be either None for an
1331
1253
# option that takes no argument, or a constructor function that checks
1332
1254
# the type.
1587
1509
    try:
1588
1510
        # some options like --builtin and --no-plugins have special effects
1589
1511
        argv, master_opts = _parse_master_args(argv)
1590
 
        if not master_opts['no-plugins']:
1591
 
            from bzrlib.plugin import load_plugins
1592
 
            load_plugins()
 
1512
        if 'no-plugins' not in master_opts:
 
1513
            bzrlib.load_plugins()
1593
1514
 
1594
1515
        args, opts = parse_args(argv)
1595
1516
 
1684
1605
 
1685
1606
 
1686
1607
def main(argv):
 
1608
    import errno
1687
1609
    
1688
 
    bzrlib.trace.open_tracefile(argv)
 
1610
    bzrlib.open_tracefile(argv)
1689
1611
 
1690
1612
    try:
1691
1613
        try:
1712
1634
            _report_exception('interrupted', quiet=True)
1713
1635
            return 2
1714
1636
        except Exception, e:
1715
 
            import errno
1716
1637
            quiet = False
1717
1638
            if (isinstance(e, IOError) 
1718
1639
                and hasattr(e, 'errno')