~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: John Arbash Meinel
  • Date: 2010-08-13 19:08:57 UTC
  • mto: (5050.17.7 2.2)
  • mto: This revision was merged to the branch mainline in revision 5379.
  • Revision ID: john@arbash-meinel.com-20100813190857-mvzwnimrxvm0zimp
Lots of documentation updates.

We had a lot of http links pointing to the old domain. They should
all now be properly updated to the new domain. (only bazaar-vcs.org
entry left is for pqm, which seems to still reside at the old url.)

Also removed one 'TODO' doc entry about switching to binary xdelta, since
we basically did just that with groupcompress.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2006-2010 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
21
21
 
22
22
import os
23
23
 
24
 
from bzrlib import merge_directive
25
 
from bzrlib.branch import Branch
26
 
from bzrlib.bzrdir import BzrDir
27
 
from bzrlib.conflicts import ConflictList, ContentsConflict
28
 
from bzrlib.osutils import abspath, file_kind, pathjoin
29
 
from bzrlib.tests.blackbox import ExternalBase
30
 
import bzrlib.urlutils as urlutils
31
 
from bzrlib.workingtree import WorkingTree
32
 
 
33
 
 
34
 
class TestMerge(ExternalBase):
 
24
from bzrlib import (
 
25
    branch,
 
26
    bzrdir,
 
27
    conflicts,
 
28
    errors,
 
29
    merge_directive,
 
30
    osutils,
 
31
    tests,
 
32
    urlutils,
 
33
    workingtree,
 
34
    )
 
35
 
 
36
 
 
37
class TestMerge(tests.TestCaseWithTransport):
35
38
 
36
39
    def example_branch(self, path='.'):
37
40
        tree = self.make_branch_and_tree(path)
38
41
        self.build_tree_contents([
39
 
            (pathjoin(path, 'hello'), 'foo'),
40
 
            (pathjoin(path, 'goodbye'), 'baz')])
 
42
            (osutils.pathjoin(path, 'hello'), 'foo'),
 
43
            (osutils.pathjoin(path, 'goodbye'), 'baz')])
41
44
        tree.add('hello')
42
45
        tree.commit(message='setup')
43
46
        tree.add('goodbye')
63
66
        return tree, other
64
67
 
65
68
    def test_merge_reprocess(self):
66
 
        d = BzrDir.create_standalone_workingtree('.')
 
69
        d = bzrdir.BzrDir.create_standalone_workingtree('.')
67
70
        d.commit('h')
68
71
        self.run_bzr('merge . --reprocess --merge-type weave')
69
72
 
70
73
    def test_merge(self):
71
 
        from bzrlib.branch import Branch
72
 
 
73
74
        a_tree = self.example_branch('a')
74
75
        ancestor = a_tree.branch.revno()
75
76
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
80
81
        # We can't merge when there are in-tree changes
81
82
        os.chdir('a')
82
83
        self.run_bzr('merge ../b', retcode=3)
83
 
        a = WorkingTree.open('.')
 
84
        a = workingtree.WorkingTree.open('.')
84
85
        a_tip = a.commit("Like an epidemic of u's")
85
86
        self.run_bzr('merge ../b -r last:1..last:1 --merge-type blooof',
86
87
                    retcode=3)
99
100
        self.run_bzr('merge ../b -r last:1')
100
101
        self.check_file_contents('goodbye', 'quux')
101
102
        # Merging a branch pulls its revision into the tree
102
 
        b = Branch.open('../b')
 
103
        b = branch.Branch.open('../b')
103
104
        b_tip = b.last_revision()
104
105
        self.failUnless(a.branch.repository.has_revision(b_tip))
105
106
        self.assertEqual([a_tip, b_tip], a.get_parent_ids())
210
211
        self.failUnlessExists('sub/a.txt.OTHER')
211
212
        self.failUnlessExists('sub/a.txt.BASE')
212
213
 
 
214
    def test_conflict_leaves_base_this_other_files(self):
 
215
        tree, other = self.create_conflicting_branches()
 
216
        self.run_bzr('merge ../other', working_dir='tree',
 
217
                     retcode=1)
 
218
        self.assertFileEqual('a\nb\nc\n', 'tree/fname.BASE')
 
219
        self.assertFileEqual('a\nB\nD\n', 'tree/fname.OTHER')
 
220
        self.assertFileEqual('a\nB\nC\n', 'tree/fname.THIS')
 
221
 
 
222
    def test_weave_conflict_leaves_base_this_other_files(self):
 
223
        tree, other = self.create_conflicting_branches()
 
224
        self.run_bzr('merge ../other --weave', working_dir='tree',
 
225
                     retcode=1)
 
226
        self.assertFileEqual('a\nb\nc\n', 'tree/fname.BASE')
 
227
        self.assertFileEqual('a\nB\nD\n', 'tree/fname.OTHER')
 
228
        self.assertFileEqual('a\nB\nC\n', 'tree/fname.THIS')
 
229
 
213
230
    def test_merge_remember(self):
214
231
        """Merge changes from one branch to another, test submit location."""
215
232
        tree_a = self.make_branch_and_tree('branch_a')
249
266
 
250
267
        base = urlutils.local_path_from_url(branch_a.base)
251
268
        self.assertEndsWith(err, '+N  b\nAll changes applied successfully.\n')
252
 
        self.assertEquals(abspath(branch_b.get_submit_branch()),
253
 
                          abspath(parent))
 
269
        self.assertEquals(osutils.abspath(branch_b.get_submit_branch()),
 
270
                          osutils.abspath(parent))
254
271
        # test implicit --remember when committing new file
255
272
        self.build_tree(['e'])
256
273
        tree_b.add('e')
265
282
        out, err = self.run_bzr('merge ../branch_c --remember')
266
283
        self.assertEquals(out, '')
267
284
        self.assertEquals(err, '+N  c\nAll changes applied successfully.\n')
268
 
        self.assertEquals(abspath(branch_b.get_submit_branch()),
269
 
                          abspath(branch_c.bzrdir.root_transport.base))
 
285
        self.assertEquals(osutils.abspath(branch_b.get_submit_branch()),
 
286
                          osutils.abspath(branch_c.bzrdir.root_transport.base))
270
287
        # re-open tree as external run_bzr modified it
271
288
        tree_b = branch_b.bzrdir.open_workingtree()
272
289
        tree_b.commit('merge branch_c')
294
311
                                              tree_b.get_parent_ids()[0])
295
312
        self.assertEqualDiff(testament_a.as_text(),
296
313
                         testament_b.as_text())
297
 
        tree_a.set_conflicts(ConflictList())
 
314
        tree_a.set_conflicts(conflicts.ConflictList())
298
315
        tree_a.commit('message')
299
316
        # it is legal to attempt to merge an already-merged bundle
300
317
        output = self.run_bzr('merge ../bundle')[1]
349
366
        os.chdir('a')
350
367
        (out, err) = self.run_bzr('merge --pull ../b')
351
368
        self.assertContainsRe(out, 'Now on revision 2\\.')
352
 
        tree_a = WorkingTree.open('.')
 
369
        tree_a = workingtree.WorkingTree.open('.')
353
370
        self.assertEqual([self.id2], tree_a.get_parent_ids())
354
371
 
355
372
    def test_merge_kind_change(self):
363
380
        tree_a.commit('changed file to directory')
364
381
        os.chdir('tree_b')
365
382
        self.run_bzr('merge ../tree_a')
366
 
        self.assertEqual('directory', file_kind('file'))
 
383
        self.assertEqual('directory', osutils.file_kind('file'))
367
384
        tree_b.revert()
368
 
        self.assertEqual('file', file_kind('file'))
 
385
        self.assertEqual('file', osutils.file_kind('file'))
369
386
        self.build_tree_contents([('file', 'content_2')])
370
387
        tree_b.commit('content change')
371
388
        self.run_bzr('merge ../tree_a', retcode=1)
372
389
        self.assertEqual(tree_b.conflicts(),
373
 
                         [ContentsConflict('file', file_id='file-id')])
 
390
                         [conflicts.ContentsConflict('file',
 
391
                                                     file_id='file-id')])
374
392
 
375
393
    def test_directive_cherrypick(self):
376
394
        source = self.make_branch_and_tree('source')
 
395
        source.commit("nothing")
 
396
        # see https://bugs.launchpad.net/bzr/+bug/409688 - trying to
 
397
        # cherrypick from one branch into another unrelated branch with a
 
398
        # different root id will give shape conflicts.  as a workaround we
 
399
        # make sure they share the same root id.
 
400
        target = source.bzrdir.sprout('target').open_workingtree()
377
401
        self.build_tree(['source/a'])
378
402
        source.add('a')
379
403
        source.commit('Added a', rev_id='rev1')
380
404
        self.build_tree(['source/b'])
381
405
        source.add('b')
382
406
        source.commit('Added b', rev_id='rev2')
383
 
        target = self.make_branch_and_tree('target')
384
407
        target.commit('empty commit')
385
408
        self.write_directive('directive', source.branch, 'target', 'rev2',
386
409
                             'rev1')
491
514
        out, err = self.run_bzr(['merge', '-d', 'a', 'b'])
492
515
        self.assertContainsRe(err, 'Warning: criss-cross merge encountered.')
493
516
 
494
 
    def test_merge_force(self):
495
 
        tree_a = self.make_branch_and_tree('a')
496
 
        self.build_tree(['a/foo'])
497
 
        tree_a.add(['foo'])
498
 
        tree_a.commit('add file')
499
 
        tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
500
 
        self.build_tree_contents([('a/foo', 'change 1')])
501
 
        tree_a.commit('change file')
502
 
        tree_b.merge_from_branch(tree_a.branch)
503
 
        tree_a.commit('empty change to allow merge to run')
504
 
        self.run_bzr(['merge', '../a', '--force'], working_dir='b')
505
 
 
506
517
    def test_merge_from_submit(self):
507
518
        tree_a = self.make_branch_and_tree('a')
508
519
        tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
555
566
        tree_a.merge_from_branch(tree_b.branch)
556
567
        self.build_tree_contents([('a/file',
557
568
                                   'base-contents\nthis-contents\n')])
558
 
        tree_a.set_conflicts(ConflictList())
 
569
        tree_a.set_conflicts(conflicts.ConflictList())
559
570
        tree_b.merge_from_branch(tree_a.branch)
560
571
        self.build_tree_contents([('b/file',
561
572
                                   'base-contents\nother-contents\n')])
562
 
        tree_b.set_conflicts(ConflictList())
 
573
        tree_b.set_conflicts(conflicts.ConflictList())
563
574
        tree_a.commit('', rev_id='rev3a')
564
575
        tree_b.commit('', rev_id='rev3b')
565
576
        out, err = self.run_bzr(['merge', '-d', 'a', 'b', '--lca'], retcode=1)
582
593
        self.addCleanup(this_tree.unlock)
583
594
        self.assertEqual([],
584
595
                         list(this_tree.iter_changes(this_tree.basis_tree())))
 
596
 
 
597
    def test_merge_missing_second_revision_spec(self):
 
598
        """Merge uses branch basis when the second revision is unspecified."""
 
599
        this = self.make_branch_and_tree('this')
 
600
        this.commit('rev1')
 
601
        other = self.make_branch_and_tree('other')
 
602
        self.build_tree(['other/other_file'])
 
603
        other.add('other_file')
 
604
        other.commit('rev1b')
 
605
        self.run_bzr('merge -d this other -r0..')
 
606
        self.failUnlessExists('this/other_file')
 
607
 
 
608
    def test_merge_interactive_unlocks_branch(self):
 
609
        this = self.make_branch_and_tree('this')
 
610
        other = self.make_branch_and_tree('other')
 
611
        other.commit('empty commit')
 
612
        self.run_bzr('merge -i -d this other')
 
613
        this.lock_write()
 
614
        this.unlock()
 
615
 
 
616
    def test_merge_reversed_revision_range(self):
 
617
        tree = self.make_branch_and_tree(".")
 
618
        for f in ("a", "b"):
 
619
            self.build_tree([f])
 
620
            tree.add(f)
 
621
            tree.commit("added "+f)
 
622
        for context in (".", "", "a"):
 
623
            self.run_bzr("merge -r 1..0 " + context)
 
624
            self.failIfExists("a")
 
625
            tree.revert()
 
626
            self.failUnlessExists("a")
 
627
 
 
628
 
 
629
class TestMergeForce(tests.TestCaseWithTransport):
 
630
 
 
631
    def setUp(self):
 
632
        super(TestMergeForce, self).setUp()
 
633
        self.tree_a = self.make_branch_and_tree('a')
 
634
        self.build_tree(['a/foo'])
 
635
        self.tree_a.add(['foo'])
 
636
        self.tree_a.commit('add file')
 
637
        self.tree_b = self.tree_a.bzrdir.sprout('b').open_workingtree()
 
638
        self.build_tree_contents([('a/foo', 'change 1')])
 
639
        self.tree_a.commit('change file')
 
640
        self.tree_b.merge_from_branch(self.tree_a.branch)
 
641
 
 
642
    def test_merge_force(self):
 
643
        self.tree_a.commit('empty change to allow merge to run')
 
644
        # Second merge on top of the uncommitted one
 
645
        self.run_bzr(['merge', '../a', '--force'], working_dir='b')
 
646
 
 
647
 
 
648
    def test_merge_with_uncommitted_changes(self):
 
649
        self.run_bzr_error(['Working tree .* has uncommitted changes'],
 
650
                           ['merge', '../a'], working_dir='b')
 
651
 
 
652
    def test_merge_with_pending_merges(self):
 
653
        # Revert the changes keeping the pending merge
 
654
        self.run_bzr(['revert', 'b'])
 
655
        self.run_bzr_error(['Working tree .* has uncommitted changes'],
 
656
                           ['merge', '../a'], working_dir='b')