/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/blackbox/test_merge.py

  • Committer: Jelmer Vernooij
  • Date: 2017-07-23 22:06:41 UTC
  • mfrom: (6738 trunk)
  • mto: This revision was merged to the branch mainline in revision 6739.
  • Revision ID: jelmer@jelmer.uk-20170723220641-69eczax9bmv8d6kk
Merge trunk, address review comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 
27
27
from breezy import (
28
28
    branch,
 
29
    conflicts,
29
30
    controldir,
30
31
    merge_directive,
31
32
    osutils,
33
34
    urlutils,
34
35
    workingtree,
35
36
    )
36
 
from breezy.bzr import (
37
 
    conflicts,
38
 
    )
39
37
from breezy.tests import (
40
38
    scenarios,
41
39
    script,
50
48
    def example_branch(self, path='.'):
51
49
        tree = self.make_branch_and_tree(path)
52
50
        self.build_tree_contents([
53
 
            (osutils.pathjoin(path, 'hello'), b'foo'),
54
 
            (osutils.pathjoin(path, 'goodbye'), b'baz')])
 
51
            (osutils.pathjoin(path, 'hello'), 'foo'),
 
52
            (osutils.pathjoin(path, 'goodbye'), 'baz')])
55
53
        tree.add('hello')
56
54
        tree.commit(message='setup')
57
55
        tree.add('goodbye')
65
63
            conflict.
66
64
        """
67
65
        builder = self.make_branch_builder('branch')
68
 
        builder.build_snapshot(None,
69
 
                               [('add', ('', b'root-id', 'directory', None)),
70
 
                                ('add', ('fname', b'f-id', 'file', b'a\nb\nc\n'))],
71
 
                               revision_id=b'rev1')
72
 
        builder.build_snapshot([b'rev1'],
73
 
                               [('modify', ('fname', b'a\nB\nD\n'))],
74
 
                               revision_id=b'rev2other')
 
66
        builder.build_snapshot('rev1', None,
 
67
            [('add', ('', 'root-id', 'directory', None)),
 
68
             ('add', ('fname', 'f-id', 'file', 'a\nb\nc\n'))])
 
69
        builder.build_snapshot('rev2other', ['rev1'],
 
70
            [('modify', ('f-id', 'a\nB\nD\n'))])
75
71
        other = builder.get_branch().controldir.sprout('other').open_branch()
76
 
        builder.build_snapshot([b'rev1'],
77
 
                               [('modify', ('fname', b'a\nB\nC\n'))], revision_id=b'rev2this')
 
72
        builder.build_snapshot('rev2this', ['rev1'],
 
73
            [('modify', ('f-id', 'a\nB\nC\n'))])
78
74
        tree = builder.get_branch().create_checkout('tree', lightweight=True)
79
75
        return tree, other
80
76
 
87
83
        a_tree = self.example_branch('a')
88
84
        ancestor = a_tree.branch.revno()
89
85
        b_tree = a_tree.controldir.sprout('b').open_workingtree()
90
 
        self.build_tree_contents([('b/goodbye', b'quux')])
 
86
        self.build_tree_contents([('b/goodbye', 'quux')])
91
87
        b_tree.commit(message="more u's are always good")
92
88
 
93
 
        self.build_tree_contents([('a/hello', b'quuux')])
 
89
        self.build_tree_contents([('a/hello', 'quuux')])
94
90
        # We can't merge when there are in-tree changes
95
91
        self.run_bzr('merge ../b', retcode=3, working_dir='a')
96
92
        a = workingtree.WorkingTree.open('a')
114
110
                     working_dir='a')
115
111
        a_tree.revert(backups=False)
116
112
        self.run_bzr('merge ../b -r last:1', working_dir='a')
117
 
        self.check_file_contents('a/goodbye', b'quux')
 
113
        self.check_file_contents('a/goodbye', 'quux')
118
114
        # Merging a branch pulls its revision into the tree
119
115
        b = branch.Branch.open('b')
120
116
        b_tip = b.last_revision()
125
121
                                working_dir='a')
126
122
        self.assertTrue("Not a branch" in err)
127
123
        self.run_bzr('merge -r revno:%d:./..revno:%d:../b'
128
 
                     % (ancestor, b.revno()), working_dir='a')
 
124
                    %(ancestor,b.revno()), working_dir='a')
129
125
        self.assertEqual(a.get_parent_ids(),
130
 
                         [a.branch.last_revision(), b.last_revision()])
131
 
        self.check_file_contents('a/goodbye', b'quux')
 
126
                          [a.branch.last_revision(), b.last_revision()])
 
127
        self.check_file_contents('a/goodbye', 'quux')
132
128
        a_tree.revert(backups=False)
133
 
        self.run_bzr('merge -r revno:%d:../b' % b.revno(), working_dir='a')
 
129
        self.run_bzr('merge -r revno:%d:../b'%b.revno(), working_dir='a')
134
130
        self.assertEqual(a.get_parent_ids(),
135
 
                         [a.branch.last_revision(), b.last_revision()])
 
131
                          [a.branch.last_revision(), b.last_revision()])
136
132
        a_tip = a.commit('merged')
137
133
        self.run_bzr('merge ../b -r last:1', working_dir='a')
138
134
        self.assertEqual([a_tip], a.get_parent_ids())
143
139
        # 'show-base' is not set
144
140
        self.run_bzr('merge ../other', working_dir='tree',
145
141
                     retcode=1)
146
 
        self.assertEqualDiff(b'a\n'
147
 
                             b'B\n'
148
 
                             b'<<<<<<< TREE\n'
149
 
                             b'C\n'
150
 
                             b'=======\n'
151
 
                             b'D\n'
152
 
                             b'>>>>>>> MERGE-SOURCE\n',
153
 
                             tree.get_file_text('fname'))
 
142
        self.assertEqualDiff('a\n'
 
143
                             'B\n'
 
144
                             '<<<<<<< TREE\n'
 
145
                             'C\n'
 
146
                             '=======\n'
 
147
                             'D\n'
 
148
                             '>>>>>>> MERGE-SOURCE\n',
 
149
                             tree.get_file_text('f-id'))
154
150
 
155
151
    def test_merge_explicit_reprocess_show_base(self):
156
152
        tree, other = self.create_conflicting_branches()
164
160
        # Explicitly disable reprocess
165
161
        self.run_bzr('merge ../other --no-reprocess', working_dir='tree',
166
162
                     retcode=1)
167
 
        self.assertEqualDiff(b'a\n'
168
 
                             b'<<<<<<< TREE\n'
169
 
                             b'B\n'
170
 
                             b'C\n'
171
 
                             b'=======\n'
172
 
                             b'B\n'
173
 
                             b'D\n'
174
 
                             b'>>>>>>> MERGE-SOURCE\n',
175
 
                             tree.get_file_text('fname'))
 
163
        self.assertEqualDiff('a\n'
 
164
                             '<<<<<<< TREE\n'
 
165
                             'B\n'
 
166
                             'C\n'
 
167
                             '=======\n'
 
168
                             'B\n'
 
169
                             'D\n'
 
170
                             '>>>>>>> MERGE-SOURCE\n',
 
171
                             tree.get_file_text('f-id'))
176
172
 
177
173
    def test_merge_override_show_base(self):
178
174
        tree, other = self.create_conflicting_branches()
179
175
        # Setting '--show-base' will auto-disable '--reprocess'
180
176
        self.run_bzr('merge ../other --show-base', working_dir='tree',
181
177
                     retcode=1)
182
 
        self.assertEqualDiff(b'a\n'
183
 
                             b'<<<<<<< TREE\n'
184
 
                             b'B\n'
185
 
                             b'C\n'
186
 
                             b'||||||| BASE-REVISION\n'
187
 
                             b'b\n'
188
 
                             b'c\n'
189
 
                             b'=======\n'
190
 
                             b'B\n'
191
 
                             b'D\n'
192
 
                             b'>>>>>>> MERGE-SOURCE\n',
193
 
                             tree.get_file_text('fname'))
 
178
        self.assertEqualDiff('a\n'
 
179
                             '<<<<<<< TREE\n'
 
180
                             'B\n'
 
181
                             'C\n'
 
182
                             '||||||| BASE-REVISION\n'
 
183
                             'b\n'
 
184
                             'c\n'
 
185
                             '=======\n'
 
186
                             'B\n'
 
187
                             'D\n'
 
188
                             '>>>>>>> MERGE-SOURCE\n',
 
189
                             tree.get_file_text('f-id'))
194
190
 
195
191
    def test_merge_with_missing_file(self):
196
192
        """Merge handles missing file conflicts"""
197
193
        self.build_tree_contents([
198
194
            ('a/',),
199
195
            ('a/sub/',),
200
 
            ('a/sub/a.txt', b'hello\n'),
201
 
            ('a/b.txt', b'hello\n'),
202
 
            ('a/sub/c.txt', b'hello\n')])
 
196
            ('a/sub/a.txt', 'hello\n'),
 
197
            ('a/b.txt', 'hello\n'),
 
198
            ('a/sub/c.txt', 'hello\n')])
203
199
        a_tree = self.make_branch_and_tree('a')
204
200
        a_tree.add(['sub', 'b.txt', 'sub/c.txt', 'sub/a.txt'])
205
201
        a_tree.commit(message='added a')
206
202
        b_tree = a_tree.controldir.sprout('b').open_workingtree()
207
203
        self.build_tree_contents([
208
 
            ('a/sub/a.txt', b'hello\nthere\n'),
209
 
            ('a/b.txt', b'hello\nthere\n'),
210
 
            ('a/sub/c.txt', b'hello\nthere\n')])
 
204
            ('a/sub/a.txt', 'hello\nthere\n'),
 
205
            ('a/b.txt', 'hello\nthere\n'),
 
206
            ('a/sub/c.txt', 'hello\nthere\n')])
211
207
        a_tree.commit(message='Added there')
212
208
        os.remove('a/sub/a.txt')
213
209
        os.remove('a/sub/c.txt')
215
211
        os.remove('a/b.txt')
216
212
        a_tree.commit(message='Removed a.txt')
217
213
        self.build_tree_contents([
218
 
            ('b/sub/a.txt', b'hello\nsomething\n'),
219
 
            ('b/b.txt', b'hello\nsomething\n'),
220
 
            ('b/sub/c.txt', b'hello\nsomething\n')])
 
214
            ('b/sub/a.txt', 'hello\nsomething\n'),
 
215
            ('b/b.txt', 'hello\nsomething\n'),
 
216
            ('b/sub/c.txt', 'hello\nsomething\n')])
221
217
        b_tree.commit(message='Modified a.txt')
222
218
 
223
219
        self.run_bzr('merge ../a/', retcode=1, working_dir='b')
232
228
        tree, other = self.create_conflicting_branches()
233
229
        self.run_bzr('merge ../other', working_dir='tree',
234
230
                     retcode=1)
235
 
        self.assertFileEqual(b'a\nb\nc\n', 'tree/fname.BASE')
236
 
        self.assertFileEqual(b'a\nB\nD\n', 'tree/fname.OTHER')
237
 
        self.assertFileEqual(b'a\nB\nC\n', 'tree/fname.THIS')
 
231
        self.assertFileEqual('a\nb\nc\n', 'tree/fname.BASE')
 
232
        self.assertFileEqual('a\nB\nD\n', 'tree/fname.OTHER')
 
233
        self.assertFileEqual('a\nB\nC\n', 'tree/fname.THIS')
238
234
 
239
235
    def test_weave_conflict_leaves_base_this_other_files(self):
240
236
        tree, other = self.create_conflicting_branches()
241
237
        self.run_bzr('merge ../other --weave', working_dir='tree',
242
238
                     retcode=1)
243
 
        self.assertFileEqual(b'a\nb\nc\n', 'tree/fname.BASE')
244
 
        self.assertFileEqual(b'a\nB\nD\n', 'tree/fname.OTHER')
245
 
        self.assertFileEqual(b'a\nB\nC\n', 'tree/fname.THIS')
 
239
        self.assertFileEqual('a\nb\nc\n', 'tree/fname.BASE')
 
240
        self.assertFileEqual('a\nB\nD\n', 'tree/fname.OTHER')
 
241
        self.assertFileEqual('a\nB\nC\n', 'tree/fname.THIS')
246
242
 
247
243
    def test_merge_remember(self):
248
244
        """Merge changes from one branch to another, test submit location."""
268
264
        # test merge for failure without parent set
269
265
        out = self.run_bzr('merge', retcode=3, working_dir='branch_b')
270
266
        self.assertEqual(out,
271
 
                         ('', 'brz: ERROR: No location specified or remembered\n'))
 
267
                ('','brz: ERROR: No location specified or remembered\n'))
272
268
 
273
269
        # test uncommitted changes
274
270
        self.build_tree(['branch_b/d'])
285
281
        # re-open branch as external run_brz modified it
286
282
        branch_b = branch_b.controldir.open_branch()
287
283
        self.assertEqual(osutils.abspath(branch_b.get_submit_branch()),
288
 
                         osutils.abspath(parent))
 
284
                          osutils.abspath(parent))
289
285
        # test implicit --remember when committing new file
290
286
        self.build_tree(['branch_b/e'])
291
287
        tree_b.add('e')
304
300
        # re-open branch as external run_brz modified it
305
301
        branch_b = branch_b.controldir.open_branch()
306
302
        self.assertEqual(osutils.abspath(branch_b.get_submit_branch()),
307
 
                         osutils.abspath(branch_c.controldir.root_transport.base))
 
303
                          osutils.abspath(branch_c.controldir.root_transport.base))
308
304
        # re-open tree as external run_brz modified it
309
305
        tree_b = branch_b.controldir.open_workingtree()
310
306
        tree_b.commit('merge branch_c')
311
307
 
312
308
    def test_merge_bundle(self):
313
 
        from breezy.bzr.testament import Testament
 
309
        from breezy.testament import Testament
314
310
        tree_a = self.make_branch_and_tree('branch_a')
315
 
        self.build_tree_contents([('branch_a/a', b'hello')])
 
311
        self.build_tree_contents([('branch_a/a', 'hello')])
316
312
        tree_a.add('a')
317
313
        tree_a.commit('message')
318
314
 
319
315
        tree_b = tree_a.controldir.sprout('branch_b').open_workingtree()
320
 
        self.build_tree_contents([('branch_a/a', b'hey there')])
 
316
        self.build_tree_contents([('branch_a/a', 'hey there')])
321
317
        tree_a.commit('message')
322
318
 
323
 
        self.build_tree_contents([('branch_b/a', b'goodbye')])
 
319
        self.build_tree_contents([('branch_b/a', 'goodbye')])
324
320
        tree_b.commit('message')
325
321
        self.run_bzr('bundle ../branch_a -o ../bundle', working_dir='branch_b')
326
322
        self.run_bzr('merge ../bundle', retcode=1, working_dir='branch_a')
329
325
        testament_b = Testament.from_revision(tree_b.branch.repository,
330
326
                                              tree_b.get_parent_ids()[0])
331
327
        self.assertEqualDiff(testament_a.as_text(),
332
 
                             testament_b.as_text())
333
 
        tree_a.set_conflicts([])
 
328
                         testament_b.as_text())
 
329
        tree_a.set_conflicts(conflicts.ConflictList())
334
330
        tree_a.commit('message')
335
331
        # it is legal to attempt to merge an already-merged bundle
336
332
        err = self.run_bzr('merge ../bundle', working_dir='branch_a')[1]
337
333
        # but it does nothing
338
 
        self.assertFalse(tree_a.changes_from(
339
 
            tree_a.basis_tree()).has_changed())
 
334
        self.assertFalse(tree_a.changes_from(tree_a.basis_tree()).has_changed())
340
335
        self.assertEqual('Nothing to do.\n', err)
341
336
 
342
337
    def test_merge_uncommitted(self):
373
368
        """It should not be possible to merge changes from a file which
374
369
        does not exist."""
375
370
        tree_a = self.make_branch_and_tree('tree_a')
376
 
        self.build_tree_contents([('tree_a/file', b'bar\n')])
 
371
        self.build_tree_contents([('tree_a/file', 'bar\n')])
377
372
        tree_a.add(['file'])
378
373
        tree_a.commit('commit 1')
379
 
        self.run_bzr_error(('Path\\(s\\) do not exist: non/existing',),
 
374
        self.run_bzr_error(('Path\(s\) do not exist: non/existing',),
380
375
                           ['merge', 'non/existing'], working_dir='tree_a')
381
376
 
382
377
    def pullable_branch(self):
383
378
        tree_a = self.make_branch_and_tree('a')
384
 
        self.build_tree_contents([('a/file', b'bar\n')])
 
379
        self.build_tree_contents([('a/file', 'bar\n')])
385
380
        tree_a.add(['file'])
386
381
        self.id1 = tree_a.commit('commit 1')
387
382
 
388
383
        tree_b = self.make_branch_and_tree('b')
389
384
        tree_b.pull(tree_a.branch)
390
 
        self.build_tree_contents([('b/file', b'foo\n')])
 
385
        self.build_tree_contents([('b/file', 'foo\n')])
391
386
        self.id2 = tree_b.commit('commit 2')
392
387
 
393
388
    def test_merge_pull(self):
401
396
        self.pullable_branch()
402
397
        (out, err) = self.run_bzr('merge --pull --preview -d a b')
403
398
        self.assertThat(out, matchers.DocTestMatches(
404
 
            """=== modified file 'file'
 
399
"""=== modified file 'file'
405
400
--- file\t...
406
401
+++ file\t...
407
402
@@ -1,1 +1,1 @@
414
409
 
415
410
    def test_merge_kind_change(self):
416
411
        tree_a = self.make_branch_and_tree('tree_a')
417
 
        self.build_tree_contents([('tree_a/file', b'content_1')])
418
 
        tree_a.add('file', b'file-id')
 
412
        self.build_tree_contents([('tree_a/file', 'content_1')])
 
413
        tree_a.add('file', 'file-id')
419
414
        tree_a.commit('added file')
420
415
        tree_b = tree_a.controldir.sprout('tree_b').open_workingtree()
421
416
        os.unlink('tree_a/file')
425
420
        self.assertEqual('directory', osutils.file_kind('tree_b/file'))
426
421
        tree_b.revert()
427
422
        self.assertEqual('file', osutils.file_kind('tree_b/file'))
428
 
        self.build_tree_contents([('tree_b/file', b'content_2')])
 
423
        self.build_tree_contents([('tree_b/file', 'content_2')])
429
424
        tree_b.commit('content change')
430
425
        self.run_bzr('merge ../tree_a', retcode=1, working_dir='tree_b')
431
426
        self.assertEqual(tree_b.conflicts(),
432
 
                         [conflicts.ContentsConflict('file', file_id='file-id')])
 
427
                         [conflicts.ContentsConflict('file',
 
428
                                                     file_id='file-id')])
433
429
 
434
430
    def test_directive_cherrypick(self):
435
431
        source = self.make_branch_and_tree('source')
441
437
        target = source.controldir.sprout('target').open_workingtree()
442
438
        self.build_tree(['source/a'])
443
439
        source.add('a')
444
 
        source.commit('Added a', rev_id=b'rev1')
 
440
        source.commit('Added a', rev_id='rev1')
445
441
        self.build_tree(['source/b'])
446
442
        source.add('b')
447
 
        source.commit('Added b', rev_id=b'rev2')
 
443
        source.commit('Added b', rev_id='rev2')
448
444
        target.commit('empty commit')
449
 
        self.write_directive('directive', source.branch, 'target', b'rev2',
450
 
                             b'rev1')
 
445
        self.write_directive('directive', source.branch, 'target', 'rev2',
 
446
                             'rev1')
451
447
        out, err = self.run_bzr('merge -d target directive')
452
448
        self.assertPathDoesNotExist('target/a')
453
449
        self.assertPathExists('target/b')
459
455
            source.repository, revision_id, 0, 0, target,
460
456
            base_revision_id=base_revision_id)
461
457
        if mangle_patch:
462
 
            md.patch = b'asdf\n'
463
 
        self.build_tree_contents([(filename, b''.join(md.to_lines()))])
 
458
            md.patch = 'asdf\n'
 
459
        self.build_tree_contents([(filename, ''.join(md.to_lines()))])
464
460
 
465
461
    def test_directive_verify_warning(self):
466
462
        source = self.make_branch_and_tree('source')
467
463
        self.build_tree(['source/a'])
468
464
        source.add('a')
469
 
        source.commit('Added a', rev_id=b'rev1')
 
465
        source.commit('Added a', rev_id='rev1')
470
466
        target = self.make_branch_and_tree('target')
471
467
        target.commit('empty commit')
472
 
        self.write_directive('directive', source.branch, 'target', b'rev1')
 
468
        self.write_directive('directive', source.branch, 'target', 'rev1')
473
469
        err = self.run_bzr('merge -d target directive')[1]
474
470
        self.assertNotContainsRe(err, 'Preview patch does not match changes')
475
471
        target.revert()
476
 
        self.write_directive('directive', source.branch, 'target', b'rev1',
 
472
        self.write_directive('directive', source.branch, 'target', 'rev1',
477
473
                             mangle_patch=True)
478
474
        err = self.run_bzr('merge -d target directive')[1]
479
475
        self.assertContainsRe(err, 'Preview patch does not match changes')
485
481
        branch_a = target.controldir.sprout('branch_a').open_workingtree()
486
482
        self.build_tree(['branch_a/file1'])
487
483
        branch_a.add('file1')
488
 
        branch_a.commit('added file1', rev_id=b'rev2a')
 
484
        branch_a.commit('added file1', rev_id='rev2a')
489
485
        branch_b = target.controldir.sprout('branch_b').open_workingtree()
490
486
        self.build_tree(['branch_b/file2'])
491
487
        branch_b.add('file2')
492
 
        branch_b.commit('added file2', rev_id=b'rev2b')
 
488
        branch_b.commit('added file2', rev_id='rev2b')
493
489
        branch_b.merge_from_branch(branch_a.branch)
494
490
        self.assertPathExists('branch_b/file1')
495
 
        branch_b.commit('merged branch_a', rev_id=b'rev3b')
 
491
        branch_b.commit('merged branch_a', rev_id='rev3b')
496
492
 
497
493
        # It works if the revid has an interger revno
498
494
        self.run_bzr('merge -d target -r revid:rev2a branch_a')
523
519
        # make source branch
524
520
        source = self.make_branch_and_tree('source')
525
521
        for f in ('a', 'b', 'c', 'd'):
526
 
            self.build_tree(['source/' + f])
 
522
            self.build_tree(['source/'+f])
527
523
            source.add(f)
528
 
            source.commit('added ' + f, rev_id=b'rev_' + f.encode('ascii'))
 
524
            source.commit('added '+f, rev_id='rev_'+f)
529
525
        # target branch
530
 
        target = source.controldir.sprout(
531
 
            'target', b'rev_a').open_workingtree()
 
526
        target = source.controldir.sprout('target', 'rev_a').open_workingtree()
532
527
        self.assertDirectoryContent('target', ['.bzr', 'a'])
533
528
        # pick 1 revision
534
529
        self.run_bzr('merge -d target -r revid:rev_b..revid:rev_c source')
544
539
 
545
540
    def test_merge_criss_cross(self):
546
541
        tree_a = self.make_branch_and_tree('a')
547
 
        tree_a.commit('', rev_id=b'rev1')
 
542
        tree_a.commit('', rev_id='rev1')
548
543
        tree_b = tree_a.controldir.sprout('b').open_workingtree()
549
 
        tree_a.commit('', rev_id=b'rev2a')
550
 
        tree_b.commit('', rev_id=b'rev2b')
 
544
        tree_a.commit('', rev_id='rev2a')
 
545
        tree_b.commit('', rev_id='rev2b')
551
546
        tree_a.merge_from_branch(tree_b.branch)
552
547
        tree_b.merge_from_branch(tree_a.branch)
553
 
        tree_a.commit('', rev_id=b'rev3a')
554
 
        tree_b.commit('', rev_id=b'rev3b')
 
548
        tree_a.commit('', rev_id='rev3a')
 
549
        tree_b.commit('', rev_id='rev3b')
555
550
        graph = tree_a.branch.repository.get_graph(tree_b.branch.repository)
556
551
        out, err = self.run_bzr(['merge', '-d', 'a', 'b'])
557
552
        self.assertContainsRe(err, 'Warning: criss-cross merge encountered.')
563
558
        tree_c = tree_a.controldir.sprout('c').open_workingtree()
564
559
        out, err = self.run_bzr(['merge', '-d', 'c'])
565
560
        self.assertContainsRe(err,
566
 
                              'Merging from remembered parent location .*a\\/')
567
 
        with tree_c.branch.lock_write():
568
 
            tree_c.branch.set_submit_branch(
569
 
                tree_b.controldir.root_transport.base)
 
561
                              'Merging from remembered parent location .*a\/')
 
562
        tree_c.branch.lock_write()
 
563
        try:
 
564
            tree_c.branch.set_submit_branch(tree_b.controldir.root_transport.base)
 
565
        finally:
 
566
            tree_c.branch.unlock()
570
567
        out, err = self.run_bzr(['merge', '-d', 'c'])
571
568
        self.assertContainsRe(err,
572
 
                              'Merging from remembered submit location .*b\\/')
 
569
                              'Merging from remembered submit location .*b\/')
573
570
 
574
571
    def test_remember_sets_submit(self):
575
572
        tree_a = self.make_branch_and_tree('a')
590
587
 
591
588
    def test_no_remember_dont_set_submit(self):
592
589
        tree_a = self.make_branch_and_tree('a')
593
 
        self.build_tree_contents([('a/file', b"a\n")])
 
590
        self.build_tree_contents([('a/file', "a\n")])
594
591
        tree_a.add('file')
595
592
        tree_a.commit('rev1')
596
593
        tree_b = tree_a.controldir.sprout('b').open_workingtree()
607
604
 
608
605
    def test_weave_cherrypick(self):
609
606
        this_tree = self.make_branch_and_tree('this')
610
 
        self.build_tree_contents([('this/file', b"a\n")])
 
607
        self.build_tree_contents([('this/file', "a\n")])
611
608
        this_tree.add('file')
612
609
        this_tree.commit('rev1')
613
610
        other_tree = this_tree.controldir.sprout('other').open_workingtree()
614
 
        self.build_tree_contents([('other/file', b"a\nb\n")])
 
611
        self.build_tree_contents([('other/file', "a\nb\n")])
615
612
        other_tree.commit('rev2b')
616
 
        self.build_tree_contents([('other/file', b"c\na\nb\n")])
 
613
        self.build_tree_contents([('other/file', "c\na\nb\n")])
617
614
        other_tree.commit('rev3b')
618
615
        self.run_bzr('merge --weave -d this other -r -2..-1')
619
 
        self.assertFileEqual(b'c\na\n', 'this/file')
 
616
        self.assertFileEqual('c\na\n', 'this/file')
620
617
 
621
618
    def test_lca_merge_criss_cross(self):
622
619
        tree_a = self.make_branch_and_tree('a')
623
 
        self.build_tree_contents([('a/file', b'base-contents\n')])
 
620
        self.build_tree_contents([('a/file', 'base-contents\n')])
624
621
        tree_a.add('file')
625
 
        tree_a.commit('', rev_id=b'rev1')
 
622
        tree_a.commit('', rev_id='rev1')
626
623
        tree_b = tree_a.controldir.sprout('b').open_workingtree()
627
624
        self.build_tree_contents([('a/file',
628
 
                                   b'base-contents\nthis-contents\n')])
629
 
        tree_a.commit('', rev_id=b'rev2a')
 
625
                                   'base-contents\nthis-contents\n')])
 
626
        tree_a.commit('', rev_id='rev2a')
630
627
        self.build_tree_contents([('b/file',
631
 
                                   b'base-contents\nother-contents\n')])
632
 
        tree_b.commit('', rev_id=b'rev2b')
 
628
                                   'base-contents\nother-contents\n')])
 
629
        tree_b.commit('', rev_id='rev2b')
633
630
        tree_a.merge_from_branch(tree_b.branch)
634
631
        self.build_tree_contents([('a/file',
635
 
                                   b'base-contents\nthis-contents\n')])
636
 
        tree_a.set_conflicts([])
 
632
                                   'base-contents\nthis-contents\n')])
 
633
        tree_a.set_conflicts(conflicts.ConflictList())
637
634
        tree_b.merge_from_branch(tree_a.branch)
638
635
        self.build_tree_contents([('b/file',
639
 
                                   b'base-contents\nother-contents\n')])
640
 
        tree_b.set_conflicts([])
641
 
        tree_a.commit('', rev_id=b'rev3a')
642
 
        tree_b.commit('', rev_id=b'rev3b')
 
636
                                   'base-contents\nother-contents\n')])
 
637
        tree_b.set_conflicts(conflicts.ConflictList())
 
638
        tree_a.commit('', rev_id='rev3a')
 
639
        tree_b.commit('', rev_id='rev3b')
643
640
        out, err = self.run_bzr(['merge', '-d', 'a', 'b', '--lca'], retcode=1)
644
 
        self.assertFileEqual(b'base-contents\n<<<<<<< TREE\nthis-contents\n'
645
 
                             b'=======\nother-contents\n>>>>>>> MERGE-SOURCE\n',
 
641
        self.assertFileEqual('base-contents\n<<<<<<< TREE\nthis-contents\n'
 
642
                             '=======\nother-contents\n>>>>>>> MERGE-SOURCE\n',
646
643
                             'a/file')
647
644
 
648
645
    def test_merge_preview(self):
649
646
        this_tree = self.make_branch_and_tree('this')
650
647
        this_tree.commit('rev1')
651
648
        other_tree = this_tree.controldir.sprout('other').open_workingtree()
652
 
        self.build_tree_contents([('other/file', b'new line')])
 
649
        self.build_tree_contents([('other/file', 'new line')])
653
650
        other_tree.add('file')
654
651
        other_tree.commit('rev2a')
655
652
        this_tree.commit('rev2b')
656
653
        out, err = self.run_bzr(['merge', '-d', 'this', 'other', '--preview'])
657
 
        self.assertContainsRe(out, '\\+new line')
658
 
        self.assertNotContainsRe(err, '\\+N  file\n')
 
654
        self.assertContainsRe(out, '\+new line')
 
655
        self.assertNotContainsRe(err, '\+N  file\n')
659
656
        this_tree.lock_read()
660
657
        self.addCleanup(this_tree.unlock)
661
658
        self.assertEqual([],
687
684
        """
688
685
        # Make a source, sprout a target off it
689
686
        builder = self.make_branch_builder('source')
690
 
        builder.build_commit(message="Rev 1", rev_id=b'rev-1')
 
687
        builder.build_commit(message="Rev 1", rev_id='rev-1')
691
688
        source = builder.get_branch()
692
689
        target_bzrdir = source.controldir.sprout('target')
693
690
        # Add a non-ancestry tag to source
694
 
        builder.build_commit(message="Rev 2a", rev_id=b'rev-2a')
695
 
        source.tags.set_tag('tag-a', b'rev-2a')
696
 
        source.set_last_revision_info(1, b'rev-1')
 
691
        builder.build_commit(message="Rev 2a", rev_id='rev-2a')
 
692
        source.tags.set_tag('tag-a', 'rev-2a')
 
693
        source.set_last_revision_info(1, 'rev-1')
697
694
        source.get_config_stack().set('branch.fetch_tags', True)
698
 
        builder.build_commit(message="Rev 2b", rev_id=b'rev-2b')
 
695
        builder.build_commit(message="Rev 2b", rev_id='rev-2b')
699
696
        # Merge from source
700
697
        self.run_bzr('merge -d target source')
701
698
        target = target_bzrdir.open_branch()
702
699
        # The tag is present, and so is its revision.
703
 
        self.assertEqual(b'rev-2a', target.tags.lookup_tag('tag-a'))
704
 
        target.repository.get_revision(b'rev-2a')
 
700
        self.assertEqual('rev-2a', target.tags.lookup_tag('tag-a'))
 
701
        target.repository.get_revision('rev-2a')
705
702
 
706
703
 
707
704
class TestMergeRevisionRange(tests.TestCaseWithTransport):
729
726
        source = self.make_branch_and_tree('source')
730
727
        self.build_tree(['source/a'])
731
728
        source.add('a')
732
 
        source.commit('Added a', rev_id=b'rev1')
 
729
        source.commit('Added a', rev_id='rev1')
733
730
        target = self.make_branch_and_tree('target')
734
731
        self.run_script("""\
735
732
$ brz merge -d target source
736
733
2>brz: ERROR: Merging into empty branches not currently supported, https://bugs.launchpad.net/bzr/+bug/308562
737
734
""")
738
735
 
739
 
 
740
736
class TestMergeForce(tests.TestCaseWithTransport):
741
737
 
742
738
    def setUp(self):
746
742
        self.tree_a.add(['foo'])
747
743
        self.tree_a.commit('add file')
748
744
        self.tree_b = self.tree_a.controldir.sprout('b').open_workingtree()
749
 
        self.build_tree_contents([('a/foo', b'change 1')])
 
745
        self.build_tree_contents([('a/foo', 'change 1')])
750
746
        self.tree_a.commit('change file')
751
747
        self.tree_b.merge_from_branch(self.tree_a.branch)
752
748
 
755
751
        # Second merge on top of the uncommitted one
756
752
        self.run_bzr(['merge', '../a', '--force'], working_dir='b')
757
753
 
 
754
 
758
755
    def test_merge_with_uncommitted_changes(self):
759
756
        self.run_bzr_error(['Working tree .* has uncommitted changes'],
760
757
                           ['merge', '../a'], working_dir='b')