~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_merge_core.py

  • Committer: John Arbash Meinel
  • Author(s): Mark Hammond
  • Date: 2008-09-09 17:02:21 UTC
  • mto: This revision was merged to the branch mainline in revision 3697.
  • Revision ID: john@arbash-meinel.com-20080909170221-svim3jw2mrz0amp3
An updated transparent icon for bzr.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012, 2016 Canonical Ltd
 
1
# Copyright (C) 2005, 2006 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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
import os
 
18
import stat
18
19
import sys
19
20
 
20
21
import bzrlib
21
22
from bzrlib import (
22
 
    controldir,
23
 
    errors,
24
23
    generate_ids,
25
24
    merge_directive,
26
25
    osutils,
27
26
    )
28
 
from bzrlib.conflicts import (
29
 
    ContentsConflict,
30
 
    TextConflict,
31
 
    PathConflict,
32
 
    )
 
27
from bzrlib.conflicts import ContentsConflict, TextConflict, PathConflict
 
28
from bzrlib import errors
 
29
from bzrlib.errors import (NotBranchError, NotVersionedError,
 
30
                           WorkingTreeNotRevision, BzrCommandError, NoDiff3)
 
31
from bzrlib import  inventory
33
32
from bzrlib.merge import (
34
33
    Merge3Merger,
35
34
    Diff3Merger,
36
35
    WeaveMerger,
37
36
    Merger,
38
37
    )
39
 
from bzrlib.osutils import getcwd, pathjoin
 
38
from bzrlib.osutils import (file_kind, getcwd, pathjoin, rename,
 
39
                            sha_file,
 
40
                            )
 
41
from bzrlib import progress
40
42
from bzrlib.transform import TreeTransform
41
 
from bzrlib.tests import TestCaseWithTransport, TestSkipped
 
43
from bzrlib.tests import TestCaseWithTransport, TestCase, TestSkipped
42
44
from bzrlib.workingtree import WorkingTree
43
45
 
44
46
 
45
47
class MergeBuilder(object):
46
 
 
47
48
    def __init__(self, dir=None):
48
49
        self.dir = osutils.mkdtemp(prefix="merge-test", dir=dir)
49
50
        self.tree_root = generate_ids.gen_root_id()
50
51
        def wt(name):
51
52
           path = pathjoin(self.dir, name)
52
53
           os.mkdir(path)
53
 
           wt = controldir.ControlDir.create_standalone_workingtree(path)
 
54
           wt = bzrlib.bzrdir.BzrDir.create_standalone_workingtree(path)
54
55
           # the tests perform pulls, so need a branch that is writeable.
55
56
           wt.lock_write()
56
57
           wt.set_root_id(self.tree_root)
68
69
            return None
69
70
        return pathjoin(self.cset.entries[parent].path, name)
70
71
 
71
 
    def add_file(self, id, parent, name, contents, executable, this=True,
 
72
    def add_file(self, id, parent, name, contents, executable, this=True, 
72
73
                 base=True, other=True):
73
74
        def new_file(tt):
74
75
            parent_id = tt.trans_id_file_id(parent)
78
79
                new_file(tt)
79
80
 
80
81
    def merge(self, merge_type=Merge3Merger, interesting_ids=None, **kwargs):
81
 
        merger = self.make_merger(merge_type, interesting_ids, **kwargs)
82
 
        merger.do_merge()
83
 
        return merger.cooked_conflicts
84
 
 
85
 
    def make_preview_transform(self):
86
 
        merger = self.make_merger(Merge3Merger, None, this_revision_tree=True)
87
 
        return merger.make_preview_transform()
88
 
 
89
 
    def make_merger(self, merge_type, interesting_ids,
90
 
            this_revision_tree=False, **kwargs):
91
82
        self.base_tt.apply()
92
83
        self.base.commit('base commit')
93
84
        for tt, wt in ((self.this_tt, self.this), (self.other_tt, self.other)):
100
91
            tt.apply()
101
92
            wt.commit('branch commit')
102
93
            wt.flush()
103
 
            if wt.branch.last_revision_info()[0] != 2:
 
94
            if len(wt.branch.revision_history()) != 2:
104
95
                raise AssertionError()
105
96
        self.this.branch.fetch(self.other.branch)
106
97
        other_basis = self.other.branch.basis_tree()
107
 
        if this_revision_tree:
108
 
            self.this.commit('message')
109
 
            this_tree = self.this.basis_tree()
110
 
        else:
111
 
            this_tree = self.this
112
 
        merger = merge_type(this_tree, self.this, self.base, other_basis,
113
 
                            interesting_ids=interesting_ids, do_merge=False,
114
 
                            this_branch=self.this.branch, **kwargs)
115
 
        return merger
 
98
        merger = merge_type(self.this, self.this, self.base, other_basis, 
 
99
                            interesting_ids=interesting_ids, **kwargs)
 
100
        return merger.cooked_conflicts
116
101
 
117
102
    def list_transforms(self):
118
103
        return [self.this_tt, self.base_tt, self.other_tt]
119
104
 
120
105
    def selected_transforms(self, this, base, other):
121
 
        pairs = [(this, self.this_tt), (base, self.base_tt),
 
106
        pairs = [(this, self.this_tt), (base, self.base_tt), 
122
107
                 (other, self.other_tt)]
123
108
        return [(v, tt) for (v, tt) in pairs if v is not None]
124
109
 
135
120
                tt.cancel_versioning(trans_id)
136
121
                tt.set_executability(None, trans_id)
137
122
 
138
 
    def add_dir(self, file_id, parent, name, this=True, base=True, other=True):
139
 
        for option, tt in self.selected_transforms(this, base, other):
140
 
            if option is True:
141
 
                parent_id = tt.trans_id_file_id(parent)
142
 
                tt.new_directory(name, parent_id, file_id)
 
123
    def add_dir(self, file_id, parent, name):
 
124
        for tt in self.list_transforms():
 
125
            parent_id = tt.trans_id_file_id(parent)
 
126
            tt.new_directory(name, parent_id, file_id)
143
127
 
144
128
    def change_name(self, id, base=None, this=None, other=None):
145
 
        for val, tt in ((base, self.base_tt), (this, self.this_tt),
 
129
        for val, tt in ((base, self.base_tt), (this, self.this_tt), 
146
130
                        (other, self.other_tt)):
147
131
            if val is None:
148
132
                continue
191
175
            if parent_dir == "":
192
176
                return None
193
177
            return orig_inventory_by_path[parent_dir]
194
 
 
 
178
        
195
179
        def new_path(file_id):
196
180
            if fild_id in inventory_change:
197
181
                return inventory_change[file_id]
255
239
        self.assertEqual(builder.this.get_file("1").read(), "text4" )
256
240
        self.assertEqual(builder.this.get_file("2").read(), "hello1" )
257
241
        builder.cleanup()
258
 
 
 
242
        
259
243
    def test_file_moves(self):
260
244
        """Test moves"""
261
245
        builder = MergeBuilder(getcwd())
293
277
                              " and therefore always fails on win32")
294
278
        try:
295
279
            self.do_contents_test(Diff3Merger)
296
 
        except errors.NoDiff3:
 
280
        except NoDiff3:
297
281
            raise TestSkipped("diff3 not available")
298
282
 
299
283
    def test_contents_merge3(self):
339
323
        builder.remove_file("4", base=True)
340
324
        builder.add_file("5", builder.tree_root, "name7", "a\nb\nc\nd\ne\nf\n",
341
325
                         True)
342
 
        builder.change_contents("5", other="a\nz\nc\nd\ne\nf\n",
 
326
        builder.change_contents("5", other="a\nz\nc\nd\ne\nf\n", 
343
327
                                     this="a\nb\nc\nd\ne\nz\n")
344
328
        conflicts = builder.merge(merge_factory)
345
329
        try:
346
330
            self.assertEqual([], conflicts)
347
331
            self.assertEqual("text4", builder.this.get_file("1").read())
348
332
            self.assertEqual("text2", builder.this.get_file("2").read())
349
 
            self.assertEqual("a\nz\nc\nd\ne\nz\n",
 
333
            self.assertEqual("a\nz\nc\nd\ne\nz\n", 
350
334
                             builder.this.get_file("5").read())
351
335
            self.assertTrue(builder.this.is_executable("1"))
352
336
            self.assertFalse(builder.this.is_executable("2"))
379
363
            builder.add_symlink("2", builder.tree_root, "name2", "target1")
380
364
            builder.change_target("2", other="target4", base="text3")
381
365
            conflicts = builder.merge()
382
 
            self.assertEqual(conflicts, [ContentsConflict('name2',
 
366
            self.assertEqual(conflicts, [ContentsConflict('name2', 
383
367
                                                          file_id='2')])
384
368
            builder.cleanup()
385
369
 
435
419
        builder = MergeBuilder(getcwd())
436
420
        builder.add_file("1", builder.tree_root, "name1", "text1", False)
437
421
        builder.remove_file("1", other=True)
438
 
        builder.add_file("2", builder.tree_root, "name1", "text1", False,
 
422
        builder.add_file("2", builder.tree_root, "name1", "text1", False, 
439
423
                         this=False, base=False)
440
424
        conflicts = builder.merge()
441
 
        self.assertEqual(conflicts, [])
 
425
        self.assertEqual(conflicts, []) 
442
426
        builder.cleanup()
443
427
 
444
428
    def test_merge_one_renamed(self):
450
434
        self.assertEqual('text2', builder.this.get_file('1').read())
451
435
        builder.cleanup()
452
436
 
453
 
 
454
437
class FunctionalMergeTest(TestCaseWithTransport):
455
438
 
456
439
    def test_trivial_star_merge(self):
457
 
        """Test that merges in a star shape Just Work."""
 
440
        """Test that merges in a star shape Just Work.""" 
458
441
        # John starts a branch
459
442
        self.build_tree(("original/", "original/file1", "original/file2"))
460
443
        tree = self.make_branch_and_tree('original')
482
465
        tree.merge_from_branch(mary_tree.branch)
483
466
        self.assertEqual("John\n", open("original/file1", "rt").read())
484
467
        self.assertEqual("Mary\n", open("original/file2", "rt").read())
485
 
 
 
468
 
486
469
    def test_conflicts(self):
 
470
        os.mkdir('a')
487
471
        wta = self.make_branch_and_tree('a')
488
 
        self.build_tree_contents([('a/file', 'contents\n')])
 
472
        a = wta.branch
 
473
        file('a/file', 'wb').write('contents\n')
489
474
        wta.add('file')
490
475
        wta.commit('base revision', allow_pointless=False)
491
 
        d_b = wta.branch.bzrdir.clone('b')
492
 
        self.build_tree_contents([('a/file', 'other contents\n')])
 
476
        d_b = a.bzrdir.clone('b')
 
477
        b = d_b.open_branch()
 
478
        file('a/file', 'wb').write('other contents\n')
493
479
        wta.commit('other revision', allow_pointless=False)
494
 
        self.build_tree_contents([('b/file', 'this contents contents\n')])
 
480
        file('b/file', 'wb').write('this contents contents\n')
495
481
        wtb = d_b.open_workingtree()
496
482
        wtb.commit('this revision', allow_pointless=False)
497
483
        self.assertEqual(1, wtb.merge_from_branch(wta.branch))
498
 
        self.assertPathExists('b/file.THIS')
499
 
        self.assertPathExists('b/file.BASE')
500
 
        self.assertPathExists('b/file.OTHER')
 
484
        self.assert_(os.path.lexists('b/file.THIS'))
 
485
        self.assert_(os.path.lexists('b/file.BASE'))
 
486
        self.assert_(os.path.lexists('b/file.OTHER'))
501
487
        wtb.revert()
502
488
        self.assertEqual(1, wtb.merge_from_branch(wta.branch,
503
489
                                                  merge_type=WeaveMerger))
504
 
        self.assertPathExists('b/file')
505
 
        self.assertPathExists('b/file.THIS')
506
 
        self.assertPathExists('b/file.BASE')
507
 
        self.assertPathExists('b/file.OTHER')
508
 
 
509
 
    def test_weave_conflicts_not_in_base(self):
510
 
        builder = self.make_branch_builder('source')
511
 
        builder.start_series()
512
 
        # See bug #494197
513
 
        #  A        base revision (before criss-cross)
514
 
        #  |\
515
 
        #  B C      B does nothing, C adds 'foo'
516
 
        #  |X|
517
 
        #  D E      D and E modify foo in incompatible ways
518
 
        #
519
 
        # Merging will conflict, with C as a clean base text. However, the
520
 
        # current code uses A as the global base and 'foo' doesn't exist there.
521
 
        # It isn't trivial to create foo.BASE because it tries to look up
522
 
        # attributes like 'executable' in A.
523
 
        builder.build_snapshot('A-id', None, [
524
 
            ('add', ('', 'TREE_ROOT', 'directory', None))])
525
 
        builder.build_snapshot('B-id', ['A-id'], [])
526
 
        builder.build_snapshot('C-id', ['A-id'], [
527
 
            ('add', ('foo', 'foo-id', 'file', 'orig\ncontents\n'))])
528
 
        builder.build_snapshot('D-id', ['B-id', 'C-id'], [
529
 
            ('add', ('foo', 'foo-id', 'file', 'orig\ncontents\nand D\n'))])
530
 
        builder.build_snapshot('E-id', ['C-id', 'B-id'], [
531
 
            ('modify', ('foo-id', 'orig\ncontents\nand E\n'))])
532
 
        builder.finish_series()
533
 
        tree = builder.get_branch().create_checkout('tree', lightweight=True)
534
 
        self.assertEqual(1, tree.merge_from_branch(tree.branch,
535
 
                                                   to_revision='D-id',
536
 
                                                   merge_type=WeaveMerger))
537
 
        self.assertPathExists('tree/foo.THIS')
538
 
        self.assertPathExists('tree/foo.OTHER')
539
 
        self.expectFailure('fail to create .BASE in some criss-cross merges',
540
 
            self.assertPathExists, 'tree/foo.BASE')
541
 
        self.assertPathExists('tree/foo.BASE')
 
490
        self.assert_(os.path.lexists('b/file'))
 
491
        self.assert_(os.path.lexists('b/file.THIS'))
 
492
        self.assert_(not os.path.lexists('b/file.BASE'))
 
493
        self.assert_(os.path.lexists('b/file.OTHER'))
542
494
 
543
495
    def test_merge_unrelated(self):
544
496
        """Sucessfully merges unrelated branches with no common names"""
545
497
        wta = self.make_branch_and_tree('a')
546
498
        a = wta.branch
547
 
        with file('a/a_file', 'wb') as f: f.write('contents\n')
 
499
        file('a/a_file', 'wb').write('contents\n')
548
500
        wta.add('a_file')
549
501
        wta.commit('a_revision', allow_pointless=False)
550
502
        wtb = self.make_branch_and_tree('b')
551
503
        b = wtb.branch
552
 
        with file('b/b_file', 'wb') as f: f.write('contents\n')
 
504
        file('b/b_file', 'wb').write('contents\n')
553
505
        wtb.add('b_file')
554
506
        b_rev = wtb.commit('b_revision', allow_pointless=False)
555
507
        wta.merge_from_branch(wtb.branch, b_rev, 'null:')
556
 
        self.assertTrue(os.path.lexists('a/b_file'))
 
508
        self.assert_(os.path.lexists('a/b_file'))
557
509
        self.assertEqual([b_rev], wta.get_parent_ids()[1:])
558
510
 
559
511
    def test_merge_unrelated_conflicting(self):
560
512
        """Sucessfully merges unrelated branches with common names"""
561
513
        wta = self.make_branch_and_tree('a')
562
514
        a = wta.branch
563
 
        with file('a/file', 'wb') as f: f.write('contents\n')
 
515
        file('a/file', 'wb').write('contents\n')
564
516
        wta.add('file')
565
517
        wta.commit('a_revision', allow_pointless=False)
566
518
        wtb = self.make_branch_and_tree('b')
567
519
        b = wtb.branch
568
 
        with file('b/file', 'wb') as f: f.write('contents\n')
 
520
        file('b/file', 'wb').write('contents\n')
569
521
        wtb.add('file')
570
522
        b_rev = wtb.commit('b_revision', allow_pointless=False)
571
523
        wta.merge_from_branch(wtb.branch, b_rev, 'null:')
572
 
        self.assertTrue(os.path.lexists('a/file'))
573
 
        self.assertTrue(os.path.lexists('a/file.moved'))
 
524
        self.assert_(os.path.lexists('a/file'))
 
525
        self.assert_(os.path.lexists('a/file.moved'))
574
526
        self.assertEqual([b_rev], wta.get_parent_ids()[1:])
575
527
 
576
528
    def test_merge_deleted_conflicts(self):
577
529
        wta = self.make_branch_and_tree('a')
578
 
        with file('a/file', 'wb') as f: f.write('contents\n')
 
530
        file('a/file', 'wb').write('contents\n')
579
531
        wta.add('file')
580
532
        wta.commit('a_revision', allow_pointless=False)
581
533
        self.run_bzr('branch a b')
582
534
        os.remove('a/file')
583
535
        wta.commit('removed file', allow_pointless=False)
584
 
        with file('b/file', 'wb') as f: f.write('changed contents\n')
 
536
        file('b/file', 'wb').write('changed contents\n')
585
537
        wtb = WorkingTree.open('b')
586
538
        wtb.commit('changed file', allow_pointless=False)
587
539
        wtb.merge_from_branch(wta.branch, wta.branch.last_revision(),
588
540
                              wta.branch.get_rev_id(1))
589
 
        self.assertFalse(os.path.lexists('b/file'))
 
541
        self.failIf(os.path.lexists('b/file'))
590
542
 
591
543
    def test_merge_metadata_vs_deletion(self):
592
544
        """Conflict deletion vs metadata change"""
593
545
        a_wt = self.make_branch_and_tree('a')
594
 
        with file('a/file', 'wb') as f: f.write('contents\n')
 
546
        file('a/file', 'wb').write('contents\n')
595
547
        a_wt.add('file')
596
548
        a_wt.commit('r0')
597
549
        self.run_bzr('branch a b')
603
555
        self.assertFalse(os.path.exists('a/file'))
604
556
        b_wt.commit('exec a')
605
557
        a_wt.merge_from_branch(b_wt.branch, b_wt.last_revision(), 'null:')
606
 
        self.assertTrue(os.path.exists('a/file'))
 
558
        self.assert_(os.path.exists('a/file'))
607
559
 
608
560
    def test_merge_swapping_renames(self):
609
561
        a_wt = self.make_branch_and_tree('a')
610
 
        with file('a/un','wb') as f: f.write('UN')
611
 
        with file('a/deux','wb') as f: f.write('DEUX')
 
562
        file('a/un','wb').write('UN')
 
563
        file('a/deux','wb').write('DEUX')
612
564
        a_wt.add('un', 'un-id')
613
565
        a_wt.add('deux', 'deux-id')
614
566
        a_wt.commit('r0', rev_id='r0')
620
572
        b_wt.commit('r1', rev_id='r1')
621
573
        self.assertEqual(0, a_wt.merge_from_branch(b_wt.branch,
622
574
            b_wt.branch.last_revision(), b_wt.branch.get_rev_id(1)))
623
 
        self.assertPathExists('a/un')
624
 
        self.assertTrue('a/deux')
 
575
        self.failUnlessExists('a/un')
 
576
        self.failUnless('a/deux')
625
577
        self.assertFalse(os.path.exists('a/tmp'))
626
578
        self.assertEqual(file('a/un').read(),'DEUX')
627
579
        self.assertEqual(file('a/deux').read(),'UN')
628
580
 
629
581
    def test_merge_delete_and_add_same(self):
630
582
        a_wt = self.make_branch_and_tree('a')
631
 
        with file('a/file', 'wb') as f: f.write('THIS')
 
583
        file('a/file', 'wb').write('THIS')
632
584
        a_wt.add('file')
633
585
        a_wt.commit('r0')
634
586
        self.run_bzr('branch a b')
635
587
        b_wt = WorkingTree.open('b')
636
588
        os.remove('b/file')
637
589
        b_wt.commit('r1')
638
 
        with file('b/file', 'wb') as f: f.write('THAT')
 
590
        file('b/file', 'wb').write('THAT')
639
591
        b_wt.add('file')
640
592
        b_wt.commit('r2')
641
593
        a_wt.merge_from_branch(b_wt.branch, b_wt.branch.last_revision(),
642
594
                               b_wt.branch.get_rev_id(1))
643
 
        self.assertTrue(os.path.exists('a/file'))
 
595
        self.assert_(os.path.exists('a/file'))
644
596
        self.assertEqual(file('a/file').read(),'THAT')
645
597
 
646
598
    def test_merge_rename_before_create(self):
647
599
        """rename before create
648
 
 
 
600
        
649
601
        This case requires that you must not do creates
650
602
        before move-into-place:
651
603
 
658
610
        $ bzr commit
659
611
        """
660
612
        a_wt = self.make_branch_and_tree('a')
661
 
        with file('a/foo', 'wb') as f: f.write('A/FOO')
 
613
        file('a/foo', 'wb').write('A/FOO')
662
614
        a_wt.add('foo')
663
615
        a_wt.commit('added foo')
664
616
        self.run_bzr('branch a b')
665
617
        b_wt = WorkingTree.open('b')
666
618
        b_wt.rename_one('foo', 'bar')
667
 
        with file('b/foo', 'wb') as f: f.write('B/FOO')
 
619
        file('b/foo', 'wb').write('B/FOO')
668
620
        b_wt.add('foo')
669
621
        b_wt.commit('moved foo to bar, added new foo')
670
622
        a_wt.merge_from_branch(b_wt.branch, b_wt.branch.last_revision(),
687
639
        """
688
640
        os.mkdir('a')
689
641
        a_wt = self.make_branch_and_tree('a')
690
 
        with file('a/foo', 'wb') as f: f.write('A/FOO')
 
642
        file('a/foo', 'wb').write('A/FOO')
691
643
        a_wt.add('foo')
692
644
        a_wt.commit('added foo')
693
645
        self.run_bzr('branch a b')
705
657
        This case requires that you must not do deletes before
706
658
        move-out-of-the-way, and that you must not do children
707
659
        after parents:
708
 
 
 
660
        
709
661
        $ mkdir foo
710
662
        $ touch foo/bar
711
663
        $ bzr add foo/bar
716
668
        """
717
669
        a_wt = self.make_branch_and_tree('a')
718
670
        os.mkdir('a/foo')
719
 
        with file('a/foo/bar', 'wb') as f: f.write('A/FOO/BAR')
 
671
        file('a/foo/bar', 'wb').write('A/FOO/BAR')
720
672
        a_wt.add('foo')
721
673
        a_wt.add('foo/bar')
722
674
        a_wt.commit('added foo/bar')
734
686
 
735
687
        This case requires that you must not do
736
688
        move-out-of-the-way before deletes:
737
 
 
 
689
        
738
690
        $ touch foo
739
691
        $ touch bar
740
692
        $ bzr add foo bar
745
697
        $ bzr commit
746
698
        """
747
699
        a_wt = self.make_branch_and_tree('a')
748
 
        with file('a/foo', 'wb') as f: f.write('A/FOO')
749
 
        with file('a/bar', 'wb') as f: f.write('A/BAR')
 
700
        file('a/foo', 'wb').write('A/FOO')
 
701
        file('a/bar', 'wb').write('A/BAR')
750
702
        a_wt.add('foo')
751
703
        a_wt.add('bar')
752
704
        a_wt.commit('added foo and bar')
773
725
    def test_from_revision_ids(self):
774
726
        this, other = self.set_up_trees()
775
727
        self.assertRaises(errors.NoSuchRevision, Merger.from_revision_ids,
776
 
                          None, this, 'rev2b')
 
728
                          progress.DummyProgress(), this, 'rev2b')
777
729
        this.lock_write()
778
730
        self.addCleanup(this.unlock)
779
 
        merger = Merger.from_revision_ids(None, this,
 
731
        merger = Merger.from_revision_ids(progress.DummyProgress(), this,
780
732
            'rev2b', other_branch=other.branch)
781
733
        self.assertEqual('rev2b', merger.other_rev_id)
782
734
        self.assertEqual('rev1', merger.base_rev_id)
783
 
        merger = Merger.from_revision_ids(None, this,
 
735
        merger = Merger.from_revision_ids(progress.DummyProgress(), this,
784
736
            'rev2b', 'rev2a', other_branch=other.branch)
785
737
        self.assertEqual('rev2a', merger.base_rev_id)
786
738
 
787
739
    def test_from_uncommitted(self):
788
740
        this, other = self.set_up_trees()
789
 
        merger = Merger.from_uncommitted(this, other, None)
 
741
        merger = Merger.from_uncommitted(this, other, progress.DummyProgress())
790
742
        self.assertIs(other, merger.other_tree)
791
743
        self.assertIs(None, merger.other_rev_id)
792
744
        self.assertEqual('rev2b', merger.base_rev_id)
805
757
        other.lock_read()
806
758
        self.addCleanup(other.unlock)
807
759
        merger, verified = Merger.from_mergeable(this, md,
808
 
            None)
 
760
            progress.DummyProgress())
809
761
        md.patch = None
810
762
        merger, verified = Merger.from_mergeable(this, md,
811
 
            None)
 
763
            progress.DummyProgress())
812
764
        self.assertEqual('inapplicable', verified)
813
765
        self.assertEqual('rev3', merger.other_rev_id)
814
766
        self.assertEqual('rev1', merger.base_rev_id)
815
767
        md.base_revision_id = 'rev2b'
816
768
        merger, verified = Merger.from_mergeable(this, md,
817
 
            None)
 
769
            progress.DummyProgress())
818
770
        self.assertEqual('rev2b', merger.base_rev_id)
819
771
 
820
772
    def test_from_mergeable_old_merge_directive(self):
824
776
        md = merge_directive.MergeDirective.from_objects(
825
777
            other.branch.repository, 'rev3', 0, 0, 'this')
826
778
        merger, verified = Merger.from_mergeable(this, md,
827
 
            None)
 
779
            progress.DummyProgress())
828
780
        self.assertEqual('rev3', merger.other_rev_id)
829
781
        self.assertEqual('rev1', merger.base_rev_id)