~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

 * bzr add now lists how many files were ignored per glob.  add --verbose
   lists the specific files.  (Aaron Bentley)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""builtin bzr commands"""
18
18
 
 
19
# DO NOT change this to cStringIO - it results in control files 
 
20
# written as UCS4
 
21
# FIXIT! (Only deal with byte streams OR unicode at any one layer.)
 
22
# RBC 20051018
19
23
 
20
 
import errno
 
24
from StringIO import StringIO
 
25
import sys
21
26
import os
22
 
from shutil import rmtree
23
 
import sys
24
27
 
25
28
import bzrlib
26
 
import bzrlib.branch
 
29
from bzrlib import BZRDIR
 
30
from bzrlib.commands import Command, display_command
27
31
from bzrlib.branch import Branch
28
 
import bzrlib.bzrdir as bzrdir
29
 
from bzrlib.commands import Command, display_command
30
32
from bzrlib.revision import common_ancestor
31
33
import bzrlib.errors as errors
32
34
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError, 
33
35
                           NotBranchError, DivergedBranches, NotConflicted,
34
36
                           NoSuchFile, NoWorkingTree, FileInWrongBranch)
35
 
from bzrlib.log import show_one_log
36
 
from bzrlib.merge import Merge3Merger
37
37
from bzrlib.option import Option
38
 
from bzrlib.progress import DummyProgress
39
38
from bzrlib.revisionspec import RevisionSpec
40
39
import bzrlib.trace
41
40
from bzrlib.trace import mutter, note, log_error, warning, is_quiet
42
 
from bzrlib.transport.local import LocalTransport
43
 
import bzrlib.ui
44
41
from bzrlib.workingtree import WorkingTree
 
42
from bzrlib.log import show_one_log
45
43
 
46
44
 
47
45
def tree_files(file_list, default_branch=u'.'):
125
123
    def run(self, all=False, show_ids=False, file_list=None, revision=None):
126
124
        tree, file_list = tree_files(file_list)
127
125
            
128
 
        from bzrlib.status import show_tree_status
129
 
        show_tree_status(tree, show_unchanged=all, show_ids=show_ids,
130
 
                         specific_files=file_list, revision=revision)
 
126
        from bzrlib.status import show_status
 
127
        show_status(tree.branch, show_unchanged=all, show_ids=show_ids,
 
128
                    specific_files=file_list, revision=revision)
131
129
 
132
130
 
133
131
class cmd_cat_revision(Command):
150
148
            raise BzrCommandError('You must supply either --revision or a revision_id')
151
149
        b = WorkingTree.open_containing(u'.')[0].branch
152
150
        if revision_id is not None:
153
 
            sys.stdout.write(b.repository.get_revision_xml(revision_id))
 
151
            sys.stdout.write(b.get_revision_xml(revision_id))
154
152
        elif revision is not None:
155
153
            for rev in revision:
156
154
                if rev is None:
157
155
                    raise BzrCommandError('You cannot specify a NULL revision.')
158
156
                revno, rev_id = rev.in_history(b)
159
 
                sys.stdout.write(b.repository.get_revision_xml(rev_id))
 
157
                sys.stdout.write(b.get_revision_xml(rev_id))
160
158
    
161
159
 
162
160
class cmd_revno(Command):
300
298
            if len(revision) > 1:
301
299
                raise BzrCommandError('bzr inventory --revision takes'
302
300
                    ' exactly one revision identifier')
303
 
            inv = tree.branch.repository.get_revision_inventory(
 
301
            inv = tree.branch.get_revision_inventory(
304
302
                revision[0].in_history(tree.branch).rev_id)
305
303
 
306
304
        for path, entry in inv.entries():
397
395
    If you want to forget your local changes and just update your branch to
398
396
    match the remote one, use --overwrite.
399
397
    """
400
 
    takes_options = ['remember', 'overwrite', 'revision', 'verbose']
 
398
    takes_options = ['remember', 'overwrite', 'verbose']
401
399
    takes_args = ['location?']
402
400
 
403
 
    def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
 
401
    def run(self, location=None, remember=False, overwrite=False, verbose=False):
 
402
        from bzrlib.merge import merge
 
403
        from shutil import rmtree
 
404
        import errno
404
405
        # FIXME: too much stuff is in the command class        
405
406
        tree_to = WorkingTree.open_containing(u'.')[0]
406
407
        stored_loc = tree_to.branch.get_parent()
414
415
        br_from = Branch.open(location)
415
416
        br_to = tree_to.branch
416
417
 
417
 
        if revision is None:
418
 
            rev_id = None
419
 
        elif len(revision) == 1:
420
 
            rev_id = revision[0].in_history(br_from).rev_id
421
 
        else:
422
 
            raise BzrCommandError('bzr pull --revision takes one value.')
423
 
 
424
418
        old_rh = br_to.revision_history()
425
 
        count = tree_to.pull(br_from, overwrite, rev_id)
 
419
        count = tree_to.pull(br_from, overwrite)
426
420
 
427
421
        if br_to.get_parent() is None or remember:
428
422
            br_to.set_parent(location)
469
463
            create_prefix=False, verbose=False):
470
464
        # FIXME: Way too big!  Put this into a function called from the
471
465
        # command.
 
466
        import errno
 
467
        from shutil import rmtree
472
468
        from bzrlib.transport import get_transport
473
469
        
474
470
        tree_from = WorkingTree.open_containing(u'.')[0]
506
502
                        if new_transport.base == transport.base:
507
503
                            raise BzrCommandError("Could not creeate "
508
504
                                                  "path prefix.")
509
 
            br_to = bzrlib.bzrdir.BzrDir.create_branch_convenience(location)
 
505
            br_to = Branch.initialize(location)
510
506
        old_rh = br_to.revision_history()
511
507
        try:
512
508
            try:
552
548
    aliases = ['get', 'clone']
553
549
 
554
550
    def run(self, from_location, to_location=None, revision=None, basis=None):
 
551
        from bzrlib.clone import copy_branch
 
552
        import errno
 
553
        from shutil import rmtree
555
554
        if revision is None:
556
555
            revision = [None]
557
556
        elif len(revision) > 1:
568
567
        br_from.lock_read()
569
568
        try:
570
569
            if basis is not None:
571
 
                basis_dir = bzrdir.BzrDir.open_containing(basis)[0]
 
570
                basis_branch = WorkingTree.open_containing(basis)[0].branch
572
571
            else:
573
 
                basis_dir = None
 
572
                basis_branch = None
574
573
            if len(revision) == 1 and revision[0] is not None:
575
574
                revision_id = revision[0].in_history(br_from)[1]
576
575
            else:
577
 
                # FIXME - wt.last_revision, fallback to branch, fall back to
578
 
                # None or perhaps NULL_REVISION to mean copy nothing
579
 
                # RBC 20060209
580
 
                revision_id = br_from.last_revision()
 
576
                revision_id = None
581
577
            if to_location is None:
582
578
                to_location = os.path.basename(from_location.rstrip("/\\"))
583
579
                name = None
595
591
                else:
596
592
                    raise
597
593
            try:
598
 
                dir = br_from.bzrdir.sprout(to_location, revision_id, basis_dir)
599
 
                branch = dir.open_branch()
 
594
                copy_branch(br_from, to_location, revision_id, basis_branch)
600
595
            except bzrlib.errors.NoSuchRevision:
601
596
                rmtree(to_location)
602
597
                msg = "The branch %s has no revision %s." % (from_location, revision[0])
605
600
                rmtree(to_location)
606
601
                msg = "The branch %s cannot be used as a --basis"
607
602
                raise BzrCommandError(msg)
 
603
            branch = Branch.open(to_location)
608
604
            if name:
609
 
                branch.control_files.put_utf8('branch-name', name)
610
 
 
 
605
                name = StringIO(name)
 
606
                branch.put_controlfile('branch-name', name)
611
607
            note('Branched %d revision(s).' % branch.revno())
612
608
        finally:
613
609
            br_from.unlock()
614
610
 
615
611
 
616
 
class cmd_checkout(Command):
617
 
    """Create a new checkout of an existing branch.
618
 
 
619
 
    If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
620
 
    be used.  In other words, "checkout ../foo/bar" will attempt to create ./bar.
621
 
 
622
 
    To retrieve the branch as of a particular revision, supply the --revision
623
 
    parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
624
 
    out of date [so you cannot commit] but it may be useful (i.e. to examine old
625
 
    code.)
626
 
 
627
 
    --basis is to speed up checking out from remote branches.  When specified, it
628
 
    uses the inventory and file contents from the basis branch in preference to the
629
 
    branch being checked out. [Not implemented yet.]
630
 
    """
631
 
    takes_args = ['branch_location', 'to_location?']
632
 
    takes_options = ['revision'] # , 'basis']
633
 
 
634
 
    def run(self, branch_location, to_location=None, revision=None, basis=None):
635
 
        if revision is None:
636
 
            revision = [None]
637
 
        elif len(revision) > 1:
638
 
            raise BzrCommandError(
639
 
                'bzr checkout --revision takes exactly 1 revision value')
640
 
        source = Branch.open(branch_location)
641
 
        if len(revision) == 1 and revision[0] is not None:
642
 
            revision_id = revision[0].in_history(source)[1]
643
 
        else:
644
 
            revision_id = None
645
 
        if to_location is None:
646
 
            to_location = os.path.basename(branch_location.rstrip("/\\"))
647
 
        try:
648
 
            os.mkdir(to_location)
649
 
        except OSError, e:
650
 
            if e.errno == errno.EEXIST:
651
 
                raise BzrCommandError('Target directory "%s" already'
652
 
                                      ' exists.' % to_location)
653
 
            if e.errno == errno.ENOENT:
654
 
                raise BzrCommandError('Parent of "%s" does not exist.' %
655
 
                                      to_location)
656
 
            else:
657
 
                raise
658
 
        checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
659
 
        bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
660
 
        checkout.create_workingtree(revision_id)
661
 
 
662
 
 
663
612
class cmd_renames(Command):
664
613
    """Show list of renamed files.
665
614
    """
671
620
    @display_command
672
621
    def run(self, dir=u'.'):
673
622
        tree = WorkingTree.open_containing(dir)[0]
674
 
        old_inv = tree.basis_tree().inventory
 
623
        old_inv = tree.branch.basis_tree().inventory
675
624
        new_inv = tree.read_working_inventory()
676
625
 
677
626
        renames = list(bzrlib.tree.find_renames(old_inv, new_inv))
680
629
            print "%s => %s" % (old_name, new_name)        
681
630
 
682
631
 
683
 
class cmd_update(Command):
684
 
    """Update a tree to have the latest code committed to its branch.
685
 
    
686
 
    This will perform a merge into the working tree, and may generate
687
 
    conflicts. If you have any uncommitted changes, you will still 
688
 
    need to commit them after the update.
689
 
    """
690
 
    takes_args = ['dir?']
691
 
 
692
 
    def run(self, dir='.'):
693
 
        tree = WorkingTree.open_containing(dir)[0]
694
 
        tree.lock_write()
695
 
        try:
696
 
            if tree.last_revision() == tree.branch.last_revision():
697
 
                note("Tree is up to date.")
698
 
                return
699
 
            conflicts = tree.update()
700
 
            note('Updated to revision %d.' %
701
 
                 (tree.branch.revision_id_to_revno(tree.last_revision()),))
702
 
            if conflicts != 0:
703
 
                return 1
704
 
            else:
705
 
                return 0
706
 
        finally:
707
 
            tree.unlock()
708
 
 
709
 
 
710
632
class cmd_info(Command):
711
633
    """Show statistical information about a branch."""
712
634
    takes_args = ['branch?']
713
635
    
714
636
    @display_command
715
637
    def run(self, branch=None):
716
 
        import bzrlib.info
717
 
        bzrlib.info.show_bzrdir_info(bzrdir.BzrDir.open_containing(branch)[0])
 
638
        import info
 
639
        b = WorkingTree.open_containing(branch)[0].branch
 
640
        info.show_info(b)
718
641
 
719
642
 
720
643
class cmd_remove(Command):
787
710
        tree = WorkingTree.open_containing(u'.')[0]
788
711
        b = tree.branch
789
712
        # FIXME. should be tree.last_revision
790
 
        for revision_id in b.repository.get_ancestry(b.last_revision()):
 
713
        for revision_id in b.get_ancestry(b.last_revision()):
791
714
            print revision_id
792
715
 
793
716
 
817
740
            # locations if the user supplies an extended path
818
741
            if not os.path.exists(location):
819
742
                os.mkdir(location)
820
 
        bzrdir.BzrDir.create_standalone_workingtree(location)
 
743
        Branch.initialize(location)
821
744
 
822
745
 
823
746
class cmd_diff(Command):
851
774
 
852
775
    @display_command
853
776
    def run(self, revision=None, file_list=None, diff_options=None):
854
 
        from bzrlib.diff import diff_cmd_helper, show_diff_trees
 
777
        from bzrlib.diff import show_diff
855
778
        try:
856
 
            tree1, file_list = internal_tree_files(file_list)
857
 
            tree2 = None
 
779
            tree, file_list = internal_tree_files(file_list)
858
780
            b = None
859
781
            b2 = None
860
782
        except FileInWrongBranch:
861
783
            if len(file_list) != 2:
862
784
                raise BzrCommandError("Files are in different branches")
863
785
 
864
 
            tree1, file1 = WorkingTree.open_containing(file_list[0])
865
 
            tree2, file2 = WorkingTree.open_containing(file_list[1])
 
786
            b, file1 = Branch.open_containing(file_list[0])
 
787
            b2, file2 = Branch.open_containing(file_list[1])
866
788
            if file1 != "" or file2 != "":
867
789
                # FIXME diff those two files. rbc 20051123
868
790
                raise BzrCommandError("Files are in different branches")
869
791
            file_list = None
870
792
        if revision is not None:
871
 
            if tree2 is not None:
 
793
            if b2 is not None:
872
794
                raise BzrCommandError("Can't specify -r with two branches")
873
 
            if (len(revision) == 1) or (revision[1].spec is None):
874
 
                return diff_cmd_helper(tree1, file_list, diff_options,
875
 
                                       revision[0])
 
795
            if len(revision) == 1:
 
796
                return show_diff(tree.branch, revision[0], specific_files=file_list,
 
797
                                 external_diff_options=diff_options)
876
798
            elif len(revision) == 2:
877
 
                return diff_cmd_helper(tree1, file_list, diff_options,
878
 
                                       revision[0], revision[1])
 
799
                return show_diff(tree.branch, revision[0], specific_files=file_list,
 
800
                                 external_diff_options=diff_options,
 
801
                                 revision2=revision[1])
879
802
            else:
880
803
                raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
881
804
        else:
882
 
            if tree2 is not None:
883
 
                return show_diff_trees(tree1, tree2, sys.stdout, 
884
 
                                       specific_files=file_list,
885
 
                                       external_diff_options=diff_options)
 
805
            if b is not None:
 
806
                return show_diff(b, None, specific_files=file_list,
 
807
                                 external_diff_options=diff_options, b2=b2)
886
808
            else:
887
 
                return diff_cmd_helper(tree1, file_list, diff_options)
 
809
                return show_diff(tree.branch, None, specific_files=file_list,
 
810
                                 external_diff_options=diff_options)
888
811
 
889
812
 
890
813
class cmd_deleted(Command):
899
822
    @display_command
900
823
    def run(self, show_ids=False):
901
824
        tree = WorkingTree.open_containing(u'.')[0]
902
 
        old = tree.basis_tree()
 
825
        old = tree.branch.basis_tree()
903
826
        for path, ie in old.inventory.iter_entries():
904
827
            if not tree.has_id(ie.file_id):
905
828
                if show_ids:
916
839
        from bzrlib.delta import compare_trees
917
840
 
918
841
        tree = WorkingTree.open_containing(u'.')[0]
919
 
        td = compare_trees(tree.basis_tree(), tree)
 
842
        td = compare_trees(tree.branch.basis_tree(), tree)
920
843
 
921
844
        for path, id, kind, text_modified, meta_modified in td.modified:
922
845
            print path
929
852
    @display_command
930
853
    def run(self):
931
854
        wt = WorkingTree.open_containing(u'.')[0]
932
 
        basis_inv = wt.basis_tree().inventory
 
855
        basis_inv = wt.branch.basis_tree().inventory
933
856
        inv = wt.inventory
934
857
        for file_id in inv:
935
858
            if file_id in basis_inv:
936
859
                continue
937
860
            path = inv.id2path(file_id)
938
 
            if not os.access(bzrlib.osutils.abspath(path), os.F_OK):
 
861
            if not os.access(b.abspath(path), os.F_OK):
939
862
                continue
940
863
            print path
941
864
                
969
892
                            help='show from oldest to newest'),
970
893
                     'timezone', 'verbose', 
971
894
                     'show-ids', 'revision',
972
 
                     'log-format',
973
895
                     'line', 'long', 
974
896
                     Option('message',
975
897
                            help='show revisions whose message matches this regexp',
982
904
            show_ids=False,
983
905
            forward=False,
984
906
            revision=None,
985
 
            log_format=None,
986
907
            message=None,
987
908
            long=False,
988
909
            short=False,
993
914
            "invalid message argument %r" % message
994
915
        direction = (forward and 'forward') or 'reverse'
995
916
        
996
 
        # log everything
997
 
        file_id = None
998
917
        if filename:
999
 
            # find the file id to log:
1000
 
 
1001
 
            dir, fp = bzrdir.BzrDir.open_containing(filename)
1002
 
            b = dir.open_branch()
 
918
            # might be a tree:
 
919
            tree = None
 
920
            try:
 
921
                tree, fp = WorkingTree.open_containing(filename)
 
922
                b = tree.branch
 
923
                if fp != '':
 
924
                    inv = tree.read_working_inventory()
 
925
            except NotBranchError:
 
926
                pass
 
927
            if tree is None:
 
928
                b, fp = Branch.open_containing(filename)
 
929
                if fp != '':
 
930
                    inv = b.get_inventory(b.last_revision())
1003
931
            if fp != '':
1004
 
                try:
1005
 
                    # might be a tree:
1006
 
                    inv = dir.open_workingtree().inventory
1007
 
                except (errors.NotBranchError, errors.NotLocalUrl):
1008
 
                    # either no tree, or is remote.
1009
 
                    inv = b.basis_tree().inventory
1010
932
                file_id = inv.path2id(fp)
 
933
            else:
 
934
                file_id = None  # points to branch root
1011
935
        else:
1012
 
            # local dir only
1013
 
            # FIXME ? log the current subdir only RBC 20060203 
1014
 
            dir, relpath = bzrdir.BzrDir.open_containing('.')
1015
 
            b = dir.open_branch()
 
936
            tree, relpath = WorkingTree.open_containing(u'.')
 
937
            b = tree.branch
 
938
            file_id = None
1016
939
 
1017
940
        if revision is None:
1018
941
            rev1 = None
1020
943
        elif len(revision) == 1:
1021
944
            rev1 = rev2 = revision[0].in_history(b).revno
1022
945
        elif len(revision) == 2:
1023
 
            if revision[0].spec is None:
1024
 
                # missing begin-range means first revision
1025
 
                rev1 = 1
1026
 
            else:
1027
 
                rev1 = revision[0].in_history(b).revno
1028
 
 
1029
 
            if revision[1].spec is None:
1030
 
                # missing end-range means last known revision
1031
 
                rev2 = b.revno()
1032
 
            else:
1033
 
                rev2 = revision[1].in_history(b).revno
 
946
            rev1 = revision[0].in_history(b).revno
 
947
            rev2 = revision[1].in_history(b).revno
1034
948
        else:
1035
949
            raise BzrCommandError('bzr log --revision takes one or two values.')
1036
950
 
1046
960
        # in e.g. the default C locale.
1047
961
        outf = codecs.getwriter(bzrlib.user_encoding)(sys.stdout, errors='replace')
1048
962
 
1049
 
        if (log_format == None):
1050
 
            default = bzrlib.config.BranchConfig(b).log_format()
1051
 
            log_format = get_log_format(long=long, short=short, line=line, default=default)
1052
 
 
 
963
        log_format = get_log_format(long=long, short=short, line=line)
1053
964
        lf = log_formatter(log_format,
1054
965
                           show_ids=show_ids,
1055
966
                           to_file=outf,
1064
975
                 end_revision=rev2,
1065
976
                 search=message)
1066
977
 
1067
 
 
1068
978
def get_log_format(long=False, short=False, line=False, default='long'):
1069
979
    log_format = default
1070
980
    if long:
1126
1036
        elif relpath:
1127
1037
            relpath += '/'
1128
1038
        if revision is not None:
1129
 
            tree = tree.branch.repository.revision_tree(
 
1039
            tree = tree.branch.revision_tree(
1130
1040
                revision[0].in_history(tree.branch).rev_id)
1131
1041
        for fp, fc, kind, fid, entry in tree.list_files():
1132
1042
            if fp.startswith(relpath):
1262
1172
 
1263
1173
    Note: export of tree with non-ascii filenames to zip is not supported.
1264
1174
 
1265
 
     Supported formats       Autodetected by extension
1266
 
     -----------------       -------------------------
 
1175
    Supported formats       Autodetected by extension
 
1176
    -----------------       -------------------------
1267
1177
         dir                            -
1268
1178
         tar                          .tar
1269
1179
         tbz2                    .tar.bz2, .tbz2
1284
1194
            if len(revision) != 1:
1285
1195
                raise BzrError('bzr export --revision takes exactly 1 argument')
1286
1196
            rev_id = revision[0].in_history(b).rev_id
1287
 
        t = b.repository.revision_tree(rev_id)
 
1197
        t = b.revision_tree(rev_id)
1288
1198
        try:
1289
1199
            export(t, dest, format, root)
1290
1200
        except errors.NoSuchExportFormat, e:
1367
1277
                StrictCommitFailed)
1368
1278
        from bzrlib.msgeditor import edit_commit_message, \
1369
1279
                make_commit_message_template
 
1280
        from bzrlib.status import show_status
1370
1281
        from tempfile import TemporaryFile
1371
1282
        import codecs
1372
1283
 
1448
1359
 
1449
1360
        if c.needs_write:
1450
1361
            c.write()
1451
 
 
1452
 
 
1453
 
def get_format_type(typestring):
1454
 
    """Parse and return a format specifier."""
1455
 
    if typestring == "metadir":
1456
 
        return bzrdir.BzrDirMetaFormat1()
1457
 
    if typestring == "knit":
1458
 
        format = bzrdir.BzrDirMetaFormat1()
1459
 
        format.repository_format = bzrlib.repository.RepositoryFormatKnit1()
1460
 
        return format
1461
 
    msg = "No known bzr-dir format %s. Supported types are: metadir\n" %\
1462
 
        (typestring)
1463
 
    raise BzrCommandError(msg)
 
1362
            
1464
1363
 
1465
1364
 
1466
1365
class cmd_upgrade(Command):
1467
1366
    """Upgrade branch storage to current format.
1468
1367
 
1469
1368
    The check command or bzr developers may sometimes advise you to run
1470
 
    this command. When the default format has changed you may also be warned
1471
 
    during other operations to upgrade.
 
1369
    this command.
 
1370
 
 
1371
    This version of this command upgrades from the full-text storage
 
1372
    used by bzr 0.0.8 and earlier to the weave format (v5).
1472
1373
    """
1473
 
    takes_args = ['url?']
1474
 
    takes_options = [
1475
 
                     Option('format', 
1476
 
                            help='Upgrade to a specific format rather than the'
1477
 
                                 ' current default format. Currently this '
1478
 
                                 ' option only accepts =metadir',
1479
 
                            type=get_format_type),
1480
 
                    ]
1481
 
 
1482
 
 
1483
 
    def run(self, url='.', format=None):
 
1374
    takes_args = ['dir?']
 
1375
 
 
1376
    def run(self, dir=u'.'):
1484
1377
        from bzrlib.upgrade import upgrade
1485
 
        upgrade(url, format)
 
1378
        upgrade(dir)
1486
1379
 
1487
1380
 
1488
1381
class cmd_whoami(Command):
1502
1395
        else:
1503
1396
            print config.username()
1504
1397
 
1505
 
 
1506
1398
class cmd_nick(Command):
1507
 
    """Print or set the branch nickname.  
1508
 
 
 
1399
    """\
 
1400
    Print or set the branch nickname.  
1509
1401
    If unset, the tree root directory name is used as the nickname
1510
1402
    To print the current nickname, execute with no argument.  
1511
1403
    """
1521
1413
    def printme(self, branch):
1522
1414
        print branch.nick 
1523
1415
 
1524
 
 
1525
1416
class cmd_selftest(Command):
1526
1417
    """Run internal test suite.
1527
1418
    
1532
1423
    
1533
1424
    If arguments are given, they are regular expressions that say
1534
1425
    which tests should run.
1535
 
 
1536
 
    If the global option '--no-plugins' is given, plugins are not loaded
1537
 
    before running the selftests.  This has two effects: features provided or
1538
 
    modified by plugins will not be tested, and tests provided by plugins will
1539
 
    not be run.
1540
 
 
1541
 
    examples:
1542
 
        bzr selftest ignore
1543
 
        bzr --no-plugins selftest -v
1544
1426
    """
1545
1427
    # TODO: --list should give a list of all available tests
1546
 
 
1547
 
    # NB: this is used from the class without creating an instance, which is
1548
 
    # why it does not have a self parameter.
1549
 
    def get_transport_type(typestring):
1550
 
        """Parse and return a transport specifier."""
1551
 
        if typestring == "sftp":
1552
 
            from bzrlib.transport.sftp import SFTPAbsoluteServer
1553
 
            return SFTPAbsoluteServer
1554
 
        if typestring == "memory":
1555
 
            from bzrlib.transport.memory import MemoryServer
1556
 
            return MemoryServer
1557
 
        msg = "No known transport type %s. Supported types are: sftp\n" %\
1558
 
            (typestring)
1559
 
        raise BzrCommandError(msg)
1560
 
 
1561
1428
    hidden = True
1562
1429
    takes_args = ['testspecs*']
1563
 
    takes_options = ['verbose',
 
1430
    takes_options = ['verbose', 
1564
1431
                     Option('one', help='stop when one test fails'),
1565
1432
                     Option('keep-output', 
1566
 
                            help='keep output directories when tests fail'),
1567
 
                     Option('transport', 
1568
 
                            help='Use a different transport by default '
1569
 
                                 'throughout the test suite.',
1570
 
                            type=get_transport_type),
 
1433
                            help='keep output directories when tests fail')
1571
1434
                    ]
1572
1435
 
1573
1436
    def run(self, testspecs_list=None, verbose=False, one=False,
1574
 
            keep_output=False, transport=None):
 
1437
            keep_output=False):
1575
1438
        import bzrlib.ui
1576
1439
        from bzrlib.tests import selftest
1577
1440
        # we don't want progress meters from the tests to go to the
1588
1451
            result = selftest(verbose=verbose, 
1589
1452
                              pattern=pattern,
1590
1453
                              stop_on_failure=one, 
1591
 
                              keep_output=keep_output,
1592
 
                              transport=transport)
 
1454
                              keep_output=keep_output)
1593
1455
            if result:
1594
1456
                bzrlib.trace.info('tests passed')
1595
1457
            else:
1599
1461
            bzrlib.ui.ui_factory = save_ui
1600
1462
 
1601
1463
 
1602
 
def _get_bzr_branch():
1603
 
    """If bzr is run from a branch, return Branch or None"""
1604
 
    import bzrlib.errors
1605
 
    from bzrlib.branch import Branch
1606
 
    from bzrlib.osutils import abspath
1607
 
    from os.path import dirname
1608
 
    
1609
 
    try:
1610
 
        branch = Branch.open(dirname(abspath(dirname(__file__))))
1611
 
        return branch
1612
 
    except bzrlib.errors.BzrError:
1613
 
        return None
1614
 
    
1615
 
 
1616
1464
def show_version():
1617
1465
    print "bzr (bazaar-ng) %s" % bzrlib.__version__
1618
1466
    # is bzrlib itself in a branch?
1619
 
    branch = _get_bzr_branch()
1620
 
    if branch:
1621
 
        rh = branch.revision_history()
1622
 
        revno = len(rh)
1623
 
        print "  bzr checkout, revision %d" % (revno,)
1624
 
        print "  nick: %s" % (branch.nick,)
1625
 
        if rh:
1626
 
            print "  revid: %s" % (rh[-1],)
 
1467
    bzrrev = bzrlib.get_bzr_revision()
 
1468
    if bzrrev:
 
1469
        print "  (bzr checkout, revision %d {%s})" % bzrrev
1627
1470
    print bzrlib.__copyright__
1628
1471
    print "http://bazaar-ng.org/"
1629
1472
    print
1667
1510
        last1 = branch1.last_revision()
1668
1511
        last2 = branch2.last_revision()
1669
1512
 
1670
 
        source = MultipleRevisionSources(branch1.repository, 
1671
 
                                         branch2.repository)
 
1513
        source = MultipleRevisionSources(branch1, branch2)
1672
1514
        
1673
1515
        base_rev_id = common_ancestor(last1, last2, source)
1674
1516
 
1721
1563
 
1722
1564
    def run(self, branch=None, revision=None, force=False, merge_type=None,
1723
1565
            show_base=False, reprocess=False):
 
1566
        from bzrlib.merge import merge
 
1567
        from bzrlib.merge_core import ApplyMerge3
1724
1568
        if merge_type is None:
1725
 
            merge_type = Merge3Merger
 
1569
            merge_type = ApplyMerge3
1726
1570
        if branch is None:
1727
1571
            branch = WorkingTree.open_containing(u'.')[0].branch.get_parent()
1728
1572
            if branch is None:
1751
1595
        try:
1752
1596
            conflict_count = merge(other, base, check_clean=(not force),
1753
1597
                                   merge_type=merge_type, reprocess=reprocess,
1754
 
                                   show_base=show_base, 
1755
 
                                   pb=bzrlib.ui.ui_factory.progress_bar())
 
1598
                                   show_base=show_base)
1756
1599
            if conflict_count != 0:
1757
1600
                return 1
1758
1601
            else:
1778
1621
    def run(self, file_list=None, merge_type=None, show_base=False,
1779
1622
            reprocess=False):
1780
1623
        from bzrlib.merge import merge_inner, transform_tree
 
1624
        from bzrlib.merge_core import ApplyMerge3
1781
1625
        if merge_type is None:
1782
 
            merge_type = Merge3Merger
 
1626
            merge_type = ApplyMerge3
1783
1627
        tree, file_list = tree_files(file_list)
1784
1628
        tree.lock_write()
1785
1629
        try:
1788
1632
                raise BzrCommandError("Sorry, remerge only works after normal"
1789
1633
                                      + " merges.  Not cherrypicking or"
1790
1634
                                      + "multi-merges.")
1791
 
            repository = tree.branch.repository
1792
1635
            base_revision = common_ancestor(tree.branch.last_revision(), 
1793
 
                                            pending_merges[0], repository)
1794
 
            base_tree = repository.revision_tree(base_revision)
1795
 
            other_tree = repository.revision_tree(pending_merges[0])
 
1636
                                            pending_merges[0], tree.branch)
 
1637
            base_tree = tree.branch.revision_tree(base_revision)
 
1638
            other_tree = tree.branch.revision_tree(pending_merges[0])
1796
1639
            interesting_ids = None
1797
1640
            if file_list is not None:
1798
1641
                interesting_ids = set()
1804
1647
                    
1805
1648
                    for name, ie in tree.inventory.iter_entries(file_id):
1806
1649
                        interesting_ids.add(ie.file_id)
1807
 
            transform_tree(tree, tree.basis_tree(), interesting_ids)
 
1650
            transform_tree(tree, tree.branch.basis_tree(), interesting_ids)
1808
1651
            if file_list is None:
1809
1652
                restore_files = list(tree.iter_conflicts())
1810
1653
            else:
1839
1682
    aliases = ['merge-revert']
1840
1683
 
1841
1684
    def run(self, revision=None, no_backup=False, file_list=None):
 
1685
        from bzrlib.merge import merge_inner
1842
1686
        from bzrlib.commands import parse_spec
1843
1687
        if file_list is not None:
1844
1688
            if len(file_list) == 0:
1845
1689
                raise BzrCommandError("No files specified")
1846
1690
        else:
1847
1691
            file_list = []
1848
 
        
1849
 
        tree, file_list = tree_files(file_list)
1850
1692
        if revision is None:
 
1693
            revno = -1
 
1694
            tree = WorkingTree.open_containing(u'.')[0]
1851
1695
            # FIXME should be tree.last_revision
1852
1696
            rev_id = tree.branch.last_revision()
1853
1697
        elif len(revision) != 1:
1854
1698
            raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
1855
1699
        else:
 
1700
            tree, file_list = tree_files(file_list)
1856
1701
            rev_id = revision[0].in_history(tree.branch).rev_id
1857
 
        tree.revert(file_list, tree.branch.repository.revision_tree(rev_id),
1858
 
                    not no_backup, bzrlib.ui.ui_factory.progress_bar())
 
1702
        tree.revert(file_list, tree.branch.revision_tree(rev_id),
 
1703
                                not no_backup)
1859
1704
 
1860
1705
 
1861
1706
class cmd_assert_fail(Command):
1869
1714
    """Show help on a command or other topic.
1870
1715
 
1871
1716
    For a list of all available commands, say 'bzr help commands'."""
1872
 
    takes_options = [Option('long', 'show help on all commands')]
 
1717
    takes_options = ['long']
1873
1718
    takes_args = ['topic?']
1874
1719
    aliases = ['?']
1875
1720
    
1906
1751
        from bzrlib.branch import Branch
1907
1752
        from_b = Branch.open(from_branch)
1908
1753
        to_b = Branch.open(to_branch)
1909
 
        Fetcher(to_b, from_b)
 
1754
        from_b.lock_read()
 
1755
        try:
 
1756
            to_b.lock_write()
 
1757
            try:
 
1758
                Fetcher(to_b, from_b)
 
1759
            finally:
 
1760
                to_b.unlock()
 
1761
        finally:
 
1762
            from_b.unlock()
1910
1763
 
1911
1764
 
1912
1765
class cmd_missing(Command):
1919
1772
                            'Display changes in the local branch only'),
1920
1773
                     Option('theirs-only', 
1921
1774
                            'Display changes in the remote branch only'), 
1922
 
                     'log-format',
1923
1775
                     'line',
1924
1776
                     'long', 
1925
1777
                     'short',
1928
1780
                     ]
1929
1781
 
1930
1782
    def run(self, other_branch=None, reverse=False, mine_only=False,
1931
 
            theirs_only=False, log_format=None, long=False, short=False, line=False, 
 
1783
            theirs_only=False, long=True, short=False, line=False, 
1932
1784
            show_ids=False, verbose=False):
1933
1785
        from bzrlib.missing import find_unmerged, iter_log_data
1934
1786
        from bzrlib.log import log_formatter
1941
1793
            print "Using last location: " + local_branch.get_parent()
1942
1794
        remote_branch = bzrlib.branch.Branch.open(other_branch)
1943
1795
        local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
1944
 
        if (log_format == None):
1945
 
            default = bzrlib.config.BranchConfig(local_branch).log_format()
1946
 
            log_format = get_log_format(long=long, short=short, line=line, default=default)
 
1796
        log_format = get_log_format(long=long, short=short, line=line)
1947
1797
        lf = log_formatter(log_format, sys.stdout,
1948
1798
                           show_ids=show_ids,
1949
1799
                           show_timezone='original')
1952
1802
            remote_extra.reverse()
1953
1803
        if local_extra and not theirs_only:
1954
1804
            print "You have %d extra revision(s):" % len(local_extra)
1955
 
            for data in iter_log_data(local_extra, local_branch.repository,
1956
 
                                      verbose):
 
1805
            for data in iter_log_data(local_extra, local_branch, verbose):
1957
1806
                lf.show(*data)
1958
1807
            printed_local = True
1959
1808
        else:
1962
1811
            if printed_local is True:
1963
1812
                print "\n\n"
1964
1813
            print "You are missing %d revision(s):" % len(remote_extra)
1965
 
            for data in iter_log_data(remote_extra, remote_branch.repository, 
1966
 
                                      verbose):
 
1814
            for data in iter_log_data(remote_extra, remote_branch, verbose):
1967
1815
                lf.show(*data)
1968
1816
        if not remote_extra and not local_extra:
1969
1817
            status_code = 0
2009
1857
                rev_id = b.last_revision()
2010
1858
            else:
2011
1859
                rev_id = revision[0].in_history(b).rev_id
2012
 
            t = Testament.from_revision(b.repository, rev_id)
 
1860
            t = Testament.from_revision(b, rev_id)
2013
1861
            if long:
2014
1862
                sys.stdout.writelines(t.as_text_lines())
2015
1863
            else:
2045
1893
        branch.lock_read()
2046
1894
        try:
2047
1895
            file_id = tree.inventory.path2id(relpath)
2048
 
            tree = branch.repository.revision_tree(branch.last_revision())
 
1896
            tree = branch.revision_tree(branch.last_revision())
2049
1897
            file_version = tree.inventory[file_id].revision
2050
1898
            annotate_file(branch, file_version, file_id, long, all, sys.stdout)
2051
1899
        finally:
2057
1905
    # TODO be able to replace existing ones.
2058
1906
 
2059
1907
    hidden = True # is this right ?
2060
 
    takes_args = ['revision_id*']
 
1908
    takes_args = ['revision_id?']
2061
1909
    takes_options = ['revision']
2062
1910
    
2063
 
    def run(self, revision_id_list=None, revision=None):
 
1911
    def run(self, revision_id=None, revision=None):
2064
1912
        import bzrlib.config as config
2065
1913
        import bzrlib.gpg as gpg
2066
 
        if revision_id_list is not None and revision is not None:
 
1914
        if revision_id is not None and revision is not None:
2067
1915
            raise BzrCommandError('You can only supply one of revision_id or --revision')
2068
 
        if revision_id_list is None and revision is None:
 
1916
        if revision_id is None and revision is None:
2069
1917
            raise BzrCommandError('You must supply either --revision or a revision_id')
2070
1918
        b = WorkingTree.open_containing(u'.')[0].branch
2071
1919
        gpg_strategy = gpg.GPGStrategy(config.BranchConfig(b))
2072
 
        if revision_id_list is not None:
2073
 
            for revision_id in revision_id_list:
2074
 
                b.repository.sign_revision(revision_id, gpg_strategy)
 
1920
        if revision_id is not None:
 
1921
            b.sign_revision(revision_id, gpg_strategy)
2075
1922
        elif revision is not None:
2076
1923
            if len(revision) == 1:
2077
1924
                revno, rev_id = revision[0].in_history(b)
2078
 
                b.repository.sign_revision(rev_id, gpg_strategy)
 
1925
                b.sign_revision(rev_id, gpg_strategy)
2079
1926
            elif len(revision) == 2:
2080
1927
                # are they both on rh- if so we can walk between them
2081
1928
                # might be nice to have a range helper for arbitrary
2087
1934
                if from_revno is None or to_revno is None:
2088
1935
                    raise BzrCommandError('Cannot sign a range of non-revision-history revisions')
2089
1936
                for revno in range(from_revno, to_revno + 1):
2090
 
                    b.repository.sign_revision(b.get_rev_id(revno), 
2091
 
                                               gpg_strategy)
 
1937
                    b.sign_revision(b.get_rev_id(revno), gpg_strategy)
2092
1938
            else:
2093
1939
                raise BzrCommandError('Please supply either one revision, or a range.')
2094
1940
 
2106
1952
    
2107
1953
    In the future, uncommit will create a changeset, which can then
2108
1954
    be re-applied.
2109
 
 
2110
 
    TODO: jam 20060108 Add an option to allow uncommit to remove unreferenced
2111
 
              information in 'branch-as-repostory' branches.
2112
 
    TODO: jam 20060108 Add the ability for uncommit to remove unreferenced
2113
 
              information in shared branches as well.
2114
1955
    """
2115
 
    takes_options = ['verbose', 'revision',
 
1956
    takes_options = ['all', 'verbose', 'revision',
2116
1957
                    Option('dry-run', help='Don\'t actually make changes'),
2117
1958
                    Option('force', help='Say yes to all questions.')]
2118
1959
    takes_args = ['location?']
2119
1960
    aliases = []
2120
1961
 
2121
 
    def run(self, location=None, 
 
1962
    def run(self, location=None, all=False,
2122
1963
            dry_run=False, verbose=False,
2123
1964
            revision=None, force=False):
2124
1965
        from bzrlib.branch import Branch
2128
1969
 
2129
1970
        if location is None:
2130
1971
            location = u'.'
2131
 
        control, relpath = bzrdir.BzrDir.open_containing(location)
2132
 
        b = control.open_branch()
2133
 
        try:
2134
 
            tree = control.open_workingtree()
2135
 
        except (errors.NoWorkingTree, errors.NotLocalUrl):
2136
 
            tree = None
 
1972
        b, relpath = Branch.open_containing(location)
2137
1973
 
2138
1974
        if revision is None:
2139
1975
            revno = b.revno()
2146
1982
        for r in range(revno, b.revno()+1):
2147
1983
            rev_id = b.get_rev_id(r)
2148
1984
            lf = log_formatter('short', to_file=sys.stdout,show_timezone='original')
2149
 
            lf.show(r, b.repository.get_revision(rev_id), None)
 
1985
            lf.show(r, b.get_revision(rev_id), None)
2150
1986
 
2151
1987
        if dry_run:
2152
1988
            print 'Dry-run, pretending to remove the above revisions.'
2160
1996
                    print 'Canceled'
2161
1997
                    return 0
2162
1998
 
2163
 
        uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
 
1999
        uncommit(b, remove_files=all,
 
2000
                dry_run=dry_run, verbose=verbose,
2164
2001
                revno=revno)
2165
2002
 
2166
2003
 
2167
 
def merge(other_revision, base_revision,
2168
 
          check_clean=True, ignore_zero=False,
2169
 
          this_dir=None, backup_files=False, merge_type=Merge3Merger,
2170
 
          file_list=None, show_base=False, reprocess=False, 
2171
 
          pb=DummyProgress()):
2172
 
    """Merge changes into a tree.
2173
 
 
2174
 
    base_revision
2175
 
        list(path, revno) Base for three-way merge.  
2176
 
        If [None, None] then a base will be automatically determined.
2177
 
    other_revision
2178
 
        list(path, revno) Other revision for three-way merge.
2179
 
    this_dir
2180
 
        Directory to merge changes into; '.' by default.
2181
 
    check_clean
2182
 
        If true, this_dir must have no uncommitted changes before the
2183
 
        merge begins.
2184
 
    ignore_zero - If true, suppress the "zero conflicts" message when 
2185
 
        there are no conflicts; should be set when doing something we expect
2186
 
        to complete perfectly.
2187
 
    file_list - If supplied, merge only changes to selected files.
2188
 
 
2189
 
    All available ancestors of other_revision and base_revision are
2190
 
    automatically pulled into the branch.
2191
 
 
2192
 
    The revno may be -1 to indicate the last revision on the branch, which is
2193
 
    the typical case.
2194
 
 
2195
 
    This function is intended for use from the command line; programmatic
2196
 
    clients might prefer to call merge.merge_inner(), which has less magic 
2197
 
    behavior.
2198
 
    """
2199
 
    from bzrlib.merge import Merger
2200
 
    if this_dir is None:
2201
 
        this_dir = u'.'
2202
 
    this_tree = WorkingTree.open_containing(this_dir)[0]
2203
 
    if show_base and not merge_type is Merge3Merger:
2204
 
        raise BzrCommandError("Show-base is not supported for this merge"
2205
 
                              " type. %s" % merge_type)
2206
 
    if reprocess and not merge_type is Merge3Merger:
2207
 
        raise BzrCommandError("Reprocess is not supported for this merge"
2208
 
                              " type. %s" % merge_type)
2209
 
    if reprocess and show_base:
2210
 
        raise BzrCommandError("Cannot reprocess and show base.")
2211
 
    merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
2212
 
    merger.check_basis(check_clean)
2213
 
    merger.set_other(other_revision)
2214
 
    merger.set_base(base_revision)
2215
 
    if merger.base_rev_id == merger.other_rev_id:
2216
 
        note('Nothing to do.')
2217
 
        return 0
2218
 
    merger.backup_files = backup_files
2219
 
    merger.merge_type = merge_type 
2220
 
    merger.set_interesting_files(file_list)
2221
 
    merger.show_base = show_base 
2222
 
    merger.reprocess = reprocess
2223
 
    conflicts = merger.do_merge()
2224
 
    merger.set_pending()
2225
 
    return conflicts
2226
 
 
2227
 
 
2228
2004
# these get imported and then picked up by the scan for cmd_*
2229
2005
# TODO: Some more consistent way to split command definitions across files;
2230
2006
# we do need to load at least some information about them to know of 
2231
2007
# aliases.
2232
2008
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
2233
 
from bzrlib.sign_my_commits import cmd_sign_my_commits