~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: John Arbash Meinel
  • Date: 2006-10-16 01:25:46 UTC
  • mfrom: (2071 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2080.
  • Revision ID: john@arbash-meinel.com-20061016012546-d01a0740671b4d73
[merge] bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""builtin bzr commands"""
18
18
 
 
19
import os
19
20
 
 
21
from bzrlib.lazy_import import lazy_import
 
22
lazy_import(globals(), """
20
23
import codecs
21
24
import errno
22
 
import os
23
 
import os.path
24
25
import sys
25
26
 
26
27
import bzrlib
32
33
    errors,
33
34
    ignores,
34
35
    log,
 
36
    merge as _mod_merge,
35
37
    osutils,
36
38
    repository,
37
39
    transport,
 
40
    tree as _mod_tree,
38
41
    ui,
39
42
    urlutils,
40
43
    )
41
 
from bzrlib.branch import Branch, BranchReferenceFormat
42
 
from bzrlib.bundle import read_bundle_from_url
 
44
from bzrlib.branch import Branch
43
45
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
44
46
from bzrlib.conflicts import ConflictList
 
47
from bzrlib.revision import common_ancestor
 
48
from bzrlib.revisionspec import RevisionSpec
 
49
from bzrlib.workingtree import WorkingTree
 
50
""")
 
51
 
45
52
from bzrlib.commands import Command, display_command
46
 
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError, 
47
 
                           NotBranchError, DivergedBranches, NotConflicted,
48
 
                           NoSuchFile, NoWorkingTree, FileInWrongBranch,
49
 
                           NotVersionedError, NotABundle)
50
 
from bzrlib.merge import Merge3Merger
51
53
from bzrlib.option import Option
52
54
from bzrlib.progress import DummyProgress, ProgressPhase
53
 
from bzrlib.revision import common_ancestor
54
 
from bzrlib.revisionspec import RevisionSpec
55
55
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
56
 
from bzrlib.transport.local import LocalTransport
57
 
import bzrlib.tree
58
 
from bzrlib.workingtree import WorkingTree
59
56
 
60
57
 
61
58
def tree_files(file_list, default_branch=u'.'):
62
59
    try:
63
60
        return internal_tree_files(file_list, default_branch)
64
 
    except FileInWrongBranch, e:
65
 
        raise BzrCommandError("%s is not in the same branch as %s" %
66
 
                             (e.path, file_list[0]))
 
61
    except errors.FileInWrongBranch, e:
 
62
        raise errors.BzrCommandError("%s is not in the same branch as %s" %
 
63
                                     (e.path, file_list[0]))
67
64
 
68
65
 
69
66
# XXX: Bad function name; should possibly also be a class method of
90
87
        try:
91
88
            new_list.append(tree.relpath(filename))
92
89
        except errors.PathNotChild:
93
 
            raise FileInWrongBranch(tree.branch, filename)
 
90
            raise errors.FileInWrongBranch(tree.branch, filename)
94
91
    return tree, new_list
95
92
 
96
93
 
114
111
        return format
115
112
    msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
116
113
          "metaweave and weave" % typestring
117
 
    raise BzrCommandError(msg)
 
114
    raise errors.BzrCommandError(msg)
118
115
 
119
116
 
120
117
# TODO: Make sure no commands unconditionally use the working directory as a
195
192
    def run(self, revision_id=None, revision=None):
196
193
 
197
194
        if revision_id is not None and revision is not None:
198
 
            raise BzrCommandError('You can only supply one of revision_id or --revision')
 
195
            raise errors.BzrCommandError('You can only supply one of'
 
196
                                         ' revision_id or --revision')
199
197
        if revision_id is None and revision is None:
200
 
            raise BzrCommandError('You must supply either --revision or a revision_id')
 
198
            raise errors.BzrCommandError('You must supply either'
 
199
                                         ' --revision or a revision_id')
201
200
        b = WorkingTree.open_containing(u'.')[0].branch
202
201
 
203
202
        # TODO: jam 20060112 should cat-revision always output utf-8?
206
205
        elif revision is not None:
207
206
            for rev in revision:
208
207
                if rev is None:
209
 
                    raise BzrCommandError('You cannot specify a NULL revision.')
 
208
                    raise errors.BzrCommandError('You cannot specify a NULL'
 
209
                                                 ' revision.')
210
210
                revno, rev_id = rev.in_history(b)
211
211
                self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
212
212
    
242
242
            for rev in revision_info_list:
243
243
                revs.append(RevisionSpec.from_string(rev))
244
244
        if len(revs) == 0:
245
 
            raise BzrCommandError('You must supply a revision identifier')
 
245
            raise errors.BzrCommandError('You must supply a revision identifier')
246
246
 
247
247
        b = WorkingTree.open_containing(u'.')[0].branch
248
248
 
299
299
                base_tree, base_path = WorkingTree.open_containing(
300
300
                                            file_ids_from)
301
301
            except errors.NoWorkingTree:
302
 
                base_branch, base_path = branch.Branch.open_containing(
 
302
                base_branch, base_path = Branch.open_containing(
303
303
                                            file_ids_from)
304
304
                base_tree = base_branch.basis_tree()
305
305
 
374
374
    @display_command
375
375
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
376
376
        if kind and kind not in ['file', 'directory', 'symlink']:
377
 
            raise BzrCommandError('invalid kind specified')
 
377
            raise errors.BzrCommandError('invalid kind specified')
378
378
 
379
379
        work_tree, file_list = tree_files(file_list)
380
380
 
381
381
        if revision is not None:
382
382
            if len(revision) > 1:
383
 
                raise BzrCommandError('bzr inventory --revision takes'
384
 
                                      ' exactly one revision identifier')
 
383
                raise errors.BzrCommandError('bzr inventory --revision takes'
 
384
                                             ' exactly one revision identifier')
385
385
            revision_id = revision[0].in_history(work_tree.branch).rev_id
386
386
            tree = work_tree.branch.repository.revision_tree(revision_id)
387
387
                        
395
395
            trees = [tree]
396
396
 
397
397
        if file_list is not None:
398
 
            file_ids = bzrlib.tree.find_ids_across_trees(file_list, trees,
 
398
            file_ids = _mod_tree.find_ids_across_trees(file_list, trees,
399
399
                                                      require_versioned=True)
400
400
            # find_ids_across_trees may include some paths that don't
401
401
            # exist in 'tree'.
437
437
            names_list = []
438
438
 
439
439
        if len(names_list) < 2:
440
 
            raise BzrCommandError("missing file argument")
 
440
            raise errors.BzrCommandError("missing file argument")
441
441
        tree, rel_names = tree_files(names_list)
442
442
        
443
443
        if os.path.isdir(names_list[-1]):
446
446
                self.outf.write("%s => %s\n" % pair)
447
447
        else:
448
448
            if len(names_list) != 2:
449
 
                raise BzrCommandError('to mv multiple files the destination '
450
 
                                      'must be a versioned directory')
 
449
                raise errors.BzrCommandError('to mv multiple files the destination '
 
450
                                             'must be a versioned directory')
451
451
            tree.rename_one(rel_names[0], rel_names[1])
452
452
            self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
453
453
            
481
481
        try:
482
482
            tree_to = WorkingTree.open_containing(u'.')[0]
483
483
            branch_to = tree_to.branch
484
 
        except NoWorkingTree:
 
484
        except errors.NoWorkingTree:
485
485
            tree_to = None
486
486
            branch_to = Branch.open_containing(u'.')[0]
487
487
 
489
489
        if location is not None:
490
490
            try:
491
491
                reader = bundle.read_bundle_from_url(location)
492
 
            except NotABundle:
 
492
            except errors.NotABundle:
493
493
                pass # Continue on considering this url a Branch
494
494
 
495
495
        stored_loc = branch_to.get_parent()
496
496
        if location is None:
497
497
            if stored_loc is None:
498
 
                raise BzrCommandError("No pull location known or specified.")
 
498
                raise errors.BzrCommandError("No pull location known or"
 
499
                                             " specified.")
499
500
            else:
500
501
                display_url = urlutils.unescape_for_display(stored_loc,
501
502
                        self.outf.encoding)
519
520
        elif len(revision) == 1:
520
521
            rev_id = revision[0].in_history(branch_from).rev_id
521
522
        else:
522
 
            raise BzrCommandError('bzr pull --revision takes one value.')
 
523
            raise errors.BzrCommandError('bzr pull --revision takes one value.')
523
524
 
524
525
        old_rh = branch_to.revision_history()
525
526
        if tree_to is not None:
579
580
        stored_loc = br_from.get_push_location()
580
581
        if location is None:
581
582
            if stored_loc is None:
582
 
                raise BzrCommandError("No push location known or specified.")
 
583
                raise errors.BzrCommandError("No push location known or specified.")
583
584
            else:
584
585
                display_url = urlutils.unescape_for_display(stored_loc,
585
586
                        self.outf.encoding)
593
594
        try:
594
595
            dir_to = bzrdir.BzrDir.open(location_url)
595
596
            br_to = dir_to.open_branch()
596
 
        except NotBranchError:
 
597
        except errors.NotBranchError:
597
598
            # create a branch.
598
599
            to_transport = to_transport.clone('..')
599
600
            if not create_prefix:
601
602
                    relurl = to_transport.relpath(location_url)
602
603
                    mutter('creating directory %s => %s', location_url, relurl)
603
604
                    to_transport.mkdir(relurl)
604
 
                except NoSuchFile:
605
 
                    raise BzrCommandError("Parent directory of %s "
606
 
                                          "does not exist." % location)
 
605
                except errors.NoSuchFile:
 
606
                    raise errors.BzrCommandError("Parent directory of %s "
 
607
                                                 "does not exist." % location)
607
608
            else:
608
609
                current = to_transport.base
609
610
                needed = [(to_transport, to_transport.relpath(location_url))]
612
613
                        to_transport, relpath = needed[-1]
613
614
                        to_transport.mkdir(relpath)
614
615
                        needed.pop()
615
 
                    except NoSuchFile:
 
616
                    except errors.NoSuchFile:
616
617
                        new_transport = to_transport.clone('..')
617
618
                        needed.append((new_transport,
618
619
                                       new_transport.relpath(to_transport.base)))
619
620
                        if new_transport.base == to_transport.base:
620
 
                            raise BzrCommandError("Could not create "
621
 
                                                  "path prefix.")
 
621
                            raise errors.BzrCommandError("Could not create "
 
622
                                                         "path prefix.")
622
623
            dir_to = br_from.bzrdir.clone(location_url,
623
624
                revision_id=br_from.last_revision())
624
625
            br_to = dir_to.open_branch()
639
640
                    warning('This transport does not update the working '
640
641
                            'tree of: %s' % (br_to.base,))
641
642
                    count = br_to.pull(br_from, overwrite)
642
 
                except NoWorkingTree:
 
643
                except errors.NoWorkingTree:
643
644
                    count = br_to.pull(br_from, overwrite)
644
645
                else:
645
646
                    count = tree_to.pull(br_from, overwrite)
646
 
            except DivergedBranches:
647
 
                raise BzrCommandError("These branches have diverged."
648
 
                                      "  Try a merge then push with overwrite.")
 
647
            except errors.DivergedBranches:
 
648
                raise errors.BzrCommandError('These branches have diverged.'
 
649
                                        '  Try using "merge" and then "push".')
649
650
        note('%d revision(s) pushed.' % (count,))
650
651
 
651
652
        if verbose:
678
679
        if revision is None:
679
680
            revision = [None]
680
681
        elif len(revision) > 1:
681
 
            raise BzrCommandError(
 
682
            raise errors.BzrCommandError(
682
683
                'bzr branch --revision takes exactly 1 revision value')
683
684
        try:
684
685
            br_from = Branch.open(from_location)
685
686
        except OSError, e:
686
687
            if e.errno == errno.ENOENT:
687
 
                raise BzrCommandError('Source location "%s" does not'
688
 
                                      ' exist.' % to_location)
 
688
                raise errors.BzrCommandError('Source location "%s" does not'
 
689
                                             ' exist.' % to_location)
689
690
            else:
690
691
                raise
691
692
        br_from.lock_read()
711
712
            try:
712
713
                to_transport.mkdir('.')
713
714
            except errors.FileExists:
714
 
                raise BzrCommandError('Target directory "%s" already'
715
 
                                      ' exists.' % to_location)
 
715
                raise errors.BzrCommandError('Target directory "%s" already'
 
716
                                             ' exists.' % to_location)
716
717
            except errors.NoSuchFile:
717
 
                raise BzrCommandError('Parent of "%s" does not exist.' %
718
 
                                      to_location)
 
718
                raise errors.BzrCommandError('Parent of "%s" does not exist.'
 
719
                                             % to_location)
719
720
            try:
720
721
                # preserve whatever source format we have.
721
722
                dir = br_from.bzrdir.sprout(to_transport.base,
724
725
            except errors.NoSuchRevision:
725
726
                to_transport.delete_tree('.')
726
727
                msg = "The branch %s has no revision %s." % (from_location, revision[0])
727
 
                raise BzrCommandError(msg)
 
728
                raise errors.BzrCommandError(msg)
728
729
            except errors.UnlistableBranch:
729
730
                osutils.rmtree(to_location)
730
731
                msg = "The branch %s cannot be used as a --basis" % (basis,)
731
 
                raise BzrCommandError(msg)
 
732
                raise errors.BzrCommandError(msg)
732
733
            if name:
733
734
                branch.control_files.put_utf8('branch-name', name)
734
735
            note('Branched %d revision(s).' % branch.revno())
773
774
        if revision is None:
774
775
            revision = [None]
775
776
        elif len(revision) > 1:
776
 
            raise BzrCommandError(
 
777
            raise errors.BzrCommandError(
777
778
                'bzr checkout --revision takes exactly 1 revision value')
778
779
        if branch_location is None:
779
780
            branch_location = osutils.getcwd()
799
800
            os.mkdir(to_location)
800
801
        except OSError, e:
801
802
            if e.errno == errno.EEXIST:
802
 
                raise BzrCommandError('Target directory "%s" already'
803
 
                                      ' exists.' % to_location)
 
803
                raise errors.BzrCommandError('Target directory "%s" already'
 
804
                                             ' exists.' % to_location)
804
805
            if e.errno == errno.ENOENT:
805
 
                raise BzrCommandError('Parent of "%s" does not exist.' %
806
 
                                      to_location)
 
806
                raise errors.BzrCommandError('Parent of "%s" does not exist.'
 
807
                                             % to_location)
807
808
            else:
808
809
                raise
809
810
        old_format = bzrdir.BzrDirFormat.get_default_format()
824
825
 
825
826
    @display_command
826
827
    def run(self, dir=u'.'):
827
 
        from bzrlib.tree import find_renames
828
828
        tree = WorkingTree.open_containing(dir)[0]
829
829
        old_inv = tree.basis_tree().inventory
830
830
        new_inv = tree.read_working_inventory()
831
 
        renames = list(find_renames(old_inv, new_inv))
 
831
        renames = list(_mod_tree.find_renames(old_inv, new_inv))
832
832
        renames.sort()
833
833
        for old_name, new_name in renames:
834
834
            self.outf.write("%s => %s\n" % (old_name, new_name))
913
913
        tree, file_list = tree_files(file_list)
914
914
        if new is False:
915
915
            if file_list is None:
916
 
                raise BzrCommandError('Specify one or more files to remove, or'
917
 
                                      ' use --new.')
 
916
                raise errors.BzrCommandError('Specify one or more files to'
 
917
                                             ' remove, or use --new.')
918
918
        else:
919
919
            added = tree.changes_from(tree.basis_tree(),
920
920
                specific_files=file_list).added
921
921
            file_list = sorted([f[0] for f in added], reverse=True)
922
922
            if len(file_list) == 0:
923
 
                raise BzrCommandError('No matching files.')
 
923
                raise errors.BzrCommandError('No matching files.')
924
924
        tree.remove(file_list, verbose=verbose, to_file=self.outf)
925
925
 
926
926
 
940
940
        tree, relpath = WorkingTree.open_containing(filename)
941
941
        i = tree.inventory.path2id(relpath)
942
942
        if i is None:
943
 
            raise BzrError("%r is not a versioned file" % filename)
 
943
            raise errors.BzrError("%r is not a versioned file" % filename)
944
944
        else:
945
945
            self.outf.write(i + '\n')
946
946
 
961
961
        inv = tree.inventory
962
962
        fid = inv.path2id(relpath)
963
963
        if fid is None:
964
 
            raise BzrError("%r is not a versioned file" % filename)
 
964
            raise errors.BzrError("%r is not a versioned file" % filename)
965
965
        for fip in inv.get_idpath(fid):
966
966
            self.outf.write(fip + '\n')
967
967
 
1081
1081
                    
1082
1082
        try:
1083
1083
            existing_bzrdir = bzrdir.BzrDir.open(location)
1084
 
        except NotBranchError:
 
1084
        except errors.NotBranchError:
1085
1085
            # really a NotBzrDir error...
1086
1086
            bzrdir.BzrDir.create_branch_convenience(location, format=format)
1087
1087
        else:
 
1088
            from bzrlib.transport.local import LocalTransport
1088
1089
            if existing_bzrdir.has_branch():
1089
1090
                if (isinstance(to_transport, LocalTransport)
1090
1091
                    and not existing_bzrdir.has_workingtree()):
1191
1192
            new_label = 'new/'
1192
1193
        else:
1193
1194
            if not ':' in prefix:
1194
 
                 raise BzrError("--diff-prefix expects two values separated by a colon")
 
1195
                 raise errors.BzrError("--diff-prefix expects two values"
 
1196
                                       " separated by a colon")
1195
1197
            old_label, new_label = prefix.split(":")
1196
1198
        
1197
1199
        try:
1199
1201
            tree2 = None
1200
1202
            b = None
1201
1203
            b2 = None
1202
 
        except FileInWrongBranch:
 
1204
        except errors.FileInWrongBranch:
1203
1205
            if len(file_list) != 2:
1204
 
                raise BzrCommandError("Files are in different branches")
 
1206
                raise errors.BzrCommandError("Files are in different branches")
1205
1207
 
1206
1208
            tree1, file1 = WorkingTree.open_containing(file_list[0])
1207
1209
            tree2, file2 = WorkingTree.open_containing(file_list[1])
1208
1210
            if file1 != "" or file2 != "":
1209
1211
                # FIXME diff those two files. rbc 20051123
1210
 
                raise BzrCommandError("Files are in different branches")
 
1212
                raise errors.BzrCommandError("Files are in different branches")
1211
1213
            file_list = None
1212
 
        except NotBranchError:
 
1214
        except errors.NotBranchError:
1213
1215
            if (revision is not None and len(revision) == 2
1214
1216
                and not revision[0].needs_branch()
1215
1217
                and not revision[1].needs_branch()):
1220
1222
                raise
1221
1223
        if revision is not None:
1222
1224
            if tree2 is not None:
1223
 
                raise BzrCommandError("Can't specify -r with two branches")
 
1225
                raise errors.BzrCommandError("Can't specify -r with two branches")
1224
1226
            if (len(revision) == 1) or (revision[1].spec is None):
1225
1227
                return diff_cmd_helper(tree1, file_list, diff_options,
1226
1228
                                       revision[0], 
1230
1232
                                       revision[0], revision[1],
1231
1233
                                       old_label=old_label, new_label=new_label)
1232
1234
            else:
1233
 
                raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
 
1235
                raise errors.BzrCommandError('bzr diff --revision takes exactly'
 
1236
                                             ' one or two revision identifiers')
1234
1237
        else:
1235
1238
            if tree2 is not None:
1236
1239
                return show_diff_trees(tree1, tree2, sys.stdout, 
1392
1395
                # b is taken from revision[0].get_branch(), and
1393
1396
                # show_log will use its revision_history. Having
1394
1397
                # different branches will lead to weird behaviors.
1395
 
                raise BzrCommandError(
 
1398
                raise errors.BzrCommandError(
1396
1399
                    "Log doesn't accept two revisions in different branches.")
1397
1400
            if revision[0].spec is None:
1398
1401
                # missing begin-range means first revision
1406
1409
            else:
1407
1410
                rev2 = revision[1].in_history(b).revno
1408
1411
        else:
1409
 
            raise BzrCommandError('bzr log --revision takes one or two values.')
 
1412
            raise errors.BzrCommandError('bzr log --revision takes one or two values.')
1410
1413
 
1411
1414
        # By this point, the revision numbers are converted to the +ve
1412
1415
        # form if they were supplied in the -ve form, so we can do
1486
1489
            null=False):
1487
1490
 
1488
1491
        if verbose and null:
1489
 
            raise BzrCommandError('Cannot set both --verbose and --null')
 
1492
            raise errors.BzrCommandError('Cannot set both --verbose and --null')
1490
1493
        all = not (unknown or versioned or ignored)
1491
1494
 
1492
1495
        selection = {'I':ignored, '?':unknown, 'V':versioned}
1558
1561
                print pattern
1559
1562
            return
1560
1563
        if name_pattern is None:
1561
 
            raise BzrCommandError("ignore requires a NAME_PATTERN")
 
1564
            raise errors.BzrCommandError("ignore requires a NAME_PATTERN")
1562
1565
        tree, relpath = WorkingTree.open_containing(u'.')
1563
1566
        ifn = tree.abspath('.bzrignore')
1564
1567
        if os.path.exists(ifn):
1621
1624
        try:
1622
1625
            revno = int(revno)
1623
1626
        except ValueError:
1624
 
            raise BzrCommandError("not a valid revision-number: %r" % revno)
 
1627
            raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
1625
1628
 
1626
1629
        print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
1627
1630
 
1659
1662
            rev_id = b.last_revision()
1660
1663
        else:
1661
1664
            if len(revision) != 1:
1662
 
                raise BzrError('bzr export --revision takes exactly 1 argument')
 
1665
                raise errors.BzrError('bzr export --revision takes exactly'
 
1666
                                      ' 1 argument')
1663
1667
            rev_id = revision[0].in_history(b).rev_id
1664
1668
        t = b.repository.revision_tree(rev_id)
1665
1669
        try:
1666
1670
            export(t, dest, format, root)
1667
1671
        except errors.NoSuchExportFormat, e:
1668
 
            raise BzrCommandError('Unsupported export format: %s' % e.format)
 
1672
            raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
1669
1673
 
1670
1674
 
1671
1675
class cmd_cat(Command):
1677
1681
    @display_command
1678
1682
    def run(self, filename, revision=None):
1679
1683
        if revision is not None and len(revision) != 1:
1680
 
            raise BzrCommandError("bzr cat --revision takes exactly one number")
 
1684
            raise errors.BzrCommandError("bzr cat --revision takes exactly one number")
1681
1685
        tree = None
1682
1686
        try:
1683
1687
            tree, relpath = WorkingTree.open_containing(filename)
1684
1688
            b = tree.branch
1685
 
        except NotBranchError:
 
1689
        except errors.NotBranchError:
1686
1690
            pass
1687
1691
 
1688
1692
        if tree is None:
1776
1780
            template = make_commit_message_template(tree, selected_list)
1777
1781
            message = edit_commit_message(template)
1778
1782
            if message is None:
1779
 
                raise BzrCommandError("please specify a commit message"
1780
 
                                      " with either --message or --file")
 
1783
                raise errors.BzrCommandError("please specify a commit message"
 
1784
                                             " with either --message or --file")
1781
1785
        elif message and file:
1782
 
            raise BzrCommandError("please specify either --message or --file")
 
1786
            raise errors.BzrCommandError("please specify either --message or --file")
1783
1787
        
1784
1788
        if file:
1785
1789
            message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1786
1790
 
1787
1791
        if message == "":
1788
 
            raise BzrCommandError("empty commit message specified")
 
1792
            raise errors.BzrCommandError("empty commit message specified")
1789
1793
        
1790
1794
        if verbose:
1791
1795
            reporter = ReportCommitToLog()
1799
1803
        except PointlessCommit:
1800
1804
            # FIXME: This should really happen before the file is read in;
1801
1805
            # perhaps prepare the commit; get the message; then actually commit
1802
 
            raise BzrCommandError("no changes to commit."
1803
 
                                  " use --unchanged to commit anyhow")
 
1806
            raise errors.BzrCommandError("no changes to commit."
 
1807
                                         " use --unchanged to commit anyhow")
1804
1808
        except ConflictsInTree:
1805
 
            raise BzrCommandError("Conflicts detected in working tree.  "
 
1809
            raise errors.BzrCommandError("Conflicts detected in working tree.  "
1806
1810
                'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
1807
1811
        except StrictCommitFailed:
1808
 
            raise BzrCommandError("Commit refused because there are unknown "
1809
 
                                  "files in the working tree.")
 
1812
            raise errors.BzrCommandError("Commit refused because there are unknown "
 
1813
                                         "files in the working tree.")
1810
1814
        except errors.BoundBranchOutOfDate, e:
1811
 
            raise BzrCommandError(str(e) + "\n"
 
1815
            raise errors.BzrCommandError(str(e) + "\n"
1812
1816
                'To commit to master branch, run update and then commit.\n'
1813
1817
                'You can also pass --local to commit to continue working '
1814
1818
                'disconnected.')
1898
1902
            # use branch if we're inside one; otherwise global config
1899
1903
            try:
1900
1904
                c = Branch.open_containing('.')[0].get_config()
1901
 
            except NotBranchError:
 
1905
            except errors.NotBranchError:
1902
1906
                c = config.GlobalConfig()
1903
1907
            if email:
1904
1908
                self.outf.write(c.user_email() + '\n')
1909
1913
        # display a warning if an email address isn't included in the given name.
1910
1914
        try:
1911
1915
            config.extract_email_address(name)
1912
 
        except BzrError, e:
 
1916
        except errors.NoEmailInUsername, e:
1913
1917
            warning('"%s" does not seem to contain an email address.  '
1914
1918
                    'This is allowed, but not recommended.', name)
1915
1919
        
1977
1981
            return FakeNFSServer
1978
1982
        msg = "No known transport type %s. Supported types are: sftp\n" %\
1979
1983
            (typestring)
1980
 
        raise BzrCommandError(msg)
 
1984
        raise errors.BzrCommandError(msg)
1981
1985
 
1982
1986
    hidden = True
1983
1987
    takes_args = ['testspecs*']
2082
2086
    
2083
2087
    @display_command
2084
2088
    def run(self, branch, other):
2085
 
        from bzrlib.revision import common_ancestor, MultipleRevisionSources
 
2089
        from bzrlib.revision import MultipleRevisionSources
2086
2090
        
2087
2091
        branch1 = Branch.open_containing(branch)[0]
2088
2092
        branch2 = Branch.open_containing(other)[0]
2150
2154
                            ' from a working copy, instead of branch changes')]
2151
2155
 
2152
2156
    def help(self):
2153
 
        from merge import merge_type_help
2154
2157
        from inspect import getdoc
2155
 
        return getdoc(self) + '\n' + merge_type_help() 
 
2158
        return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2156
2159
 
2157
2160
    def run(self, branch=None, revision=None, force=False, merge_type=None,
2158
2161
            show_base=False, reprocess=False, remember=False, 
2159
2162
            uncommitted=False):
2160
2163
        if merge_type is None:
2161
 
            merge_type = Merge3Merger
 
2164
            merge_type = _mod_merge.Merge3Merger
2162
2165
 
2163
2166
        tree = WorkingTree.open_containing(u'.')[0]
2164
2167
 
2165
2168
        if branch is not None:
2166
2169
            try:
2167
2170
                reader = bundle.read_bundle_from_url(branch)
2168
 
            except NotABundle:
 
2171
            except errors.NotABundle:
2169
2172
                pass # Continue on considering this url a Branch
2170
2173
            else:
2171
2174
                conflicts = merge_bundle(reader, tree, not force, merge_type,
2189
2192
            other_branch, path = Branch.open_containing(branch)
2190
2193
        else:
2191
2194
            if uncommitted:
2192
 
                raise BzrCommandError('Cannot use --uncommitted and --revision'
2193
 
                                      ' at the same time.')
 
2195
                raise errors.BzrCommandError('Cannot use --uncommitted and'
 
2196
                                             ' --revision at the same time.')
2194
2197
            branch = revision[0].get_branch() or branch
2195
2198
            if len(revision) == 1:
2196
2199
                base = [None, None]
2200
2203
            else:
2201
2204
                assert len(revision) == 2
2202
2205
                if None in revision:
2203
 
                    raise BzrCommandError(
 
2206
                    raise errors.BzrCommandError(
2204
2207
                        "Merge doesn't permit empty revision specifier.")
2205
2208
                base_branch, path = Branch.open_containing(branch)
2206
2209
                branch1 = revision[1].get_branch() or branch
2222
2225
        pb = ui.ui_factory.nested_progress_bar()
2223
2226
        try:
2224
2227
            try:
2225
 
                conflict_count = merge(other, base, check_clean=(not force),
2226
 
                                       merge_type=merge_type,
2227
 
                                       reprocess=reprocess,
2228
 
                                       show_base=show_base,
2229
 
                                       pb=pb, file_list=interesting_files)
 
2228
                conflict_count = _merge_helper(
 
2229
                    other, base, check_clean=(not force),
 
2230
                    merge_type=merge_type,
 
2231
                    reprocess=reprocess,
 
2232
                    show_base=show_base,
 
2233
                    pb=pb, file_list=interesting_files)
2230
2234
            finally:
2231
2235
                pb.finished()
2232
2236
            if conflict_count != 0:
2253
2257
        stored_location = tree.branch.get_parent()
2254
2258
        mutter("%s", stored_location)
2255
2259
        if stored_location is None:
2256
 
            raise BzrCommandError("No location specified or remembered")
 
2260
            raise errors.BzrCommandError("No location specified or remembered")
2257
2261
        display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2258
2262
        self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
2259
2263
        return stored_location
2286
2290
                            "conflicts")]
2287
2291
 
2288
2292
    def help(self):
2289
 
        from merge import merge_type_help
2290
2293
        from inspect import getdoc
2291
 
        return getdoc(self) + '\n' + merge_type_help() 
 
2294
        return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2292
2295
 
2293
2296
    def run(self, file_list=None, merge_type=None, show_base=False,
2294
2297
            reprocess=False):
2295
 
        from bzrlib.merge import merge_inner, transform_tree
2296
2298
        if merge_type is None:
2297
 
            merge_type = Merge3Merger
 
2299
            merge_type = _mod_merge.Merge3Merger
2298
2300
        tree, file_list = tree_files(file_list)
2299
2301
        tree.lock_write()
2300
2302
        try:
2301
2303
            parents = tree.get_parent_ids()
2302
2304
            if len(parents) != 2:
2303
 
                raise BzrCommandError("Sorry, remerge only works after normal"
2304
 
                                      " merges.  Not cherrypicking or"
2305
 
                                      " multi-merges.")
 
2305
                raise errors.BzrCommandError("Sorry, remerge only works after normal"
 
2306
                                             " merges.  Not cherrypicking or"
 
2307
                                             " multi-merges.")
2306
2308
            repository = tree.branch.repository
2307
2309
            base_revision = common_ancestor(parents[0],
2308
2310
                                            parents[1], repository)
2316
2318
                for filename in file_list:
2317
2319
                    file_id = tree.path2id(filename)
2318
2320
                    if file_id is None:
2319
 
                        raise NotVersionedError(filename)
 
2321
                        raise errors.NotVersionedError(filename)
2320
2322
                    interesting_ids.add(file_id)
2321
2323
                    if tree.kind(file_id) != "directory":
2322
2324
                        continue
2324
2326
                    for name, ie in tree.inventory.iter_entries(file_id):
2325
2327
                        interesting_ids.add(ie.file_id)
2326
2328
                new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2327
 
            transform_tree(tree, tree.basis_tree(), interesting_ids)
 
2329
            _mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
2328
2330
            tree.set_conflicts(ConflictList(new_conflicts))
2329
2331
            if file_list is None:
2330
2332
                restore_files = list(tree.iter_conflicts())
2333
2335
            for filename in restore_files:
2334
2336
                try:
2335
2337
                    restore(tree.abspath(filename))
2336
 
                except NotConflicted:
 
2338
                except errors.NotConflicted:
2337
2339
                    pass
2338
 
            conflicts = merge_inner(tree.branch, other_tree, base_tree,
2339
 
                                    this_tree=tree,
2340
 
                                    interesting_ids=interesting_ids,
2341
 
                                    other_rev_id=parents[1],
2342
 
                                    merge_type=merge_type,
2343
 
                                    show_base=show_base,
2344
 
                                    reprocess=reprocess)
 
2340
            conflicts = _mod_merge.merge_inner(
 
2341
                                      tree.branch, other_tree, base_tree,
 
2342
                                      this_tree=tree,
 
2343
                                      interesting_ids=interesting_ids,
 
2344
                                      other_rev_id=parents[1],
 
2345
                                      merge_type=merge_type,
 
2346
                                      show_base=show_base,
 
2347
                                      reprocess=reprocess)
2345
2348
        finally:
2346
2349
            tree.unlock()
2347
2350
        if conflicts > 0:
2375
2378
    aliases = ['merge-revert']
2376
2379
 
2377
2380
    def run(self, revision=None, no_backup=False, file_list=None):
2378
 
        from bzrlib.commands import parse_spec
2379
2381
        if file_list is not None:
2380
2382
            if len(file_list) == 0:
2381
 
                raise BzrCommandError("No files specified")
 
2383
                raise errors.BzrCommandError("No files specified")
2382
2384
        else:
2383
2385
            file_list = []
2384
2386
        
2387
2389
            # FIXME should be tree.last_revision
2388
2390
            rev_id = tree.last_revision()
2389
2391
        elif len(revision) != 1:
2390
 
            raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
 
2392
            raise errors.BzrCommandError('bzr revert --revision takes exactly 1 argument')
2391
2393
        else:
2392
2394
            rev_id = revision[0].in_history(tree.branch).rev_id
2393
2395
        pb = ui.ui_factory.nested_progress_bar()
2479
2481
        if other_branch is None:
2480
2482
            other_branch = parent
2481
2483
            if other_branch is None:
2482
 
                raise BzrCommandError("No peer location known or specified.")
 
2484
                raise errors.BzrCommandError("No peer location known or specified.")
2483
2485
            print "Using last location: " + local_branch.get_parent()
2484
2486
        remote_branch = Branch.open(other_branch)
2485
2487
        if remote_branch.base == local_branch.base:
2614
2616
            if revision is None:
2615
2617
                revision_id = branch.last_revision()
2616
2618
            elif len(revision) != 1:
2617
 
                raise BzrCommandError('bzr annotate --revision takes exactly 1 argument')
 
2619
                raise errors.BzrCommandError('bzr annotate --revision takes exactly 1 argument')
2618
2620
            else:
2619
2621
                revision_id = revision[0].in_history(branch).rev_id
2620
2622
            file_id = tree.inventory.path2id(relpath)
2636
2638
    def run(self, revision_id_list=None, revision=None):
2637
2639
        import bzrlib.gpg as gpg
2638
2640
        if revision_id_list is not None and revision is not None:
2639
 
            raise BzrCommandError('You can only supply one of revision_id or --revision')
 
2641
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
2640
2642
        if revision_id_list is None and revision is None:
2641
 
            raise BzrCommandError('You must supply either --revision or a revision_id')
 
2643
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
2642
2644
        b = WorkingTree.open_containing(u'.')[0].branch
2643
2645
        gpg_strategy = gpg.GPGStrategy(b.get_config())
2644
2646
        if revision_id_list is not None:
2657
2659
                if to_revid is None:
2658
2660
                    to_revno = b.revno()
2659
2661
                if from_revno is None or to_revno is None:
2660
 
                    raise BzrCommandError('Cannot sign a range of non-revision-history revisions')
 
2662
                    raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
2661
2663
                for revno in range(from_revno, to_revno + 1):
2662
2664
                    b.repository.sign_revision(b.get_rev_id(revno), 
2663
2665
                                               gpg_strategy)
2664
2666
            else:
2665
 
                raise BzrCommandError('Please supply either one revision, or a range.')
 
2667
                raise errors.BzrCommandError('Please supply either one revision, or a range.')
2666
2668
 
2667
2669
 
2668
2670
class cmd_bind(Command):
2680
2682
        b_other = Branch.open(location)
2681
2683
        try:
2682
2684
            b.bind(b_other)
2683
 
        except DivergedBranches:
2684
 
            raise BzrCommandError('These branches have diverged.'
2685
 
                                  ' Try merging, and then bind again.')
 
2685
        except errors.DivergedBranches:
 
2686
            raise errors.BzrCommandError('These branches have diverged.'
 
2687
                                         ' Try merging, and then bind again.')
2686
2688
 
2687
2689
 
2688
2690
class cmd_unbind(Command):
2698
2700
    def run(self):
2699
2701
        b, relpath = Branch.open_containing(u'.')
2700
2702
        if not b.unbind():
2701
 
            raise BzrCommandError('Local branch is not bound')
 
2703
            raise errors.BzrCommandError('Local branch is not bound')
2702
2704
 
2703
2705
 
2704
2706
class cmd_uncommit(Command):
2863
2865
            print 'listening on port: ', server.port
2864
2866
            sys.stdout.flush()
2865
2867
        else:
2866
 
            raise BzrCommandError("bzr serve requires one of --inet or --port")
 
2868
            raise errors.BzrCommandError("bzr serve requires one of --inet or --port")
2867
2869
        server.serve()
2868
2870
 
2869
2871
 
2870
2872
# command-line interpretation helper for merge-related commands
2871
 
def merge(other_revision, base_revision,
2872
 
          check_clean=True, ignore_zero=False,
2873
 
          this_dir=None, backup_files=False, merge_type=Merge3Merger,
2874
 
          file_list=None, show_base=False, reprocess=False,
2875
 
          pb=DummyProgress()):
 
2873
def _merge_helper(other_revision, base_revision,
 
2874
                  check_clean=True, ignore_zero=False,
 
2875
                  this_dir=None, backup_files=False,
 
2876
                  merge_type=None,
 
2877
                  file_list=None, show_base=False, reprocess=False,
 
2878
                  pb=DummyProgress()):
2876
2879
    """Merge changes into a tree.
2877
2880
 
2878
2881
    base_revision
2900
2903
    clients might prefer to call merge.merge_inner(), which has less magic 
2901
2904
    behavior.
2902
2905
    """
2903
 
    from bzrlib.merge import Merger
 
2906
    # Loading it late, so that we don't always have to import bzrlib.merge
 
2907
    if merge_type is None:
 
2908
        merge_type = _mod_merge.Merge3Merger
2904
2909
    if this_dir is None:
2905
2910
        this_dir = u'.'
2906
2911
    this_tree = WorkingTree.open_containing(this_dir)[0]
2907
 
    if show_base and not merge_type is Merge3Merger:
2908
 
        raise BzrCommandError("Show-base is not supported for this merge"
2909
 
                              " type. %s" % merge_type)
 
2912
    if show_base and not merge_type is _mod_merge.Merge3Merger:
 
2913
        raise errors.BzrCommandError("Show-base is not supported for this merge"
 
2914
                                     " type. %s" % merge_type)
2910
2915
    if reprocess and not merge_type.supports_reprocess:
2911
 
        raise BzrCommandError("Conflict reduction is not supported for merge"
2912
 
                              " type %s." % merge_type)
 
2916
        raise errors.BzrCommandError("Conflict reduction is not supported for merge"
 
2917
                                     " type %s." % merge_type)
2913
2918
    if reprocess and show_base:
2914
 
        raise BzrCommandError("Cannot do conflict reduction and show base.")
 
2919
        raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
2915
2920
    try:
2916
 
        merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
 
2921
        merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
 
2922
                                   pb=pb)
2917
2923
        merger.pp = ProgressPhase("Merge phase", 5, pb)
2918
2924
        merger.pp.next_phase()
2919
2925
        merger.check_basis(check_clean)
2936
2942
    return conflicts
2937
2943
 
2938
2944
 
 
2945
# Compatibility
 
2946
merge = _merge_helper
 
2947
 
 
2948
 
2939
2949
# these get imported and then picked up by the scan for cmd_*
2940
2950
# TODO: Some more consistent way to split command definitions across files;
2941
2951
# we do need to load at least some information about them to know of