~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Martin Pool
  • Date: 2005-08-30 05:30:43 UTC
  • Revision ID: mbp@sourcefrog.net-20050830053042-58932432ee958d1e
- make get_parent() be a method of Branch; add simple tests for it

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
import bzrlib.trace
23
23
from bzrlib.trace import mutter, note, log_error, warning
24
24
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
25
 
from bzrlib.branch import Branch
 
25
from bzrlib.branch import find_branch
26
26
from bzrlib import BZRDIR
27
27
from bzrlib.commands import Command
28
28
 
62
62
    directory is shown.  Otherwise, only the status of the specified
63
63
    files or directories is reported.  If a directory is given, status
64
64
    is reported for everything inside that directory.
 
65
 
 
66
    If a revision is specified, the changes since that revision are shown.
65
67
    """
66
 
    # XXX: FIXME: bzr status should accept a -r option to show changes
67
 
    # relative to a revision, or between revisions
68
 
 
69
68
    takes_args = ['file*']
70
 
    takes_options = ['all', 'show-ids']
 
69
    takes_options = ['all', 'show-ids', 'revision']
71
70
    aliases = ['st', 'stat']
72
71
    
73
72
    def run(self, all=False, show_ids=False, file_list=None):
74
73
        if file_list:
75
 
            b = Branch.open_containing(file_list[0])
 
74
            b = find_branch(file_list[0])
76
75
            file_list = [b.relpath(x) for x in file_list]
77
76
            # special case: only one path was given and it's the root
78
77
            # of the branch
79
78
            if file_list == ['']:
80
79
                file_list = None
81
80
        else:
82
 
            b = Branch.open_containing('.')
 
81
            b = find_branch('.')
83
82
            
84
83
        from bzrlib.status import show_status
85
84
        show_status(b, show_unchanged=all, show_ids=show_ids,
93
92
    takes_args = ['revision_id']
94
93
    
95
94
    def run(self, revision_id):
96
 
        b = Branch.open_containing('.')
97
 
        sys.stdout.write(b.get_revision_xml_file(revision_id).read())
 
95
        from bzrlib.xml import pack_xml
 
96
        pack_xml(find_branch('.').get_revision(revision_id), sys.stdout)
98
97
 
99
98
 
100
99
class cmd_revno(Command):
102
101
 
103
102
    This is equal to the number of revisions on this branch."""
104
103
    def run(self):
105
 
        print Branch.open_containing('.').revno()
106
 
 
 
104
        print find_branch('.').revno()
107
105
 
108
106
class cmd_revision_info(Command):
109
107
    """Show revision number and revision id for a given revision identifier.
111
109
    hidden = True
112
110
    takes_args = ['revision_info*']
113
111
    takes_options = ['revision']
114
 
    def run(self, revision=None, revision_info_list=()):
115
 
        from bzrlib.revisionspec import RevisionSpec
 
112
    def run(self, revision=None, revision_info_list=None):
 
113
        from bzrlib.branch import find_branch
116
114
 
117
115
        revs = []
118
116
        if revision is not None:
119
117
            revs.extend(revision)
120
 
        for rev in revision_info_list:
121
 
            revs.append(RevisionSpec(revision_info_list))
 
118
        if revision_info_list is not None:
 
119
            revs.extend(revision_info_list)
122
120
        if len(revs) == 0:
123
121
            raise BzrCommandError('You must supply a revision identifier')
124
122
 
125
 
        b = Branch.open_containing('.')
 
123
        b = find_branch('.')
126
124
 
127
125
        for rev in revs:
128
 
            print '%4d %s' % rev.in_history(b)
 
126
            print '%4d %s' % b.get_revision_info(rev)
129
127
 
130
128
    
131
129
class cmd_add(Command):
146
144
    Therefore simply saying 'bzr add' will version all files that
147
145
    are currently unknown.
148
146
 
149
 
    Adding a file whose parent directory is not versioned will
150
 
    implicitly add the parent, and so on up to the root. This means
151
 
    you should never need to explictly add a directory, they'll just
152
 
    get added when you add a file in the directory.
 
147
    TODO: Perhaps adding a file whose directly is not versioned should
 
148
    recursively add that parent, rather than giving an error?
153
149
    """
154
150
    takes_args = ['file*']
155
151
    takes_options = ['verbose', 'no-recurse']
156
152
    
157
153
    def run(self, file_list, verbose=False, no_recurse=False):
158
 
        # verbose currently has no effect
159
 
        from bzrlib.add import smart_add, add_reporter_print
160
 
        smart_add(file_list, not no_recurse, add_reporter_print)
 
154
        from bzrlib.add import smart_add, _PrintAddCallback
 
155
        smart_add(file_list, verbose, not no_recurse,
 
156
                  callback=_PrintAddCallback)
161
157
 
162
158
 
163
159
 
174
170
        for d in dir_list:
175
171
            os.mkdir(d)
176
172
            if not b:
177
 
                b = Branch.open_containing(d)
 
173
                b = find_branch(d)
178
174
            b.add([d])
179
175
            print 'added', d
180
176
 
185
181
    hidden = True
186
182
    
187
183
    def run(self, filename):
188
 
        print Branch.open_containing(filename).relpath(filename)
 
184
        print find_branch(filename).relpath(filename)
189
185
 
190
186
 
191
187
 
194
190
    takes_options = ['revision', 'show-ids']
195
191
    
196
192
    def run(self, revision=None, show_ids=False):
197
 
        b = Branch.open_containing('.')
198
 
        if revision is None:
 
193
        b = find_branch('.')
 
194
        if revision == None:
199
195
            inv = b.read_working_inventory()
200
196
        else:
201
197
            if len(revision) > 1:
202
198
                raise BzrCommandError('bzr inventory --revision takes'
203
199
                    ' exactly one revision identifier')
204
 
            inv = b.get_revision_inventory(revision[0].in_history(b).rev_id)
 
200
            inv = b.get_revision_inventory(b.lookup_revision(revision[0]))
205
201
 
206
202
        for path, entry in inv.entries():
207
203
            if show_ids:
220
216
    """
221
217
    takes_args = ['source$', 'dest']
222
218
    def run(self, source_list, dest):
223
 
        b = Branch.open_containing('.')
 
219
        b = find_branch('.')
224
220
 
225
221
        # TODO: glob expansion on windows?
226
222
        b.move([b.relpath(s) for s in source_list], b.relpath(dest))
243
239
    takes_args = ['from_name', 'to_name']
244
240
    
245
241
    def run(self, from_name, to_name):
246
 
        b = Branch.open_containing('.')
 
242
        b = find_branch('.')
247
243
        b.rename_one(b.relpath(from_name), b.relpath(to_name))
248
244
 
249
245
 
265
261
    def run(self, names_list):
266
262
        if len(names_list) < 2:
267
263
            raise BzrCommandError("missing file argument")
268
 
        b = Branch.open_containing(names_list[0])
 
264
        b = find_branch(names_list[0])
269
265
 
270
266
        rel_names = [b.relpath(x) for x in names_list]
271
267
        
277
273
            if len(names_list) != 2:
278
274
                raise BzrCommandError('to mv multiple files the destination '
279
275
                                      'must be a versioned directory')
280
 
            b.rename_one(rel_names[0], rel_names[1])
281
 
            print "%s => %s" % (rel_names[0], rel_names[1])
 
276
            for pair in b.move(rel_names[0], rel_names[1]):
 
277
                print "%s => %s" % pair
282
278
            
283
279
    
284
280
 
304
300
        import tempfile
305
301
        from shutil import rmtree
306
302
        import errno
 
303
        from bzrlib.branch import pull_loc
307
304
        
308
 
        br_to = Branch.open_containing('.')
309
 
        stored_loc = br_to.get_parent()
 
305
        br_to = find_branch('.')
 
306
        stored_loc = None
 
307
        try:
 
308
            stored_loc = br_to.controlfile("x-pull", "rb").read().rstrip('\n')
 
309
        except IOError, e:
 
310
            if e.errno != errno.ENOENT:
 
311
                raise
310
312
        if location is None:
311
313
            if stored_loc is None:
312
314
                raise BzrCommandError("No pull location known or specified.")
314
316
                print "Using last location: %s" % stored_loc
315
317
                location = stored_loc
316
318
        cache_root = tempfile.mkdtemp()
317
 
        from bzrlib.errors import DivergedBranches
318
 
        br_from = Branch.open_containing(location)
319
 
        location = br_from.base
 
319
        from bzrlib.branch import DivergedBranches
 
320
        br_from = find_branch(location)
 
321
        location = pull_loc(br_from)
320
322
        old_revno = br_to.revno()
321
323
        try:
322
 
            from bzrlib.errors import DivergedBranches
323
 
            br_from = Branch.open(location)
324
 
            br_from.setup_caching(cache_root)
325
 
            location = br_from.base
 
324
            from branch import find_cached_branch, DivergedBranches
 
325
            br_from = find_cached_branch(location, cache_root)
 
326
            location = pull_loc(br_from)
326
327
            old_revno = br_to.revno()
327
328
            try:
328
329
                br_to.update_revisions(br_from)
332
333
                
333
334
            merge(('.', -1), ('.', old_revno), check_clean=False)
334
335
            if location != stored_loc:
335
 
                br_to.set_parent(location)
 
336
                br_to.controlfile("x-pull", "wb").write(location + "\n")
336
337
        finally:
337
338
            rmtree(cache_root)
338
339
 
352
353
    aliases = ['get', 'clone']
353
354
 
354
355
    def run(self, from_location, to_location=None, revision=None):
355
 
        from bzrlib.branch import copy_branch
 
356
        from bzrlib.branch import copy_branch, find_cached_branch
356
357
        import tempfile
357
358
        import errno
358
359
        from shutil import rmtree
364
365
                raise BzrCommandError(
365
366
                    'bzr branch --revision takes exactly 1 revision value')
366
367
            try:
367
 
                br_from = Branch.open(from_location)
 
368
                br_from = find_cached_branch(from_location, cache_root)
368
369
            except OSError, e:
369
370
                if e.errno == errno.ENOENT:
370
371
                    raise BzrCommandError('Source location "%s" does not'
371
372
                                          ' exist.' % to_location)
372
373
                else:
373
374
                    raise
374
 
            br_from.setup_caching(cache_root)
375
375
            if to_location is None:
376
376
                to_location = os.path.basename(from_location.rstrip("/\\"))
377
377
            try:
405
405
    takes_args = ['dir?']
406
406
 
407
407
    def run(self, dir='.'):
408
 
        b = Branch.open_containing(dir)
 
408
        b = find_branch(dir)
409
409
        old_inv = b.basis_tree().inventory
410
410
        new_inv = b.read_working_inventory()
411
411
 
422
422
    def run(self, branch=None):
423
423
        import info
424
424
 
425
 
        b = Branch.open_containing(branch)
 
425
        b = find_branch(branch)
426
426
        info.show_info(b)
427
427
 
428
428
 
436
436
    takes_options = ['verbose']
437
437
    
438
438
    def run(self, file_list, verbose=False):
439
 
        b = Branch.open_containing(file_list[0])
 
439
        b = find_branch(file_list[0])
440
440
        b.remove([b.relpath(f) for f in file_list], verbose=verbose)
441
441
 
442
442
 
450
450
    hidden = True
451
451
    takes_args = ['filename']
452
452
    def run(self, filename):
453
 
        b = Branch.open_containing(filename)
 
453
        b = find_branch(filename)
454
454
        i = b.inventory.path2id(b.relpath(filename))
455
455
        if i == None:
456
456
            raise BzrError("%r is not a versioned file" % filename)
466
466
    hidden = True
467
467
    takes_args = ['filename']
468
468
    def run(self, filename):
469
 
        b = Branch.open_containing(filename)
 
469
        b = find_branch(filename)
470
470
        inv = b.inventory
471
471
        fid = inv.path2id(b.relpath(filename))
472
472
        if fid == None:
479
479
    """Display list of revision ids on this branch."""
480
480
    hidden = True
481
481
    def run(self):
482
 
        for patchid in Branch.open_containing('.').revision_history():
 
482
        for patchid in find_branch('.').revision_history():
483
483
            print patchid
484
484
 
485
485
 
486
486
class cmd_directories(Command):
487
487
    """Display list of versioned directories in this branch."""
488
488
    def run(self):
489
 
        for name, ie in Branch.open_containing('.').read_working_inventory().directories():
 
489
        for name, ie in find_branch('.').read_working_inventory().directories():
490
490
            if name == '':
491
491
                print '.'
492
492
            else:
508
508
    """
509
509
    def run(self):
510
510
        from bzrlib.branch import Branch
511
 
        Branch.initialize('.')
 
511
        Branch('.', init=True)
512
512
 
513
513
 
514
514
class cmd_diff(Command):
535
535
    examples:
536
536
        bzr diff
537
537
        bzr diff -r1
538
 
        bzr diff -r1..2
 
538
        bzr diff -r1:2
539
539
    """
540
540
    
541
541
    takes_args = ['file*']
546
546
        from bzrlib.diff import show_diff
547
547
 
548
548
        if file_list:
549
 
            b = Branch.open_containing(file_list[0])
 
549
            b = find_branch(file_list[0])
550
550
            file_list = [b.relpath(f) for f in file_list]
551
551
            if file_list == ['']:
552
552
                # just pointing to top-of-tree
553
553
                file_list = None
554
554
        else:
555
 
            b = Branch.open_containing('.')
 
555
            b = find_branch('.')
556
556
 
557
557
        if revision is not None:
558
558
            if len(revision) == 1:
577
577
    TODO: Show files deleted since a previous revision, or between two revisions.
578
578
    """
579
579
    def run(self, show_ids=False):
580
 
        b = Branch.open_containing('.')
 
580
        b = find_branch('.')
581
581
        old = b.basis_tree()
582
582
        new = b.working_tree()
583
583
 
600
600
    def run(self):
601
601
        from bzrlib.delta import compare_trees
602
602
 
603
 
        b = Branch.open_containing('.')
 
603
        b = find_branch('.')
604
604
        td = compare_trees(b.basis_tree(), b.working_tree())
605
605
 
606
606
        for path, id, kind in td.modified:
612
612
    """List files added in working tree."""
613
613
    hidden = True
614
614
    def run(self):
615
 
        b = Branch.open_containing('.')
 
615
        b = find_branch('.')
616
616
        wt = b.working_tree()
617
617
        basis_inv = b.basis_tree().inventory
618
618
        inv = wt.inventory
634
634
    takes_args = ['filename?']
635
635
    def run(self, filename=None):
636
636
        """Print the branch root."""
637
 
        b = Branch.open_containing(filename)
638
 
        print b.base
 
637
        b = find_branch(filename)
 
638
        print getattr(b, 'base', None) or getattr(b, 'baseurl')
639
639
 
640
640
 
641
641
class cmd_log(Command):
670
670
        direction = (forward and 'forward') or 'reverse'
671
671
        
672
672
        if filename:
673
 
            b = Branch.open_containing(filename)
 
673
            b = find_branch(filename)
674
674
            fp = b.relpath(filename)
675
675
            if fp:
676
676
                file_id = b.read_working_inventory().path2id(fp)
677
677
            else:
678
678
                file_id = None  # points to branch root
679
679
        else:
680
 
            b = Branch.open_containing('.')
 
680
            b = find_branch('.')
681
681
            file_id = None
682
682
 
683
683
        if revision is None:
684
684
            rev1 = None
685
685
            rev2 = None
686
686
        elif len(revision) == 1:
687
 
            rev1 = rev2 = revision[0].in_history(b).revno
 
687
            rev1 = rev2 = b.get_revision_info(revision[0])[0]
688
688
        elif len(revision) == 2:
689
 
            rev1 = revision[0].in_history(b).revno
690
 
            rev2 = revision[1].in_history(b).revno
 
689
            rev1 = b.get_revision_info(revision[0])[0]
 
690
            rev2 = b.get_revision_info(revision[1])[0]
691
691
        else:
692
692
            raise BzrCommandError('bzr log --revision takes one or two values.')
693
693
 
729
729
    hidden = True
730
730
    takes_args = ["filename"]
731
731
    def run(self, filename):
732
 
        b = Branch.open_containing(filename)
 
732
        b = find_branch(filename)
733
733
        inv = b.read_working_inventory()
734
734
        file_id = inv.path2id(b.relpath(filename))
735
735
        for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
743
743
    """
744
744
    hidden = True
745
745
    def run(self, revision=None, verbose=False):
746
 
        b = Branch.open_containing('.')
 
746
        b = find_branch('.')
747
747
        if revision == None:
748
748
            tree = b.working_tree()
749
749
        else:
750
 
            tree = b.revision_tree(revision.in_history(b).rev_id)
 
750
            tree = b.revision_tree(b.lookup_revision(revision))
751
751
 
752
752
        for fp, fc, kind, fid in tree.list_files():
753
753
            if verbose:
768
768
    """List unknown files."""
769
769
    def run(self):
770
770
        from bzrlib.osutils import quotefn
771
 
        for f in Branch.open_containing('.').unknowns():
 
771
        for f in find_branch('.').unknowns():
772
772
            print quotefn(f)
773
773
 
774
774
 
796
796
        from bzrlib.atomicfile import AtomicFile
797
797
        import os.path
798
798
 
799
 
        b = Branch.open_containing('.')
 
799
        b = find_branch('.')
800
800
        ifn = b.abspath('.bzrignore')
801
801
 
802
802
        if os.path.exists(ifn):
836
836
 
837
837
    See also: bzr ignore"""
838
838
    def run(self):
839
 
        tree = Branch.open_containing('.').working_tree()
 
839
        tree = find_branch('.').working_tree()
840
840
        for path, file_class, kind, file_id in tree.list_files():
841
841
            if file_class != 'I':
842
842
                continue
860
860
        except ValueError:
861
861
            raise BzrCommandError("not a valid revision-number: %r" % revno)
862
862
 
863
 
        print Branch.open_containing('.').get_rev_id(revno)
 
863
        print find_branch('.').lookup_revision(revno)
864
864
 
865
865
 
866
866
class cmd_export(Command):
879
879
    takes_options = ['revision', 'format', 'root']
880
880
    def run(self, dest, revision=None, format=None, root=None):
881
881
        import os.path
882
 
        b = Branch.open_containing('.')
 
882
        b = find_branch('.')
883
883
        if revision is None:
884
884
            rev_id = b.last_patch()
885
885
        else:
886
886
            if len(revision) != 1:
887
887
                raise BzrError('bzr export --revision takes exactly 1 argument')
888
 
            rev_id = revision[0].in_history(b).rev_id
 
888
            revno, rev_id = b.get_revision_info(revision[0])
889
889
        t = b.revision_tree(rev_id)
890
890
        root, ext = os.path.splitext(dest)
891
891
        if not format:
907
907
    takes_args = ['filename']
908
908
 
909
909
    def run(self, filename, revision=None):
910
 
        if revision is None:
 
910
        if revision == None:
911
911
            raise BzrCommandError("bzr cat requires a revision number")
912
912
        elif len(revision) != 1:
913
913
            raise BzrCommandError("bzr cat --revision takes exactly one number")
914
 
        b = Branch.open_containing('.')
915
 
        b.print_file(b.relpath(filename), revision[0].in_history(b).revno)
 
914
        b = find_branch('.')
 
915
        b.print_file(b.relpath(filename), revision[0])
916
916
 
917
917
 
918
918
class cmd_local_time_offset(Command):
949
949
    def run(self, message=None, file=None, verbose=True, selected_list=None,
950
950
            unchanged=False):
951
951
        from bzrlib.errors import PointlessCommit
952
 
        from bzrlib.msgeditor import edit_commit_message
953
 
        from bzrlib.status import show_status
954
 
        from cStringIO import StringIO
 
952
        from bzrlib.osutils import get_text_message
955
953
 
956
 
        b = Branch.open_containing('.')
957
 
        if selected_list:
958
 
            selected_list = [b.relpath(s) for s in selected_list]
959
 
            
 
954
        ## Warning: shadows builtin file()
960
955
        if not message and not file:
961
 
            catcher = StringIO()
962
 
            show_status(b, specific_files=selected_list,
963
 
                        to_file=catcher)
964
 
            message = edit_commit_message(catcher.getvalue())
 
956
            # FIXME: Ugly; change status code to send to a provided function?
 
957
            
 
958
            import cStringIO
 
959
            stdout = sys.stdout
 
960
            catcher = cStringIO.StringIO()
 
961
            sys.stdout = catcher
 
962
            cmd_status({"file_list":selected_list}, {})
 
963
            info = catcher.getvalue()
 
964
            sys.stdout = stdout
 
965
            message = get_text_message(info)
965
966
            
966
967
            if message is None:
967
 
                raise BzrCommandError("please specify a commit message"
968
 
                                      " with either --message or --file")
 
968
                raise BzrCommandError("please specify a commit message",
 
969
                                      ["use either --message or --file"])
969
970
        elif message and file:
970
971
            raise BzrCommandError("please specify either --message or --file")
971
972
        
973
974
            import codecs
974
975
            message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
975
976
 
 
977
        b = find_branch('.')
 
978
        if selected_list:
 
979
            selected_list = [b.relpath(s) for s in selected_list]
 
980
            
976
981
        try:
977
982
            b.commit(message, verbose=verbose,
978
983
                     specific_files=selected_list,
989
994
 
990
995
    This command checks various invariants about the branch storage to
991
996
    detect data corruption or bzr bugs.
 
997
 
 
998
    If given the --update flag, it will update some optional fields
 
999
    to help ensure data consistency.
992
1000
    """
993
1001
    takes_args = ['dir?']
994
1002
 
995
1003
    def run(self, dir='.'):
996
1004
        from bzrlib.check import check
997
1005
 
998
 
        check(Branch.open_containing(dir))
 
1006
        check(find_branch(dir))
999
1007
 
1000
1008
 
1001
1009
class cmd_scan_cache(Command):
1028
1036
 
1029
1037
    def run(self, dir='.'):
1030
1038
        from bzrlib.upgrade import upgrade
1031
 
        upgrade(Branch.open_containing(dir))
 
1039
        upgrade(find_branch(dir))
1032
1040
 
1033
1041
 
1034
1042
 
1038
1046
    
1039
1047
    def run(self, email=False):
1040
1048
        try:
1041
 
            b = bzrlib.branch.Branch.open_containing('.')
 
1049
            b = bzrlib.branch.find_branch('.')
1042
1050
        except:
1043
1051
            b = None
1044
1052
        
1108
1116
    hidden = True
1109
1117
    
1110
1118
    def run(self, branch, other):
1111
 
        from bzrlib.revision import common_ancestor, MultipleRevisionSources
1112
 
        
1113
 
        branch1 = Branch.open_containing(branch)
1114
 
        branch2 = Branch.open_containing(other)
1115
 
 
1116
 
        history_1 = branch1.revision_history()
1117
 
        history_2 = branch2.revision_history()
1118
 
 
1119
 
        last1 = branch1.last_patch()
1120
 
        last2 = branch2.last_patch()
1121
 
 
1122
 
        source = MultipleRevisionSources(branch1, branch2)
1123
 
        
1124
 
        base_rev_id = common_ancestor(last1, last2, source)
1125
 
 
1126
 
        print 'merge base is revision %s' % base_rev_id
1127
 
        
1128
 
        return
 
1119
        branch1 = find_branch(branch)
 
1120
        branch2 = find_branch(other)
 
1121
 
 
1122
        base_revno, base_revid = branch1.common_ancestor(branch2)
1129
1123
 
1130
1124
        if base_revno is None:
1131
1125
            raise bzrlib.errors.UnrelatedBranches()
1132
1126
 
 
1127
        print 'merge base is revision %s' % base_revid
1133
1128
        print ' r%-6d in %s' % (base_revno, branch)
1134
1129
 
1135
1130
        other_revno = branch2.revision_id_to_revno(base_revid)
1141
1136
class cmd_merge(Command):
1142
1137
    """Perform a three-way merge.
1143
1138
    
1144
 
    The branch is the branch you will merge from.  By default, it will
1145
 
    merge the latest revision.  If you specify a revision, that
1146
 
    revision will be merged.  If you specify two revisions, the first
1147
 
    will be used as a BASE, and the second one as OTHER.  Revision
1148
 
    numbers are always relative to the specified branch.
1149
 
 
1150
 
    By default bzr will try to merge in all new work from the other
1151
 
    branch, automatically determining an appropriate base.  If this
1152
 
    fails, you may need to give an explicit base.
 
1139
    The branch is the branch you will merge from.  By default, it will merge
 
1140
    the latest revision.  If you specify a revision, that revision will be
 
1141
    merged.  If you specify two revisions, the first will be used as a BASE, 
 
1142
    and the second one as OTHER.  Revision numbers are always relative to the
 
1143
    specified branch.
1153
1144
    
1154
1145
    Examples:
1155
1146
 
1177
1168
 
1178
1169
        if revision is None or len(revision) < 1:
1179
1170
            base = [None, None]
1180
 
            other = [branch, -1]
 
1171
            other = (branch, -1)
1181
1172
        else:
1182
1173
            if len(revision) == 1:
1183
 
                base = [None, None]
1184
 
                other = [branch, revision[0].in_history(branch).revno]
 
1174
                other = (branch, revision[0])
 
1175
                base = (None, None)
1185
1176
            else:
1186
1177
                assert len(revision) == 2
1187
1178
                if None in revision:
1188
1179
                    raise BzrCommandError(
1189
1180
                        "Merge doesn't permit that revision specifier.")
1190
 
                base = [branch, revision[0].in_history(branch).revno]
1191
 
                other = [branch, revision[1].in_history(branch).revno]
1192
 
 
1193
 
        try:
1194
 
            merge(other, base, check_clean=(not force), merge_type=merge_type)
1195
 
        except bzrlib.errors.AmbiguousBase, e:
1196
 
            m = ("sorry, bzr can't determine the right merge base yet\n"
1197
 
                 "candidates are:\n  "
1198
 
                 + "\n  ".join(e.bases)
1199
 
                 + "\n"
1200
 
                 "please specify an explicit base with -r,\n"
1201
 
                 "and (if you want) report this to the bzr developers\n")
1202
 
            log_error(m)
 
1181
                base = (branch, revision[0])
 
1182
                other = (branch, revision[1])
 
1183
            
 
1184
        merge(other, base, check_clean=(not force), merge_type=merge_type)
1203
1185
 
1204
1186
 
1205
1187
class cmd_revert(Command):
1231
1213
              backup_files=not no_backup,
1232
1214
              file_list=file_list)
1233
1215
        if not file_list:
1234
 
            Branch.open_containing('.').set_pending_merges([])
 
1216
            Branch('.').set_pending_merges([])
1235
1217
 
1236
1218
 
1237
1219
class cmd_assert_fail(Command):
1285
1267
        if verbose and quiet:
1286
1268
            raise BzrCommandError('Cannot pass both quiet and verbose')
1287
1269
 
1288
 
        b = Branch.open_containing('.')
 
1270
        b = find_branch('.')
1289
1271
        parent = b.get_parent()
1290
1272
        if remote is None:
1291
1273
            if parent is None:
1295
1277
                    print "Using last location: %s" % parent
1296
1278
                remote = parent
1297
1279
        elif parent is None:
1298
 
            # We only update parent if it did not exist, missing
1299
 
            # should not change the parent
1300
 
            b.set_parent(remote)
1301
 
        br_remote = Branch.open_containing(remote)
 
1280
            # We only update x-pull if it did not exist, missing should not change the parent
 
1281
            b.controlfile('x-pull', 'wb').write(remote + '\n')
 
1282
        br_remote = find_branch(remote)
 
1283
 
1302
1284
        return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
1303
1285
 
1304
1286
 
 
1287
 
1305
1288
class cmd_plugins(Command):
1306
1289
    """List plugins"""
1307
1290
    hidden = True