~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: John Arbash Meinel
  • Date: 2006-08-14 16:16:53 UTC
  • mto: (1946.2.6 reduce-knit-churn)
  • mto: This revision was merged to the branch mainline in revision 1919.
  • Revision ID: john@arbash-meinel.com-20060814161653-54cdcdadcd4e9003
Remove bogus entry from BRANCH.TODO

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004, 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2004, 2005, 2006 by Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
16
16
 
17
17
"""builtin bzr commands"""
18
18
 
19
 
import os
20
19
 
21
 
from bzrlib.lazy_import import lazy_import
22
 
lazy_import(globals(), """
23
20
import codecs
24
21
import errno
 
22
import os
 
23
import os.path
25
24
import sys
26
25
 
27
26
import bzrlib
33
32
    errors,
34
33
    ignores,
35
34
    log,
36
 
    merge as _mod_merge,
37
35
    osutils,
38
36
    repository,
39
37
    transport,
40
 
    tree as _mod_tree,
41
38
    ui,
42
39
    urlutils,
43
40
    )
44
 
from bzrlib.branch import Branch
 
41
from bzrlib.branch import Branch, BranchReferenceFormat
 
42
from bzrlib.bundle import read_bundle_from_url
45
43
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
46
44
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
 
 
52
45
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
53
51
from bzrlib.option import Option
54
52
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
from bzrlib.workingtree import WorkingTree
56
58
 
57
59
 
58
60
def tree_files(file_list, default_branch=u'.'):
59
61
    try:
60
62
        return internal_tree_files(file_list, default_branch)
61
 
    except errors.FileInWrongBranch, e:
62
 
        raise errors.BzrCommandError("%s is not in the same branch as %s" %
63
 
                                     (e.path, file_list[0]))
 
63
    except FileInWrongBranch, e:
 
64
        raise BzrCommandError("%s is not in the same branch as %s" %
 
65
                             (e.path, file_list[0]))
64
66
 
65
67
 
66
68
# XXX: Bad function name; should possibly also be a class method of
75
77
 
76
78
    :param file_list: Filenames to convert.  
77
79
 
78
 
    :param default_branch: Fallback tree path to use if file_list is empty or
79
 
        None.
 
80
    :param default_branch: Fallback tree path to use if file_list is empty or None.
80
81
 
81
82
    :return: workingtree, [relative_paths]
82
83
    """
83
84
    if file_list is None or len(file_list) == 0:
84
85
        return WorkingTree.open_containing(default_branch)[0], file_list
85
 
    tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
 
86
    tree = WorkingTree.open_containing(file_list[0])[0]
86
87
    new_list = []
87
88
    for filename in file_list:
88
89
        try:
89
 
            new_list.append(tree.relpath(osutils.dereference_path(filename)))
 
90
            new_list.append(tree.relpath(filename))
90
91
        except errors.PathNotChild:
91
 
            raise errors.FileInWrongBranch(tree.branch, filename)
 
92
            raise FileInWrongBranch(tree.branch, filename)
92
93
    return tree, new_list
93
94
 
94
95
 
106
107
        format = bzrdir.BzrDirMetaFormat1()
107
108
        format.repository_format = repository.RepositoryFormatKnit1()
108
109
        return format
109
 
    if typestring == "experimental-knit2":
110
 
        format = bzrdir.BzrDirMetaFormat1()
111
 
        format.repository_format = repository.RepositoryFormatKnit2()
112
 
        return format
113
110
    msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
114
111
          "metaweave and weave" % typestring
115
 
    raise errors.BzrCommandError(msg)
 
112
    raise BzrCommandError(msg)
116
113
 
117
114
 
118
115
# TODO: Make sure no commands unconditionally use the working directory as a
193
190
    def run(self, revision_id=None, revision=None):
194
191
 
195
192
        if revision_id is not None and revision is not None:
196
 
            raise errors.BzrCommandError('You can only supply one of'
197
 
                                         ' revision_id or --revision')
 
193
            raise BzrCommandError('You can only supply one of revision_id or --revision')
198
194
        if revision_id is None and revision is None:
199
 
            raise errors.BzrCommandError('You must supply either'
200
 
                                         ' --revision or a revision_id')
 
195
            raise BzrCommandError('You must supply either --revision or a revision_id')
201
196
        b = WorkingTree.open_containing(u'.')[0].branch
202
197
 
203
198
        # TODO: jam 20060112 should cat-revision always output utf-8?
206
201
        elif revision is not None:
207
202
            for rev in revision:
208
203
                if rev is None:
209
 
                    raise errors.BzrCommandError('You cannot specify a NULL'
210
 
                                                 ' revision.')
 
204
                    raise BzrCommandError('You cannot specify a NULL revision.')
211
205
                revno, rev_id = rev.in_history(b)
212
206
                self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
213
207
    
241
235
            revs.extend(revision)
242
236
        if revision_info_list is not None:
243
237
            for rev in revision_info_list:
244
 
                revs.append(RevisionSpec.from_string(rev))
 
238
                revs.append(RevisionSpec(rev))
245
239
        if len(revs) == 0:
246
 
            raise errors.BzrCommandError('You must supply a revision identifier')
 
240
            raise BzrCommandError('You must supply a revision identifier')
247
241
 
248
242
        b = WorkingTree.open_containing(u'.')[0].branch
249
243
 
280
274
 
281
275
    --dry-run will show which files would be added, but not actually 
282
276
    add them.
283
 
 
284
 
    --file-ids-from will try to use the file ids from the supplied path.
285
 
    It looks up ids trying to find a matching parent directory with the
286
 
    same filename, and then by pure path.
287
277
    """
288
278
    takes_args = ['file*']
289
 
    takes_options = ['no-recurse', 'dry-run', 'verbose',
290
 
                     Option('file-ids-from', type=unicode,
291
 
                            help='Lookup file ids from here')]
 
279
    takes_options = ['no-recurse', 'dry-run', 'verbose']
292
280
    encoding_type = 'replace'
293
281
 
294
 
    def run(self, file_list, no_recurse=False, dry_run=False, verbose=False,
295
 
            file_ids_from=None):
 
282
    def run(self, file_list, no_recurse=False, dry_run=False, verbose=False):
296
283
        import bzrlib.add
297
284
 
298
 
        if file_ids_from is not None:
299
 
            try:
300
 
                base_tree, base_path = WorkingTree.open_containing(
301
 
                                            file_ids_from)
302
 
            except errors.NoWorkingTree:
303
 
                base_branch, base_path = Branch.open_containing(
304
 
                                            file_ids_from)
305
 
                base_tree = base_branch.basis_tree()
306
 
 
307
 
            action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
308
 
                          to_file=self.outf, should_print=(not is_quiet()))
309
 
        else:
310
 
            action = bzrlib.add.AddAction(to_file=self.outf,
311
 
                should_print=(not is_quiet()))
312
 
 
313
 
        added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
 
285
        action = bzrlib.add.AddAction(to_file=self.outf,
 
286
            should_print=(not is_quiet()))
 
287
 
 
288
        added, ignored = bzrlib.add.smart_add(file_list, not no_recurse, 
314
289
                                              action=action, save=not dry_run)
315
290
        if len(ignored) > 0:
316
291
            if verbose:
363
338
    """Show inventory of the current working copy or a revision.
364
339
 
365
340
    It is possible to limit the output to a particular entry
366
 
    type using the --kind option.  For example: --kind file.
367
 
 
368
 
    It is also possible to restrict the list of files to a specific
369
 
    set. For example: bzr inventory --show-ids this/file
 
341
    type using the --kind option.  For example; --kind file.
370
342
    """
371
343
 
372
344
    takes_options = ['revision', 'show-ids', 'kind']
373
 
    takes_args = ['file*']
374
 
 
 
345
    
375
346
    @display_command
376
 
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
 
347
    def run(self, revision=None, show_ids=False, kind=None):
377
348
        if kind and kind not in ['file', 'directory', 'symlink']:
378
 
            raise errors.BzrCommandError('invalid kind specified')
379
 
 
380
 
        work_tree, file_list = tree_files(file_list)
381
 
 
382
 
        if revision is not None:
 
349
            raise BzrCommandError('invalid kind specified')
 
350
        tree = WorkingTree.open_containing(u'.')[0]
 
351
        if revision is None:
 
352
            inv = tree.read_working_inventory()
 
353
        else:
383
354
            if len(revision) > 1:
384
 
                raise errors.BzrCommandError('bzr inventory --revision takes'
385
 
                                             ' exactly one revision identifier')
386
 
            revision_id = revision[0].in_history(work_tree.branch).rev_id
387
 
            tree = work_tree.branch.repository.revision_tree(revision_id)
388
 
                        
389
 
            # We include work_tree as well as 'tree' here
390
 
            # So that doing '-r 10 path/foo' will lookup whatever file
391
 
            # exists now at 'path/foo' even if it has been renamed, as
392
 
            # well as whatever files existed in revision 10 at path/foo
393
 
            trees = [tree, work_tree]
394
 
        else:
395
 
            tree = work_tree
396
 
            trees = [tree]
397
 
 
398
 
        if file_list is not None:
399
 
            file_ids = _mod_tree.find_ids_across_trees(file_list, trees,
400
 
                                                      require_versioned=True)
401
 
            # find_ids_across_trees may include some paths that don't
402
 
            # exist in 'tree'.
403
 
            entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
404
 
                             for file_id in file_ids if file_id in tree)
405
 
        else:
406
 
            entries = tree.inventory.entries()
407
 
 
408
 
        for path, entry in entries:
 
355
                raise BzrCommandError('bzr inventory --revision takes'
 
356
                    ' exactly one revision identifier')
 
357
            inv = tree.branch.repository.get_revision_inventory(
 
358
                revision[0].in_history(tree.branch).rev_id)
 
359
 
 
360
        for path, entry in inv.entries():
409
361
            if kind and kind != entry.kind:
410
362
                continue
411
363
            if show_ids:
438
390
            names_list = []
439
391
 
440
392
        if len(names_list) < 2:
441
 
            raise errors.BzrCommandError("missing file argument")
 
393
            raise BzrCommandError("missing file argument")
442
394
        tree, rel_names = tree_files(names_list)
443
395
        
444
396
        if os.path.isdir(names_list[-1]):
447
399
                self.outf.write("%s => %s\n" % pair)
448
400
        else:
449
401
            if len(names_list) != 2:
450
 
                raise errors.BzrCommandError('to mv multiple files the destination '
451
 
                                             'must be a versioned directory')
 
402
                raise BzrCommandError('to mv multiple files the destination '
 
403
                                      'must be a versioned directory')
452
404
            tree.rename_one(rel_names[0], rel_names[1])
453
405
            self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
454
406
            
482
434
        try:
483
435
            tree_to = WorkingTree.open_containing(u'.')[0]
484
436
            branch_to = tree_to.branch
485
 
        except errors.NoWorkingTree:
 
437
        except NoWorkingTree:
486
438
            tree_to = None
487
439
            branch_to = Branch.open_containing(u'.')[0]
488
440
 
490
442
        if location is not None:
491
443
            try:
492
444
                reader = bundle.read_bundle_from_url(location)
493
 
            except errors.NotABundle:
 
445
            except NotABundle:
494
446
                pass # Continue on considering this url a Branch
495
447
 
496
448
        stored_loc = branch_to.get_parent()
497
449
        if location is None:
498
450
            if stored_loc is None:
499
 
                raise errors.BzrCommandError("No pull location known or"
500
 
                                             " specified.")
 
451
                raise BzrCommandError("No pull location known or specified.")
501
452
            else:
502
453
                display_url = urlutils.unescape_for_display(stored_loc,
503
454
                        self.outf.encoding)
521
472
        elif len(revision) == 1:
522
473
            rev_id = revision[0].in_history(branch_from).rev_id
523
474
        else:
524
 
            raise errors.BzrCommandError('bzr pull --revision takes one value.')
 
475
            raise BzrCommandError('bzr pull --revision takes one value.')
525
476
 
526
477
        old_rh = branch_to.revision_history()
527
478
        if tree_to is not None:
581
532
        stored_loc = br_from.get_push_location()
582
533
        if location is None:
583
534
            if stored_loc is None:
584
 
                raise errors.BzrCommandError("No push location known or specified.")
 
535
                raise BzrCommandError("No push location known or specified.")
585
536
            else:
586
537
                display_url = urlutils.unescape_for_display(stored_loc,
587
538
                        self.outf.encoding)
595
546
        try:
596
547
            dir_to = bzrdir.BzrDir.open(location_url)
597
548
            br_to = dir_to.open_branch()
598
 
        except errors.NotBranchError:
 
549
        except NotBranchError:
599
550
            # create a branch.
600
551
            to_transport = to_transport.clone('..')
601
552
            if not create_prefix:
603
554
                    relurl = to_transport.relpath(location_url)
604
555
                    mutter('creating directory %s => %s', location_url, relurl)
605
556
                    to_transport.mkdir(relurl)
606
 
                except errors.NoSuchFile:
607
 
                    raise errors.BzrCommandError("Parent directory of %s "
608
 
                                                 "does not exist." % location)
 
557
                except NoSuchFile:
 
558
                    raise BzrCommandError("Parent directory of %s "
 
559
                                          "does not exist." % location)
609
560
            else:
610
561
                current = to_transport.base
611
562
                needed = [(to_transport, to_transport.relpath(location_url))]
614
565
                        to_transport, relpath = needed[-1]
615
566
                        to_transport.mkdir(relpath)
616
567
                        needed.pop()
617
 
                    except errors.NoSuchFile:
 
568
                    except NoSuchFile:
618
569
                        new_transport = to_transport.clone('..')
619
570
                        needed.append((new_transport,
620
571
                                       new_transport.relpath(to_transport.base)))
621
572
                        if new_transport.base == to_transport.base:
622
 
                            raise errors.BzrCommandError("Could not create "
623
 
                                                         "path prefix.")
 
573
                            raise BzrCommandError("Could not create "
 
574
                                                  "path prefix.")
624
575
            dir_to = br_from.bzrdir.clone(location_url,
625
576
                revision_id=br_from.last_revision())
626
577
            br_to = dir_to.open_branch()
641
592
                    warning('This transport does not update the working '
642
593
                            'tree of: %s' % (br_to.base,))
643
594
                    count = br_to.pull(br_from, overwrite)
644
 
                except errors.NoWorkingTree:
 
595
                except NoWorkingTree:
645
596
                    count = br_to.pull(br_from, overwrite)
646
597
                else:
647
598
                    count = tree_to.pull(br_from, overwrite)
648
 
            except errors.DivergedBranches:
649
 
                raise errors.BzrCommandError('These branches have diverged.'
650
 
                                        '  Try using "merge" and then "push".')
 
599
            except DivergedBranches:
 
600
                raise BzrCommandError("These branches have diverged."
 
601
                                      "  Try a merge then push with overwrite.")
651
602
        note('%d revision(s) pushed.' % (count,))
652
603
 
653
604
        if verbose:
680
631
        if revision is None:
681
632
            revision = [None]
682
633
        elif len(revision) > 1:
683
 
            raise errors.BzrCommandError(
 
634
            raise BzrCommandError(
684
635
                'bzr branch --revision takes exactly 1 revision value')
685
636
        try:
686
637
            br_from = Branch.open(from_location)
687
638
        except OSError, e:
688
639
            if e.errno == errno.ENOENT:
689
 
                raise errors.BzrCommandError('Source location "%s" does not'
690
 
                                             ' exist.' % to_location)
 
640
                raise BzrCommandError('Source location "%s" does not'
 
641
                                      ' exist.' % to_location)
691
642
            else:
692
643
                raise
693
644
        br_from.lock_read()
713
664
            try:
714
665
                to_transport.mkdir('.')
715
666
            except errors.FileExists:
716
 
                raise errors.BzrCommandError('Target directory "%s" already'
717
 
                                             ' exists.' % to_location)
 
667
                raise BzrCommandError('Target directory "%s" already'
 
668
                                      ' exists.' % to_location)
718
669
            except errors.NoSuchFile:
719
 
                raise errors.BzrCommandError('Parent of "%s" does not exist.'
720
 
                                             % to_location)
 
670
                raise BzrCommandError('Parent of "%s" does not exist.' %
 
671
                                      to_location)
721
672
            try:
722
673
                # preserve whatever source format we have.
723
674
                dir = br_from.bzrdir.sprout(to_transport.base,
726
677
            except errors.NoSuchRevision:
727
678
                to_transport.delete_tree('.')
728
679
                msg = "The branch %s has no revision %s." % (from_location, revision[0])
729
 
                raise errors.BzrCommandError(msg)
 
680
                raise BzrCommandError(msg)
730
681
            except errors.UnlistableBranch:
731
682
                osutils.rmtree(to_location)
732
683
                msg = "The branch %s cannot be used as a --basis" % (basis,)
733
 
                raise errors.BzrCommandError(msg)
 
684
                raise BzrCommandError(msg)
734
685
            if name:
735
686
                branch.control_files.put_utf8('branch-name', name)
736
687
            note('Branched %d revision(s).' % branch.revno())
775
726
        if revision is None:
776
727
            revision = [None]
777
728
        elif len(revision) > 1:
778
 
            raise errors.BzrCommandError(
 
729
            raise BzrCommandError(
779
730
                'bzr checkout --revision takes exactly 1 revision value')
780
731
        if branch_location is None:
781
732
            branch_location = osutils.getcwd()
790
741
        # if the source and to_location are the same, 
791
742
        # and there is no working tree,
792
743
        # then reconstitute a branch
793
 
        if (osutils.abspath(to_location) ==
 
744
        if (osutils.abspath(to_location) == 
794
745
            osutils.abspath(branch_location)):
795
746
            try:
796
747
                source.bzrdir.open_workingtree()
801
752
            os.mkdir(to_location)
802
753
        except OSError, e:
803
754
            if e.errno == errno.EEXIST:
804
 
                raise errors.BzrCommandError('Target directory "%s" already'
805
 
                                             ' exists.' % to_location)
 
755
                raise BzrCommandError('Target directory "%s" already'
 
756
                                      ' exists.' % to_location)
806
757
            if e.errno == errno.ENOENT:
807
 
                raise errors.BzrCommandError('Parent of "%s" does not exist.'
808
 
                                             % to_location)
 
758
                raise BzrCommandError('Parent of "%s" does not exist.' %
 
759
                                      to_location)
809
760
            else:
810
761
                raise
811
762
        old_format = bzrdir.BzrDirFormat.get_default_format()
826
777
 
827
778
    @display_command
828
779
    def run(self, dir=u'.'):
 
780
        from bzrlib.tree import find_renames
829
781
        tree = WorkingTree.open_containing(dir)[0]
830
782
        old_inv = tree.basis_tree().inventory
831
783
        new_inv = tree.read_working_inventory()
832
 
        renames = list(_mod_tree.find_renames(old_inv, new_inv))
 
784
        renames = list(find_renames(old_inv, new_inv))
833
785
        renames.sort()
834
786
        for old_name, new_name in renames:
835
787
            self.outf.write("%s => %s\n" % (old_name, new_name))
850
802
 
851
803
    def run(self, dir='.'):
852
804
        tree = WorkingTree.open_containing(dir)[0]
853
 
        master = tree.branch.get_master_branch()
854
 
        if master is not None:
855
 
            tree.lock_write()
856
 
        else:
857
 
            tree.lock_tree_write()
 
805
        tree.lock_write()
 
806
        existing_pending_merges = tree.pending_merges()
858
807
        try:
859
 
            existing_pending_merges = tree.get_parent_ids()[1:]
860
 
            last_rev = tree.last_revision()
 
808
            last_rev = tree.last_revision() 
861
809
            if last_rev == tree.branch.last_revision():
862
810
                # may be up to date, check master too.
863
811
                master = tree.branch.get_master_branch()
868
816
            conflicts = tree.update()
869
817
            revno = tree.branch.revision_id_to_revno(tree.last_revision())
870
818
            note('Updated to revision %d.' % (revno,))
871
 
            if tree.get_parent_ids()[1:] != existing_pending_merges:
 
819
            if tree.pending_merges() != existing_pending_merges:
872
820
                note('Your local commits will now show as pending merges with '
873
821
                     "'bzr status', and can be committed with 'bzr commit'.")
874
822
            if conflicts != 0:
918
866
        tree, file_list = tree_files(file_list)
919
867
        if new is False:
920
868
            if file_list is None:
921
 
                raise errors.BzrCommandError('Specify one or more files to'
922
 
                                             ' remove, or use --new.')
 
869
                raise BzrCommandError('Specify one or more files to remove, or'
 
870
                                      ' use --new.')
923
871
        else:
924
872
            added = tree.changes_from(tree.basis_tree(),
925
873
                specific_files=file_list).added
926
874
            file_list = sorted([f[0] for f in added], reverse=True)
927
875
            if len(file_list) == 0:
928
 
                raise errors.BzrCommandError('No matching files.')
 
876
                raise BzrCommandError('No matching files.')
929
877
        tree.remove(file_list, verbose=verbose, to_file=self.outf)
930
878
 
931
879
 
944
892
    def run(self, filename):
945
893
        tree, relpath = WorkingTree.open_containing(filename)
946
894
        i = tree.inventory.path2id(relpath)
947
 
        if i is None:
948
 
            raise errors.BzrError("%r is not a versioned file" % filename)
 
895
        if i == None:
 
896
            raise BzrError("%r is not a versioned file" % filename)
949
897
        else:
950
898
            self.outf.write(i + '\n')
951
899
 
965
913
        tree, relpath = WorkingTree.open_containing(filename)
966
914
        inv = tree.inventory
967
915
        fid = inv.path2id(relpath)
968
 
        if fid is None:
969
 
            raise errors.BzrError("%r is not a versioned file" % filename)
 
916
        if fid == None:
 
917
            raise BzrError("%r is not a versioned file" % filename)
970
918
        for fip in inv.get_idpath(fid):
971
919
            self.outf.write(fip + '\n')
972
920
 
1029
977
            last_revision = wt.last_revision()
1030
978
 
1031
979
        revision_ids = b.repository.get_ancestry(last_revision)
1032
 
        assert revision_ids[0] is None
 
980
        assert revision_ids[0] == None
1033
981
        revision_ids.pop(0)
1034
982
        for revision_id in revision_ids:
1035
983
            self.outf.write(revision_id + '\n')
1086
1034
                    
1087
1035
        try:
1088
1036
            existing_bzrdir = bzrdir.BzrDir.open(location)
1089
 
        except errors.NotBranchError:
 
1037
        except NotBranchError:
1090
1038
            # really a NotBzrDir error...
1091
1039
            bzrdir.BzrDir.create_branch_convenience(location, format=format)
1092
1040
        else:
1093
 
            from bzrlib.transport.local import LocalTransport
1094
1041
            if existing_bzrdir.has_branch():
1095
1042
                if (isinstance(to_transport, LocalTransport)
1096
1043
                    and not existing_bzrdir.has_workingtree()):
1197
1144
            new_label = 'new/'
1198
1145
        else:
1199
1146
            if not ':' in prefix:
1200
 
                 raise errors.BzrError("--diff-prefix expects two values"
1201
 
                                       " separated by a colon")
 
1147
                 raise BzrError("--diff-prefix expects two values separated by a colon")
1202
1148
            old_label, new_label = prefix.split(":")
1203
1149
        
1204
1150
        try:
1206
1152
            tree2 = None
1207
1153
            b = None
1208
1154
            b2 = None
1209
 
        except errors.FileInWrongBranch:
 
1155
        except FileInWrongBranch:
1210
1156
            if len(file_list) != 2:
1211
 
                raise errors.BzrCommandError("Files are in different branches")
 
1157
                raise BzrCommandError("Files are in different branches")
1212
1158
 
1213
1159
            tree1, file1 = WorkingTree.open_containing(file_list[0])
1214
1160
            tree2, file2 = WorkingTree.open_containing(file_list[1])
1215
1161
            if file1 != "" or file2 != "":
1216
1162
                # FIXME diff those two files. rbc 20051123
1217
 
                raise errors.BzrCommandError("Files are in different branches")
 
1163
                raise BzrCommandError("Files are in different branches")
1218
1164
            file_list = None
1219
 
        except errors.NotBranchError:
 
1165
        except NotBranchError:
1220
1166
            if (revision is not None and len(revision) == 2
1221
1167
                and not revision[0].needs_branch()
1222
1168
                and not revision[1].needs_branch()):
1227
1173
                raise
1228
1174
        if revision is not None:
1229
1175
            if tree2 is not None:
1230
 
                raise errors.BzrCommandError("Can't specify -r with two branches")
 
1176
                raise BzrCommandError("Can't specify -r with two branches")
1231
1177
            if (len(revision) == 1) or (revision[1].spec is None):
1232
1178
                return diff_cmd_helper(tree1, file_list, diff_options,
1233
1179
                                       revision[0], 
1237
1183
                                       revision[0], revision[1],
1238
1184
                                       old_label=old_label, new_label=new_label)
1239
1185
            else:
1240
 
                raise errors.BzrCommandError('bzr diff --revision takes exactly'
1241
 
                                             ' one or two revision identifiers')
 
1186
                raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
1242
1187
        else:
1243
1188
            if tree2 is not None:
1244
1189
                return show_diff_trees(tree1, tree2, sys.stdout, 
1296
1241
        for file_id in inv:
1297
1242
            if file_id in basis_inv:
1298
1243
                continue
1299
 
            if inv.is_root(file_id) and len(basis_inv) == 0:
1300
 
                continue
1301
1244
            path = inv.id2path(file_id)
1302
1245
            if not os.access(osutils.abspath(path), os.F_OK):
1303
1246
                continue
1384
1327
        else:
1385
1328
            # local dir only
1386
1329
            # FIXME ? log the current subdir only RBC 20060203 
1387
 
            if revision is not None \
1388
 
                    and len(revision) > 0 and revision[0].get_branch():
1389
 
                location = revision[0].get_branch()
1390
 
            else:
1391
 
                location = '.'
1392
 
            dir, relpath = bzrdir.BzrDir.open_containing(location)
 
1330
            dir, relpath = bzrdir.BzrDir.open_containing('.')
1393
1331
            b = dir.open_branch()
1394
1332
 
1395
1333
        if revision is None:
1398
1336
        elif len(revision) == 1:
1399
1337
            rev1 = rev2 = revision[0].in_history(b).revno
1400
1338
        elif len(revision) == 2:
1401
 
            if revision[1].get_branch() != revision[0].get_branch():
1402
 
                # b is taken from revision[0].get_branch(), and
1403
 
                # show_log will use its revision_history. Having
1404
 
                # different branches will lead to weird behaviors.
1405
 
                raise errors.BzrCommandError(
1406
 
                    "Log doesn't accept two revisions in different branches.")
1407
1339
            if revision[0].spec is None:
1408
1340
                # missing begin-range means first revision
1409
1341
                rev1 = 1
1416
1348
            else:
1417
1349
                rev2 = revision[1].in_history(b).revno
1418
1350
        else:
1419
 
            raise errors.BzrCommandError('bzr log --revision takes one or two values.')
 
1351
            raise BzrCommandError('bzr log --revision takes one or two values.')
1420
1352
 
1421
1353
        # By this point, the revision numbers are converted to the +ve
1422
1354
        # form if they were supplied in the -ve form, so we can do
1424
1356
        if rev1 > rev2:
1425
1357
            (rev2, rev1) = (rev1, rev2)
1426
1358
 
1427
 
        if (log_format is None):
 
1359
        if (log_format == None):
1428
1360
            default = b.get_config().log_format()
1429
1361
            log_format = get_log_format(long=long, short=short, line=line, 
1430
1362
                                        default=default)
1496
1428
            null=False):
1497
1429
 
1498
1430
        if verbose and null:
1499
 
            raise errors.BzrCommandError('Cannot set both --verbose and --null')
 
1431
            raise BzrCommandError('Cannot set both --verbose and --null')
1500
1432
        all = not (unknown or versioned or ignored)
1501
1433
 
1502
1434
        selection = {'I':ignored, '?':unknown, 'V':versioned}
1510
1442
            tree = tree.branch.repository.revision_tree(
1511
1443
                revision[0].in_history(tree.branch).rev_id)
1512
1444
 
1513
 
        for fp, fc, kind, fid, entry in tree.list_files(include_root=False):
 
1445
        for fp, fc, kind, fid, entry in tree.list_files():
1514
1446
            if fp.startswith(relpath):
1515
1447
                fp = fp[len(relpath):]
1516
1448
                if non_recursive and '/' in fp:
1568
1500
                print pattern
1569
1501
            return
1570
1502
        if name_pattern is None:
1571
 
            raise errors.BzrCommandError("ignore requires a NAME_PATTERN")
 
1503
            raise BzrCommandError("ignore requires a NAME_PATTERN")
1572
1504
        tree, relpath = WorkingTree.open_containing(u'.')
1573
1505
        ifn = tree.abspath('.bzrignore')
1574
1506
        if os.path.exists(ifn):
1631
1563
        try:
1632
1564
            revno = int(revno)
1633
1565
        except ValueError:
1634
 
            raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
 
1566
            raise BzrCommandError("not a valid revision-number: %r" % revno)
1635
1567
 
1636
1568
        print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
1637
1569
 
1669
1601
            rev_id = b.last_revision()
1670
1602
        else:
1671
1603
            if len(revision) != 1:
1672
 
                raise errors.BzrError('bzr export --revision takes exactly'
1673
 
                                      ' 1 argument')
 
1604
                raise BzrError('bzr export --revision takes exactly 1 argument')
1674
1605
            rev_id = revision[0].in_history(b).rev_id
1675
1606
        t = b.repository.revision_tree(rev_id)
1676
1607
        try:
1677
1608
            export(t, dest, format, root)
1678
1609
        except errors.NoSuchExportFormat, e:
1679
 
            raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
 
1610
            raise BzrCommandError('Unsupported export format: %s' % e.format)
1680
1611
 
1681
1612
 
1682
1613
class cmd_cat(Command):
1688
1619
    @display_command
1689
1620
    def run(self, filename, revision=None):
1690
1621
        if revision is not None and len(revision) != 1:
1691
 
            raise errors.BzrCommandError("bzr cat --revision takes exactly one number")
 
1622
            raise BzrCommandError("bzr cat --revision takes exactly one number")
1692
1623
        tree = None
1693
1624
        try:
1694
1625
            tree, relpath = WorkingTree.open_containing(filename)
1695
1626
            b = tree.branch
1696
 
        except errors.NotBranchError:
 
1627
        except NotBranchError:
1697
1628
            pass
1698
1629
 
1699
1630
        if tree is None:
1700
1631
            b, relpath = Branch.open_containing(filename)
1701
 
        if revision is not None and revision[0].get_branch() is not None:
1702
 
            b = Branch.open(revision[0].get_branch())
1703
1632
        if revision is None:
1704
1633
            revision_id = b.last_revision()
1705
1634
        else:
1787
1716
            template = make_commit_message_template(tree, selected_list)
1788
1717
            message = edit_commit_message(template)
1789
1718
            if message is None:
1790
 
                raise errors.BzrCommandError("please specify a commit message"
1791
 
                                             " with either --message or --file")
 
1719
                raise BzrCommandError("please specify a commit message"
 
1720
                                      " with either --message or --file")
1792
1721
        elif message and file:
1793
 
            raise errors.BzrCommandError("please specify either --message or --file")
 
1722
            raise BzrCommandError("please specify either --message or --file")
1794
1723
        
1795
1724
        if file:
1796
1725
            message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1797
1726
 
1798
1727
        if message == "":
1799
 
            raise errors.BzrCommandError("empty commit message specified")
 
1728
            raise BzrCommandError("empty commit message specified")
1800
1729
        
1801
1730
        if verbose:
1802
1731
            reporter = ReportCommitToLog()
1810
1739
        except PointlessCommit:
1811
1740
            # FIXME: This should really happen before the file is read in;
1812
1741
            # perhaps prepare the commit; get the message; then actually commit
1813
 
            raise errors.BzrCommandError("no changes to commit."
1814
 
                                         " use --unchanged to commit anyhow")
 
1742
            raise BzrCommandError("no changes to commit."
 
1743
                                  " use --unchanged to commit anyhow")
1815
1744
        except ConflictsInTree:
1816
 
            raise errors.BzrCommandError("Conflicts detected in working tree.  "
 
1745
            raise BzrCommandError("Conflicts detected in working tree.  "
1817
1746
                'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
1818
1747
        except StrictCommitFailed:
1819
 
            raise errors.BzrCommandError("Commit refused because there are unknown "
1820
 
                                         "files in the working tree.")
 
1748
            raise BzrCommandError("Commit refused because there are unknown "
 
1749
                                  "files in the working tree.")
1821
1750
        except errors.BoundBranchOutOfDate, e:
1822
 
            raise errors.BzrCommandError(str(e) + "\n"
 
1751
            raise BzrCommandError(str(e) + "\n"
1823
1752
                'To commit to master branch, run update and then commit.\n'
1824
1753
                'You can also pass --local to commit to continue working '
1825
1754
                'disconnected.')
1909
1838
            # use branch if we're inside one; otherwise global config
1910
1839
            try:
1911
1840
                c = Branch.open_containing('.')[0].get_config()
1912
 
            except errors.NotBranchError:
 
1841
            except NotBranchError:
1913
1842
                c = config.GlobalConfig()
1914
1843
            if email:
1915
1844
                self.outf.write(c.user_email() + '\n')
1920
1849
        # display a warning if an email address isn't included in the given name.
1921
1850
        try:
1922
1851
            config.extract_email_address(name)
1923
 
        except errors.NoEmailInUsername, e:
 
1852
        except BzrError, e:
1924
1853
            warning('"%s" does not seem to contain an email address.  '
1925
1854
                    'This is allowed, but not recommended.', name)
1926
1855
        
1988
1917
            return FakeNFSServer
1989
1918
        msg = "No known transport type %s. Supported types are: sftp\n" %\
1990
1919
            (typestring)
1991
 
        raise errors.BzrCommandError(msg)
 
1920
        raise BzrCommandError(msg)
1992
1921
 
1993
1922
    hidden = True
1994
1923
    takes_args = ['testspecs*']
2004
1933
                     Option('lsprof-timed',
2005
1934
                            help='generate lsprof output for benchmarked'
2006
1935
                                 ' sections of code.'),
2007
 
                     Option('cache-dir', type=str,
2008
 
                            help='a directory to cache intermediate'
2009
 
                                 ' benchmark steps'),
2010
1936
                     ]
2011
1937
 
2012
1938
    def run(self, testspecs_list=None, verbose=None, one=False,
2013
1939
            keep_output=False, transport=None, benchmark=None,
2014
 
            lsprof_timed=None, cache_dir=None):
 
1940
            lsprof_timed=None):
2015
1941
        import bzrlib.ui
2016
1942
        from bzrlib.tests import selftest
2017
1943
        import bzrlib.benchmarks as benchmarks
2018
 
        from bzrlib.benchmarks import tree_creator
2019
 
 
2020
 
        if cache_dir is not None:
2021
 
            tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2022
1944
        # we don't want progress meters from the tests to go to the
2023
1945
        # real output; and we don't want log messages cluttering up
2024
1946
        # the real logs.
2037
1959
                test_suite_factory = benchmarks.test_suite
2038
1960
                if verbose is None:
2039
1961
                    verbose = True
2040
 
                # TODO: should possibly lock the history file...
2041
 
                benchfile = open(".perf_history", "at")
2042
1962
            else:
2043
1963
                test_suite_factory = None
2044
1964
                if verbose is None:
2045
1965
                    verbose = False
2046
 
                benchfile = None
2047
 
            try:
2048
 
                result = selftest(verbose=verbose, 
2049
 
                                  pattern=pattern,
2050
 
                                  stop_on_failure=one, 
2051
 
                                  keep_output=keep_output,
2052
 
                                  transport=transport,
2053
 
                                  test_suite_factory=test_suite_factory,
2054
 
                                  lsprof_timed=lsprof_timed,
2055
 
                                  bench_history=benchfile)
2056
 
            finally:
2057
 
                if benchfile is not None:
2058
 
                    benchfile.close()
 
1966
            result = selftest(verbose=verbose, 
 
1967
                              pattern=pattern,
 
1968
                              stop_on_failure=one, 
 
1969
                              keep_output=keep_output,
 
1970
                              transport=transport,
 
1971
                              test_suite_factory=test_suite_factory,
 
1972
                              lsprof_timed=lsprof_timed)
2059
1973
            if result:
2060
1974
                info('tests passed')
2061
1975
            else:
2065
1979
            ui.ui_factory = save_ui
2066
1980
 
2067
1981
 
 
1982
def _get_bzr_branch():
 
1983
    """If bzr is run from a branch, return Branch or None"""
 
1984
    from os.path import dirname
 
1985
    
 
1986
    try:
 
1987
        branch = Branch.open(dirname(osutils.abspath(dirname(__file__))))
 
1988
        return branch
 
1989
    except errors.BzrError:
 
1990
        return None
 
1991
    
 
1992
 
 
1993
def show_version():
 
1994
    import bzrlib
 
1995
    print "Bazaar (bzr) %s" % bzrlib.__version__
 
1996
    # is bzrlib itself in a branch?
 
1997
    branch = _get_bzr_branch()
 
1998
    if branch:
 
1999
        rh = branch.revision_history()
 
2000
        revno = len(rh)
 
2001
        print "  bzr checkout, revision %d" % (revno,)
 
2002
        print "  nick: %s" % (branch.nick,)
 
2003
        if rh:
 
2004
            print "  revid: %s" % (rh[-1],)
 
2005
    print "Using python interpreter:", sys.executable
 
2006
    import site
 
2007
    print "Using python standard library:", os.path.dirname(site.__file__)
 
2008
    print "Using bzrlib:",
 
2009
    if len(bzrlib.__path__) > 1:
 
2010
        # print repr, which is a good enough way of making it clear it's
 
2011
        # more than one element (eg ['/foo/bar', '/foo/bzr'])
 
2012
        print repr(bzrlib.__path__)
 
2013
    else:
 
2014
        print bzrlib.__path__[0]
 
2015
 
 
2016
    print
 
2017
    print bzrlib.__copyright__
 
2018
    print "http://bazaar-vcs.org/"
 
2019
    print
 
2020
    print "bzr comes with ABSOLUTELY NO WARRANTY.  bzr is free software, and"
 
2021
    print "you may use, modify and redistribute it under the terms of the GNU"
 
2022
    print "General Public License version 2 or later."
 
2023
 
 
2024
 
2068
2025
class cmd_version(Command):
2069
2026
    """Show version of bzr."""
2070
2027
 
2071
2028
    @display_command
2072
2029
    def run(self):
2073
 
        from bzrlib.version import show_version
2074
2030
        show_version()
2075
2031
 
2076
2032
 
2093
2049
    
2094
2050
    @display_command
2095
2051
    def run(self, branch, other):
2096
 
        from bzrlib.revision import MultipleRevisionSources
 
2052
        from bzrlib.revision import common_ancestor, MultipleRevisionSources
2097
2053
        
2098
2054
        branch1 = Branch.open_containing(branch)[0]
2099
2055
        branch2 = Branch.open_containing(other)[0]
2161
2117
                            ' from a working copy, instead of branch changes')]
2162
2118
 
2163
2119
    def help(self):
 
2120
        from merge import merge_type_help
2164
2121
        from inspect import getdoc
2165
 
        return getdoc(self) + '\n' + _mod_merge.merge_type_help()
 
2122
        return getdoc(self) + '\n' + merge_type_help() 
2166
2123
 
2167
2124
    def run(self, branch=None, revision=None, force=False, merge_type=None,
2168
2125
            show_base=False, reprocess=False, remember=False, 
2169
2126
            uncommitted=False):
2170
2127
        if merge_type is None:
2171
 
            merge_type = _mod_merge.Merge3Merger
 
2128
            merge_type = Merge3Merger
2172
2129
 
2173
2130
        tree = WorkingTree.open_containing(u'.')[0]
2174
2131
 
2175
2132
        if branch is not None:
2176
2133
            try:
2177
2134
                reader = bundle.read_bundle_from_url(branch)
2178
 
            except errors.NotABundle:
 
2135
            except NotABundle:
2179
2136
                pass # Continue on considering this url a Branch
2180
2137
            else:
2181
2138
                conflicts = merge_bundle(reader, tree, not force, merge_type,
2185
2142
                else:
2186
2143
                    return 1
2187
2144
 
2188
 
        if revision is None \
2189
 
                or len(revision) < 1 or revision[0].needs_branch():
2190
 
            branch = self._get_remembered_parent(tree, branch, 'Merging from')
 
2145
        branch = self._get_remembered_parent(tree, branch, 'Merging from')
2191
2146
 
2192
2147
        if revision is None or len(revision) < 1:
2193
2148
            if uncommitted:
2199
2154
            other_branch, path = Branch.open_containing(branch)
2200
2155
        else:
2201
2156
            if uncommitted:
2202
 
                raise errors.BzrCommandError('Cannot use --uncommitted and'
2203
 
                                             ' --revision at the same time.')
2204
 
            branch = revision[0].get_branch() or branch
 
2157
                raise BzrCommandError('Cannot use --uncommitted and --revision'
 
2158
                                      ' at the same time.')
2205
2159
            if len(revision) == 1:
2206
2160
                base = [None, None]
2207
2161
                other_branch, path = Branch.open_containing(branch)
2210
2164
            else:
2211
2165
                assert len(revision) == 2
2212
2166
                if None in revision:
2213
 
                    raise errors.BzrCommandError(
2214
 
                        "Merge doesn't permit empty revision specifier.")
2215
 
                base_branch, path = Branch.open_containing(branch)
2216
 
                branch1 = revision[1].get_branch() or branch
2217
 
                other_branch, path1 = Branch.open_containing(branch1)
2218
 
                if revision[0].get_branch() is not None:
2219
 
                    # then path was obtained from it, and is None.
2220
 
                    path = path1
 
2167
                    raise BzrCommandError(
 
2168
                        "Merge doesn't permit that revision specifier.")
 
2169
                other_branch, path = Branch.open_containing(branch)
2221
2170
 
2222
 
                base = [branch, revision[0].in_history(base_branch).revno]
2223
 
                other = [branch1, revision[1].in_history(other_branch).revno]
 
2171
                base = [branch, revision[0].in_history(other_branch).revno]
 
2172
                other = [branch, revision[1].in_history(other_branch).revno]
2224
2173
 
2225
2174
        if tree.branch.get_parent() is None or remember:
2226
2175
            tree.branch.set_parent(other_branch.base)
2232
2181
        pb = ui.ui_factory.nested_progress_bar()
2233
2182
        try:
2234
2183
            try:
2235
 
                conflict_count = _merge_helper(
2236
 
                    other, base, check_clean=(not force),
2237
 
                    merge_type=merge_type,
2238
 
                    reprocess=reprocess,
2239
 
                    show_base=show_base,
2240
 
                    pb=pb, file_list=interesting_files)
 
2184
                conflict_count = merge(other, base, check_clean=(not force),
 
2185
                                       merge_type=merge_type,
 
2186
                                       reprocess=reprocess,
 
2187
                                       show_base=show_base,
 
2188
                                       pb=pb, file_list=interesting_files)
2241
2189
            finally:
2242
2190
                pb.finished()
2243
2191
            if conflict_count != 0:
2264
2212
        stored_location = tree.branch.get_parent()
2265
2213
        mutter("%s", stored_location)
2266
2214
        if stored_location is None:
2267
 
            raise errors.BzrCommandError("No location specified or remembered")
 
2215
            raise BzrCommandError("No location specified or remembered")
2268
2216
        display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2269
2217
        self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
2270
2218
        return stored_location
2297
2245
                            "conflicts")]
2298
2246
 
2299
2247
    def help(self):
 
2248
        from merge import merge_type_help
2300
2249
        from inspect import getdoc
2301
 
        return getdoc(self) + '\n' + _mod_merge.merge_type_help()
 
2250
        return getdoc(self) + '\n' + merge_type_help() 
2302
2251
 
2303
2252
    def run(self, file_list=None, merge_type=None, show_base=False,
2304
2253
            reprocess=False):
 
2254
        from bzrlib.merge import merge_inner, transform_tree
2305
2255
        if merge_type is None:
2306
 
            merge_type = _mod_merge.Merge3Merger
 
2256
            merge_type = Merge3Merger
2307
2257
        tree, file_list = tree_files(file_list)
2308
2258
        tree.lock_write()
2309
2259
        try:
2310
 
            parents = tree.get_parent_ids()
2311
 
            if len(parents) != 2:
2312
 
                raise errors.BzrCommandError("Sorry, remerge only works after normal"
2313
 
                                             " merges.  Not cherrypicking or"
2314
 
                                             " multi-merges.")
 
2260
            pending_merges = tree.pending_merges() 
 
2261
            if len(pending_merges) != 1:
 
2262
                raise BzrCommandError("Sorry, remerge only works after normal"
 
2263
                                      " merges.  Not cherrypicking or"
 
2264
                                      " multi-merges.")
2315
2265
            repository = tree.branch.repository
2316
 
            base_revision = common_ancestor(parents[0],
2317
 
                                            parents[1], repository)
 
2266
            base_revision = common_ancestor(tree.branch.last_revision(), 
 
2267
                                            pending_merges[0], repository)
2318
2268
            base_tree = repository.revision_tree(base_revision)
2319
 
            other_tree = repository.revision_tree(parents[1])
 
2269
            other_tree = repository.revision_tree(pending_merges[0])
2320
2270
            interesting_ids = None
2321
2271
            new_conflicts = []
2322
2272
            conflicts = tree.conflicts()
2325
2275
                for filename in file_list:
2326
2276
                    file_id = tree.path2id(filename)
2327
2277
                    if file_id is None:
2328
 
                        raise errors.NotVersionedError(filename)
 
2278
                        raise NotVersionedError(filename)
2329
2279
                    interesting_ids.add(file_id)
2330
2280
                    if tree.kind(file_id) != "directory":
2331
2281
                        continue
2333
2283
                    for name, ie in tree.inventory.iter_entries(file_id):
2334
2284
                        interesting_ids.add(ie.file_id)
2335
2285
                new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2336
 
            else:
2337
 
                # Remerge only supports resolving contents conflicts
2338
 
                allowed_conflicts = ('text conflict', 'contents conflict')
2339
 
                restore_files = [c.path for c in conflicts
2340
 
                                 if c.typestring in allowed_conflicts]
2341
 
            _mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
 
2286
            transform_tree(tree, tree.basis_tree(), interesting_ids)
2342
2287
            tree.set_conflicts(ConflictList(new_conflicts))
2343
 
            if file_list is not None:
 
2288
            if file_list is None:
 
2289
                restore_files = list(tree.iter_conflicts())
 
2290
            else:
2344
2291
                restore_files = file_list
2345
2292
            for filename in restore_files:
2346
2293
                try:
2347
2294
                    restore(tree.abspath(filename))
2348
 
                except errors.NotConflicted:
 
2295
                except NotConflicted:
2349
2296
                    pass
2350
 
            conflicts = _mod_merge.merge_inner(
2351
 
                                      tree.branch, other_tree, base_tree,
2352
 
                                      this_tree=tree,
2353
 
                                      interesting_ids=interesting_ids,
2354
 
                                      other_rev_id=parents[1],
2355
 
                                      merge_type=merge_type,
2356
 
                                      show_base=show_base,
2357
 
                                      reprocess=reprocess)
 
2297
            conflicts = merge_inner(tree.branch, other_tree, base_tree,
 
2298
                                    this_tree=tree,
 
2299
                                    interesting_ids=interesting_ids, 
 
2300
                                    other_rev_id=pending_merges[0], 
 
2301
                                    merge_type=merge_type, 
 
2302
                                    show_base=show_base,
 
2303
                                    reprocess=reprocess)
2358
2304
        finally:
2359
2305
            tree.unlock()
2360
2306
        if conflicts > 0:
2363
2309
            return 0
2364
2310
 
2365
2311
class cmd_revert(Command):
2366
 
    """Revert files to a previous revision.
2367
 
 
2368
 
    Giving a list of files will revert only those files.  Otherwise, all files
2369
 
    will be reverted.  If the revision is not specified with '--revision', the
2370
 
    last committed revision is used.
2371
 
 
2372
 
    To remove only some changes, without reverting to a prior version, use
2373
 
    merge instead.  For example, "merge . --r-2..-3" will remove the changes
2374
 
    introduced by -2, without affecting the changes introduced by -1.  Or
2375
 
    to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
2376
 
    
2377
 
    By default, any files that have been manually changed will be backed up
2378
 
    first.  (Files changed only by merge are not backed up.)  Backup files have
2379
 
    '.~#~' appended to their name, where # is a number.
2380
 
 
2381
 
    When you provide files, you can use their current pathname or the pathname
2382
 
    from the target revision.  So you can use revert to "undelete" a file by
2383
 
    name.  If you name a directory, all the contents of that directory will be
2384
 
    reverted.
 
2312
    """Reverse all changes since the last commit.
 
2313
 
 
2314
    Only versioned files are affected.  Specify filenames to revert only 
 
2315
    those files.  By default, any files that are changed will be backed up
 
2316
    first.  Backup files have a '~' appended to their name.
2385
2317
    """
2386
2318
    takes_options = ['revision', 'no-backup']
2387
2319
    takes_args = ['file*']
2388
2320
    aliases = ['merge-revert']
2389
2321
 
2390
2322
    def run(self, revision=None, no_backup=False, file_list=None):
 
2323
        from bzrlib.commands import parse_spec
2391
2324
        if file_list is not None:
2392
2325
            if len(file_list) == 0:
2393
 
                raise errors.BzrCommandError("No files specified")
 
2326
                raise BzrCommandError("No files specified")
2394
2327
        else:
2395
2328
            file_list = []
2396
2329
        
2399
2332
            # FIXME should be tree.last_revision
2400
2333
            rev_id = tree.last_revision()
2401
2334
        elif len(revision) != 1:
2402
 
            raise errors.BzrCommandError('bzr revert --revision takes exactly 1 argument')
 
2335
            raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
2403
2336
        else:
2404
2337
            rev_id = revision[0].in_history(tree.branch).rev_id
2405
2338
        pb = ui.ui_factory.nested_progress_bar()
2491
2424
        if other_branch is None:
2492
2425
            other_branch = parent
2493
2426
            if other_branch is None:
2494
 
                raise errors.BzrCommandError("No peer location known or specified.")
 
2427
                raise BzrCommandError("No peer location known or specified.")
2495
2428
            print "Using last location: " + local_branch.get_parent()
2496
2429
        remote_branch = Branch.open(other_branch)
2497
2430
        if remote_branch.base == local_branch.base:
2501
2434
            remote_branch.lock_read()
2502
2435
            try:
2503
2436
                local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2504
 
                if (log_format is None):
 
2437
                if (log_format == None):
2505
2438
                    default = local_branch.get_config().log_format()
2506
2439
                    log_format = get_log_format(long=long, short=short, 
2507
2440
                                                line=line, default=default)
2555
2488
        import bzrlib.plugin
2556
2489
        from inspect import getdoc
2557
2490
        for name, plugin in bzrlib.plugin.all_plugins().items():
2558
 
            if getattr(plugin, '__path__', None) is not None:
 
2491
            if hasattr(plugin, '__path__'):
2559
2492
                print plugin.__path__[0]
2560
 
            elif getattr(plugin, '__file__', None) is not None:
 
2493
            elif hasattr(plugin, '__file__'):
2561
2494
                print plugin.__file__
2562
2495
            else:
2563
 
                print repr(plugin)
 
2496
                print `plugin`
2564
2497
                
2565
2498
            d = getdoc(plugin)
2566
2499
            if d:
2569
2502
 
2570
2503
class cmd_testament(Command):
2571
2504
    """Show testament (signing-form) of a revision."""
2572
 
    takes_options = ['revision', 
2573
 
                     Option('long', help='Produce long-format testament'), 
 
2505
    takes_options = ['revision', 'long', 
2574
2506
                     Option('strict', help='Produce a strict-format'
2575
2507
                            ' testament')]
2576
2508
    takes_args = ['branch?']
2626
2558
            if revision is None:
2627
2559
                revision_id = branch.last_revision()
2628
2560
            elif len(revision) != 1:
2629
 
                raise errors.BzrCommandError('bzr annotate --revision takes exactly 1 argument')
 
2561
                raise BzrCommandError('bzr annotate --revision takes exactly 1 argument')
2630
2562
            else:
2631
2563
                revision_id = revision[0].in_history(branch).rev_id
2632
2564
            file_id = tree.inventory.path2id(relpath)
2648
2580
    def run(self, revision_id_list=None, revision=None):
2649
2581
        import bzrlib.gpg as gpg
2650
2582
        if revision_id_list is not None and revision is not None:
2651
 
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
 
2583
            raise BzrCommandError('You can only supply one of revision_id or --revision')
2652
2584
        if revision_id_list is None and revision is None:
2653
 
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
 
2585
            raise BzrCommandError('You must supply either --revision or a revision_id')
2654
2586
        b = WorkingTree.open_containing(u'.')[0].branch
2655
2587
        gpg_strategy = gpg.GPGStrategy(b.get_config())
2656
2588
        if revision_id_list is not None:
2669
2601
                if to_revid is None:
2670
2602
                    to_revno = b.revno()
2671
2603
                if from_revno is None or to_revno is None:
2672
 
                    raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
 
2604
                    raise BzrCommandError('Cannot sign a range of non-revision-history revisions')
2673
2605
                for revno in range(from_revno, to_revno + 1):
2674
2606
                    b.repository.sign_revision(b.get_rev_id(revno), 
2675
2607
                                               gpg_strategy)
2676
2608
            else:
2677
 
                raise errors.BzrCommandError('Please supply either one revision, or a range.')
 
2609
                raise BzrCommandError('Please supply either one revision, or a range.')
2678
2610
 
2679
2611
 
2680
2612
class cmd_bind(Command):
2692
2624
        b_other = Branch.open(location)
2693
2625
        try:
2694
2626
            b.bind(b_other)
2695
 
        except errors.DivergedBranches:
2696
 
            raise errors.BzrCommandError('These branches have diverged.'
2697
 
                                         ' Try merging, and then bind again.')
 
2627
        except DivergedBranches:
 
2628
            raise BzrCommandError('These branches have diverged.'
 
2629
                                  ' Try merging, and then bind again.')
2698
2630
 
2699
2631
 
2700
2632
class cmd_unbind(Command):
2710
2642
    def run(self):
2711
2643
        b, relpath = Branch.open_containing(u'.')
2712
2644
        if not b.unbind():
2713
 
            raise errors.BzrCommandError('Local branch is not bound')
 
2645
            raise BzrCommandError('Local branch is not bound')
2714
2646
 
2715
2647
 
2716
2648
class cmd_uncommit(Command):
2818
2750
            pass
2819
2751
        
2820
2752
 
2821
 
class cmd_wait_until_signalled(Command):
2822
 
    """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
2823
 
 
2824
 
    This just prints a line to signal when it is ready, then blocks on stdin.
2825
 
    """
2826
 
 
2827
 
    hidden = True
2828
 
 
2829
 
    def run(self):
2830
 
        sys.stdout.write("running\n")
2831
 
        sys.stdout.flush()
2832
 
        sys.stdin.readline()
2833
 
 
2834
 
 
2835
 
class cmd_serve(Command):
2836
 
    """Run the bzr server."""
2837
 
 
2838
 
    aliases = ['server']
2839
 
 
2840
 
    takes_options = [
2841
 
        Option('inet',
2842
 
               help='serve on stdin/out for use from inetd or sshd'),
2843
 
        Option('port',
2844
 
               help='listen for connections on nominated port of the form '
2845
 
                    '[hostname:]portnumber. Passing 0 as the port number will '
2846
 
                    'result in a dynamically allocated port.',
2847
 
               type=str),
2848
 
        Option('directory',
2849
 
               help='serve contents of directory',
2850
 
               type=unicode),
2851
 
        Option('allow-writes',
2852
 
               help='By default the server is a readonly server. Supplying '
2853
 
                    '--allow-writes enables write access to the contents of '
2854
 
                    'the served directory and below. '
2855
 
                ),
2856
 
        ]
2857
 
 
2858
 
    def run(self, port=None, inet=False, directory=None, allow_writes=False):
2859
 
        from bzrlib.transport import smart
2860
 
        from bzrlib.transport import get_transport
2861
 
        if directory is None:
2862
 
            directory = os.getcwd()
2863
 
        url = urlutils.local_path_to_url(directory)
2864
 
        if not allow_writes:
2865
 
            url = 'readonly+' + url
2866
 
        t = get_transport(url)
2867
 
        if inet:
2868
 
            server = smart.SmartServerPipeStreamMedium(sys.stdin, sys.stdout, t)
2869
 
        elif port is not None:
2870
 
            if ':' in port:
2871
 
                host, port = port.split(':')
2872
 
            else:
2873
 
                host = '127.0.0.1'
2874
 
            server = smart.SmartTCPServer(t, host=host, port=int(port))
2875
 
            print 'listening on port: ', server.port
2876
 
            sys.stdout.flush()
2877
 
        else:
2878
 
            raise errors.BzrCommandError("bzr serve requires one of --inet or --port")
2879
 
        server.serve()
2880
 
 
2881
2753
 
2882
2754
# command-line interpretation helper for merge-related commands
2883
 
def _merge_helper(other_revision, base_revision,
2884
 
                  check_clean=True, ignore_zero=False,
2885
 
                  this_dir=None, backup_files=False,
2886
 
                  merge_type=None,
2887
 
                  file_list=None, show_base=False, reprocess=False,
2888
 
                  pb=DummyProgress()):
 
2755
def merge(other_revision, base_revision,
 
2756
          check_clean=True, ignore_zero=False,
 
2757
          this_dir=None, backup_files=False, merge_type=Merge3Merger,
 
2758
          file_list=None, show_base=False, reprocess=False,
 
2759
          pb=DummyProgress()):
2889
2760
    """Merge changes into a tree.
2890
2761
 
2891
2762
    base_revision
2913
2784
    clients might prefer to call merge.merge_inner(), which has less magic 
2914
2785
    behavior.
2915
2786
    """
2916
 
    # Loading it late, so that we don't always have to import bzrlib.merge
2917
 
    if merge_type is None:
2918
 
        merge_type = _mod_merge.Merge3Merger
 
2787
    from bzrlib.merge import Merger
2919
2788
    if this_dir is None:
2920
2789
        this_dir = u'.'
2921
2790
    this_tree = WorkingTree.open_containing(this_dir)[0]
2922
 
    if show_base and not merge_type is _mod_merge.Merge3Merger:
2923
 
        raise errors.BzrCommandError("Show-base is not supported for this merge"
2924
 
                                     " type. %s" % merge_type)
 
2791
    if show_base and not merge_type is Merge3Merger:
 
2792
        raise BzrCommandError("Show-base is not supported for this merge"
 
2793
                              " type. %s" % merge_type)
2925
2794
    if reprocess and not merge_type.supports_reprocess:
2926
 
        raise errors.BzrCommandError("Conflict reduction is not supported for merge"
2927
 
                                     " type %s." % merge_type)
 
2795
        raise BzrCommandError("Conflict reduction is not supported for merge"
 
2796
                              " type %s." % merge_type)
2928
2797
    if reprocess and show_base:
2929
 
        raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
 
2798
        raise BzrCommandError("Cannot do conflict reduction and show base.")
2930
2799
    try:
2931
 
        merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
2932
 
                                   pb=pb)
 
2800
        merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
2933
2801
        merger.pp = ProgressPhase("Merge phase", 5, pb)
2934
2802
        merger.pp.next_phase()
2935
2803
        merger.check_basis(check_clean)
2952
2820
    return conflicts
2953
2821
 
2954
2822
 
2955
 
# Compatibility
2956
 
merge = _merge_helper
2957
 
 
2958
 
 
2959
2823
# these get imported and then picked up by the scan for cmd_*
2960
2824
# TODO: Some more consistent way to split command definitions across files;
2961
2825
# we do need to load at least some information about them to know of 
2962
2826
# aliases.  ideally we would avoid loading the implementation until the
2963
2827
# details were needed.
2964
 
from bzrlib.cmd_version_info import cmd_version_info
2965
2828
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
2966
2829
from bzrlib.bundle.commands import cmd_bundle_revisions
2967
2830
from bzrlib.sign_my_commits import cmd_sign_my_commits