~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Robert Collins
  • Date: 2005-10-09 23:12:35 UTC
  • Revision ID: robertc@robertcollins.net-20051009231235-93626e72cac71b78
clean up test dirs on make clean

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
import bzrlib.trace
23
23
from bzrlib.trace import mutter, note, log_error, warning
24
24
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
25
 
from bzrlib.errors import DivergedBranches
26
25
from bzrlib.branch import Branch
27
26
from bzrlib import BZRDIR
28
27
from bzrlib.commands import Command
179
178
    get added when you add a file in the directory.
180
179
    """
181
180
    takes_args = ['file*']
182
 
    takes_options = ['no-recurse', 'quiet']
 
181
    takes_options = ['verbose', 'no-recurse']
183
182
    
184
 
    def run(self, file_list, no_recurse=False, quiet=False):
185
 
        from bzrlib.add import smart_add, add_reporter_print, add_reporter_null
186
 
        if quiet:
187
 
            reporter = add_reporter_null
188
 
        else:
189
 
            reporter = add_reporter_print
190
 
        smart_add(file_list, not no_recurse, reporter)
 
183
    def run(self, file_list, verbose=False, no_recurse=False):
 
184
        # verbose currently has no effect
 
185
        from bzrlib.add import smart_add, add_reporter_print
 
186
        smart_add(file_list, not no_recurse, add_reporter_print)
 
187
 
191
188
 
192
189
 
193
190
class cmd_mkdir(Command):
266
263
 
267
264
    See also the 'move' command, which moves files into a different
268
265
    directory without changing their name.
269
 
    """
270
 
    # TODO: Some way to rename multiple files without invoking 
271
 
    # bzr for each one?"""
 
266
 
 
267
    TODO: Some way to rename multiple files without invoking bzr for each
 
268
    one?"""
272
269
    takes_args = ['from_name', 'to_name']
273
270
    
274
271
    def run(self, from_name, to_name):
344
341
                print "Using saved location: %s" % stored_loc
345
342
                location = stored_loc
346
343
        cache_root = tempfile.mkdtemp()
347
 
        br_from = Branch.open(location)
348
 
        br_from.lock_read()
 
344
        from bzrlib.errors import DivergedBranches
 
345
        br_from = Branch.open_containing(location)
 
346
        location = br_from.base
 
347
        old_revno = br_to.revno()
349
348
        try:
 
349
            from bzrlib.errors import DivergedBranches
 
350
            br_from = Branch.open(location)
350
351
            br_from.setup_caching(cache_root)
351
352
            location = br_from.base
352
353
            old_revno = br_to.revno()
353
 
            old_revision_history = br_to.revision_history()
354
354
            try:
355
355
                br_to.update_revisions(br_from)
356
356
            except DivergedBranches:
357
357
                raise BzrCommandError("These branches have diverged."
358
358
                    "  Try merge.")
359
 
            new_revision_history = br_to.revision_history()
360
 
            if new_revision_history != old_revision_history:
361
 
                merge(('.', -1), ('.', old_revno), check_clean=False)
 
359
                
 
360
            merge(('.', -1), ('.', old_revno), check_clean=False)
362
361
            if stored_loc is None or remember:
363
362
                br_to.set_parent(location)
364
363
        finally:
365
 
            br_from.unlock()
366
364
            rmtree(cache_root)
367
365
 
368
366
 
390
388
        import errno
391
389
        from shutil import rmtree
392
390
        cache_root = tempfile.mkdtemp()
393
 
        if revision is None:
394
 
            revision = [None]
395
 
        elif len(revision) > 1:
396
 
            raise BzrCommandError(
397
 
                'bzr branch --revision takes exactly 1 revision value')
398
 
        try:
399
 
            br_from = Branch.open(from_location)
400
 
        except OSError, e:
401
 
            if e.errno == errno.ENOENT:
402
 
                raise BzrCommandError('Source location "%s" does not'
403
 
                                      ' exist.' % to_location)
404
 
            else:
405
 
                raise
406
 
        br_from.lock_read()
407
 
        try:
 
391
        try:
 
392
            if revision is None:
 
393
                revision = [None]
 
394
            elif len(revision) > 1:
 
395
                raise BzrCommandError(
 
396
                    'bzr branch --revision takes exactly 1 revision value')
 
397
            try:
 
398
                br_from = Branch.open(from_location)
 
399
            except OSError, e:
 
400
                if e.errno == errno.ENOENT:
 
401
                    raise BzrCommandError('Source location "%s" does not'
 
402
                                          ' exist.' % to_location)
 
403
                else:
 
404
                    raise
408
405
            br_from.setup_caching(cache_root)
409
406
            if basis is not None:
410
407
                basis_branch = Branch.open_containing(basis)
436
433
            except bzrlib.errors.UnlistableBranch:
437
434
                msg = "The branch %s cannot be used as a --basis"
438
435
        finally:
439
 
            br_from.unlock()
440
436
            rmtree(cache_root)
441
437
 
442
438
 
443
439
class cmd_renames(Command):
444
440
    """Show list of renamed files.
 
441
 
 
442
    TODO: Option to show renames between two historical versions.
 
443
 
 
444
    TODO: Only show renames under dir, rather than in the whole branch.
445
445
    """
446
 
    # TODO: Option to show renames between two historical versions.
447
 
 
448
 
    # TODO: Only show renames under dir, rather than in the whole branch.
449
446
    takes_args = ['dir?']
450
447
 
451
448
    def run(self, dir='.'):
465
462
    
466
463
    def run(self, branch=None):
467
464
        import info
 
465
 
468
466
        b = Branch.open_containing(branch)
469
467
        info.show_info(b)
470
468
 
569
567
    If files are listed, only the changes in those files are listed.
570
568
    Otherwise, all changes for the tree are listed.
571
569
 
 
570
    TODO: Allow diff across branches.
 
571
 
 
572
    TODO: Option to use external diff command; could be GNU diff, wdiff,
 
573
          or a graphical diff.
 
574
 
 
575
    TODO: Python difflib is not exactly the same as unidiff; should
 
576
          either fix it up or prefer to use an external diff.
 
577
 
 
578
    TODO: If a directory is given, diff everything under that.
 
579
 
 
580
    TODO: Selected-file diff is inefficient and doesn't show you
 
581
          deleted files.
 
582
 
 
583
    TODO: This probably handles non-Unix newlines poorly.
 
584
 
572
585
    examples:
573
586
        bzr diff
574
587
        bzr diff -r1
575
588
        bzr diff -r1..2
576
589
    """
577
 
    # TODO: Allow diff across branches.
578
 
    # TODO: Option to use external diff command; could be GNU diff, wdiff,
579
 
    #       or a graphical diff.
580
 
 
581
 
    # TODO: Python difflib is not exactly the same as unidiff; should
582
 
    #       either fix it up or prefer to use an external diff.
583
 
 
584
 
    # TODO: If a directory is given, diff everything under that.
585
 
 
586
 
    # TODO: Selected-file diff is inefficient and doesn't show you
587
 
    #       deleted files.
588
 
 
589
 
    # TODO: This probably handles non-Unix newlines poorly.
590
590
    
591
591
    takes_args = ['file*']
592
592
    takes_options = ['revision', 'diff-options']
623
623
 
624
624
class cmd_deleted(Command):
625
625
    """List files deleted in the working tree.
 
626
 
 
627
    TODO: Show files deleted since a previous revision, or between two revisions.
626
628
    """
627
 
    # TODO: Show files deleted since a previous revision, or
628
 
    # between two revisions.
629
 
    # TODO: Much more efficient way to do this: read in new
630
 
    # directories with readdir, rather than stating each one.  Same
631
 
    # level of effort but possibly much less IO.  (Or possibly not,
632
 
    # if the directories are very large...)
633
629
    def run(self, show_ids=False):
634
630
        b = Branch.open_containing('.')
635
631
        old = b.basis_tree()
636
632
        new = b.working_tree()
 
633
 
 
634
        ## TODO: Much more efficient way to do this: read in new
 
635
        ## directories with readdir, rather than stating each one.  Same
 
636
        ## level of effort but possibly much less IO.  (Or possibly not,
 
637
        ## if the directories are very large...)
 
638
 
637
639
        for path, ie in old.inventory.iter_entries():
638
640
            if not new.has_id(ie.file_id):
639
641
                if show_ids:
785
787
 
786
788
class cmd_ls(Command):
787
789
    """List files in a tree.
 
790
 
 
791
    TODO: Take a revision or remote path and list that tree instead.
788
792
    """
789
 
    # TODO: Take a revision or remote path and list that tree instead.
790
793
    hidden = True
791
794
    def run(self, revision=None, verbose=False):
792
795
        b = Branch.open_containing('.')
818
821
    To remove patterns from the ignore list, edit the .bzrignore file.
819
822
 
820
823
    If the pattern contains a slash, it is compared to the whole path
821
 
    from the branch root.  Otherwise, it is compared to only the last
822
 
    component of the path.  To match a file only in the root directory,
823
 
    prepend './'.
 
824
    from the branch root.  Otherwise, it is comapred to only the last
 
825
    component of the path.
824
826
 
825
827
    Ignore patterns are case-insensitive on case-insensitive systems.
826
828
 
830
832
        bzr ignore ./Makefile
831
833
        bzr ignore '*.class'
832
834
    """
833
 
    # TODO: Complain if the filename is absolute
834
835
    takes_args = ['name_pattern']
835
836
    
836
837
    def run(self, name_pattern):
983
984
    A selected-file commit may fail in some cases where the committed
984
985
    tree would be invalid, such as trying to commit a file in a
985
986
    newly-added directory that is not itself committed.
 
987
 
 
988
    TODO: Run hooks on tree to-be-committed, and after commit.
 
989
 
 
990
    TODO: Strict commit that fails if there are unknown or deleted files.
986
991
    """
987
 
    # TODO: Run hooks on tree to-be-committed, and after commit.
988
 
 
989
 
    # TODO: Strict commit that fails if there are unknown or deleted files.
990
 
    # TODO: Give better message for -s, --summary, used by tla people
991
 
 
992
 
    # XXX: verbose currently does nothing
993
 
 
994
992
    takes_args = ['selected*']
995
993
    takes_options = ['message', 'file', 'verbose', 'unchanged']
996
994
    aliases = ['ci', 'checkin']
997
995
 
 
996
    # TODO: Give better message for -s, --summary, used by tla people
 
997
 
 
998
    # XXX: verbose currently does nothing
 
999
    
998
1000
    def run(self, message=None, file=None, verbose=True, selected_list=None,
999
1001
            unchanged=False):
1000
1002
        from bzrlib.errors import PointlessCommit, ConflictsInTree
1101
1103
            b = None
1102
1104
        
1103
1105
        if email:
1104
 
            print bzrlib.config.user_email(b)
 
1106
            print bzrlib.osutils.user_email(b)
1105
1107
        else:
1106
 
            print bzrlib.config.username(b)
 
1108
            print bzrlib.osutils.username(b)
1107
1109
 
1108
1110
 
1109
1111
class cmd_selftest(Command):
1118
1120
    which tests should run."""
1119
1121
    # TODO: --list should give a list of all available tests
1120
1122
    hidden = True
1121
 
    takes_args = ['testspecs*']
1122
 
    takes_options = ['verbose']
1123
 
    def run(self, testspecs_list=None, verbose=False):
 
1123
    takes_args = ['testnames*']
 
1124
    takes_options = ['verbose', 'pattern']
 
1125
    def run(self, testnames_list=None, verbose=False, pattern=".*"):
1124
1126
        import bzrlib.ui
1125
1127
        from bzrlib.selftest import selftest
1126
1128
        # we don't want progress meters from the tests to go to the
1130
1132
        bzrlib.trace.info('running tests...')
1131
1133
        try:
1132
1134
            bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1133
 
            if testspecs_list is not None:
1134
 
                pattern = '|'.join(testspecs_list)
1135
 
            else:
1136
 
                pattern = ".*"
1137
1135
            result = selftest(verbose=verbose, 
1138
 
                              pattern=pattern)
 
1136
                              pattern=pattern,
 
1137
                              testnames=testnames_list)
1139
1138
            if result:
1140
1139
                bzrlib.trace.info('tests passed')
1141
1140
            else:
1173
1172
 
1174
1173
class cmd_find_merge_base(Command):
1175
1174
    """Find and print a base revision for merging two branches.
 
1175
 
 
1176
    TODO: Options to specify revisions on either side, as if
 
1177
          merging only part of the history.
1176
1178
    """
1177
 
    # TODO: Options to specify revisions on either side, as if
1178
 
    #       merging only part of the history.
1179
1179
    takes_args = ['branch', 'other']
1180
1180
    hidden = True
1181
1181
    
1420
1420
                print '\t', d.split('\n')[0]
1421
1421
 
1422
1422
 
1423
 
class cmd_testament(Command):
1424
 
    """Show testament (signing-form) of a revision."""
1425
 
    takes_options = ['revision', 'long']
1426
 
    takes_args = ['branch?']
1427
 
    def run(self, branch='.', revision=None, long=False):
1428
 
        from bzrlib.testament import Testament
1429
 
        b = Branch.open_containing(branch)
1430
 
        b.lock_read()
1431
 
        try:
1432
 
            if revision is None:
1433
 
                rev_id = b.last_revision()
1434
 
            else:
1435
 
                rev_id = revision[0].in_history(b).rev_id
1436
 
            t = Testament.from_revision(b, rev_id)
1437
 
            if long:
1438
 
                sys.stdout.writelines(t.as_text_lines())
1439
 
            else:
1440
 
                sys.stdout.write(t.as_short_text())
1441
 
        finally:
1442
 
            b.unlock()
1443
 
 
1444
 
 
1445
 
class cmd_annotate(Command):
1446
 
    """Show the origin of each line in a file.
1447
 
 
1448
 
    This prints out the given file with an annotation on the 
1449
 
    left side indicating which revision, author and date introduced the 
1450
 
    change.
1451
 
    """
1452
 
    # TODO: annotate directories; showing when each file was last changed
1453
 
    # TODO: annotate a previous version of a file
1454
 
    aliases = ['blame', 'praise']
1455
 
    takes_args = ['filename']
1456
 
 
1457
 
    def run(self, filename):
1458
 
        from bzrlib.annotate import annotate_file
1459
 
        b = Branch.open_containing(filename)
1460
 
        b.lock_read()
1461
 
        try:
1462
 
            rp = b.relpath(filename)
1463
 
            tree = b.revision_tree(b.last_revision())
1464
 
            file_id = tree.inventory.path2id(rp)
1465
 
            file_version = tree.inventory[file_id].revision
1466
 
            annotate_file(b, file_version, file_id, sys.stdout)
1467
 
        finally:
1468
 
            b.unlock()
1469
 
 
1470
 
# these get imported and then picked up by the scan for cmd_*
1471
 
# TODO: Some more consistent way to split command definitions across files;
1472
 
# we do need to load at least some information about them to know of 
1473
 
# aliases.
1474
 
from bzrlib.conflicts import cmd_resolve, cmd_conflicts