~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Martin Pool
  • Date: 2006-06-15 05:36:34 UTC
  • mto: This revision was merged to the branch mainline in revision 1797.
  • Revision ID: mbp@sourcefrog.net-20060615053634-4fd52ba691855659
Clean up many exception classes.

Errors indicating a user error are now shown with is_user_error on the
exception; use this rather than hardcoding a list of exceptions that should be
handled this way.

Exceptions now inherit from BzrNewException where possible to use consistent
formatting method.

Remove rather obsolete docstring test on Branch.missing_revisions.

Remove dead code from find_merge_base.


Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
#
 
17
# Author: Aaron Bentley <aaron.bentley@utoronto.ca>
 
18
 
 
19
"""Black-box tests for bzr merge.
 
20
"""
 
21
 
 
22
import os
 
23
 
 
24
from bzrlib.branch import Branch
 
25
from bzrlib.bzrdir import BzrDir
 
26
from bzrlib.osutils import abspath
 
27
from bzrlib.tests.blackbox import ExternalBase
 
28
from bzrlib.workingtree import WorkingTree
 
29
 
 
30
 
 
31
class TestMerge(ExternalBase):
 
32
 
 
33
    def example_branch(test):
 
34
        test.runbzr('init')
 
35
        file('hello', 'wt').write('foo')
 
36
        test.runbzr('add hello')
 
37
        test.runbzr('commit -m setup hello')
 
38
        file('goodbye', 'wt').write('baz')
 
39
        test.runbzr('add goodbye')
 
40
        test.runbzr('commit -m setup goodbye')
 
41
 
 
42
    def test_merge_reprocess(self):
 
43
        d = BzrDir.create_standalone_workingtree('.')
 
44
        d.commit('h')
 
45
        self.run_bzr('merge', '.', '--reprocess', '--merge-type', 'weave')
 
46
 
 
47
    def test_merge(self):
 
48
        from bzrlib.branch import Branch
 
49
        
 
50
        os.mkdir('a')
 
51
        os.chdir('a')
 
52
        self.example_branch()
 
53
        os.chdir('..')
 
54
        self.runbzr('branch a b')
 
55
        os.chdir('b')
 
56
        file('goodbye', 'wt').write('quux')
 
57
        self.runbzr(['commit',  '-m',  "more u's are always good"])
 
58
 
 
59
        os.chdir('../a')
 
60
        file('hello', 'wt').write('quuux')
 
61
        # We can't merge when there are in-tree changes
 
62
        self.runbzr('merge ../b', retcode=3)
 
63
        self.runbzr(['commit', '-m', "Like an epidemic of u's"])
 
64
        self.runbzr('merge ../b -r last:1..last:1 --merge-type blooof',
 
65
                    retcode=3)
 
66
        self.runbzr('merge ../b -r last:1..last:1 --merge-type merge3')
 
67
        self.runbzr('revert --no-backup')
 
68
        self.runbzr('merge ../b -r last:1..last:1 --merge-type weave')
 
69
        self.runbzr('revert --no-backup')
 
70
        self.runbzr('merge ../b -r last:1..last:1 --reprocess')
 
71
        self.runbzr('revert --no-backup')
 
72
        self.runbzr('merge ../b -r last:1')
 
73
        self.check_file_contents('goodbye', 'quux')
 
74
        # Merging a branch pulls its revision into the tree
 
75
        a = WorkingTree.open('.')
 
76
        b = Branch.open('../b')
 
77
        a.branch.repository.get_revision_xml(b.last_revision())
 
78
        self.log('pending merges: %s', a.pending_merges())
 
79
        self.assertEquals(a.pending_merges(),
 
80
                          [b.last_revision()])
 
81
        self.runbzr('commit -m merged')
 
82
        self.runbzr('merge ../b -r last:1')
 
83
        self.assertEqual(a.pending_merges(), [])
 
84
 
 
85
    def test_merge_with_missing_file(self):
 
86
        """Merge handles missing file conflicts"""
 
87
        os.mkdir('a')
 
88
        os.chdir('a')
 
89
        os.mkdir('sub')
 
90
        print >> file('sub/a.txt', 'wb'), "hello"
 
91
        print >> file('b.txt', 'wb'), "hello"
 
92
        print >> file('sub/c.txt', 'wb'), "hello"
 
93
        self.runbzr('init')
 
94
        self.runbzr('add')
 
95
        self.runbzr(('commit', '-m', 'added a'))
 
96
        self.runbzr('branch . ../b')
 
97
        print >> file('sub/a.txt', 'ab'), "there"
 
98
        print >> file('b.txt', 'ab'), "there"
 
99
        print >> file('sub/c.txt', 'ab'), "there"
 
100
        self.runbzr(('commit', '-m', 'Added there'))
 
101
        os.unlink('sub/a.txt')
 
102
        os.unlink('sub/c.txt')
 
103
        os.rmdir('sub')
 
104
        os.unlink('b.txt')
 
105
        self.runbzr(('commit', '-m', 'Removed a.txt'))
 
106
        os.chdir('../b')
 
107
        print >> file('sub/a.txt', 'ab'), "something"
 
108
        print >> file('b.txt', 'ab'), "something"
 
109
        print >> file('sub/c.txt', 'ab'), "something"
 
110
        self.runbzr(('commit', '-m', 'Modified a.txt'))
 
111
        self.runbzr('merge ../a/', retcode=1)
 
112
        self.assert_(os.path.exists('sub/a.txt.THIS'))
 
113
        self.assert_(os.path.exists('sub/a.txt.BASE'))
 
114
        os.chdir('../a')
 
115
        self.runbzr('merge ../b/', retcode=1)
 
116
        self.assert_(os.path.exists('sub/a.txt.OTHER'))
 
117
        self.assert_(os.path.exists('sub/a.txt.BASE'))
 
118
 
 
119
    def test_merge_remember(self):
 
120
        """Merge changes from one branch to another and test parent location."""
 
121
        tree_a = self.make_branch_and_tree('branch_a')
 
122
        branch_a = tree_a.branch
 
123
        self.build_tree(['branch_a/a'])
 
124
        tree_a.add('a')
 
125
        tree_a.commit('commit a')
 
126
        branch_b = branch_a.bzrdir.sprout('branch_b').open_branch()
 
127
        tree_b = branch_b.bzrdir.open_workingtree()
 
128
        branch_c = branch_a.bzrdir.sprout('branch_c').open_branch()
 
129
        tree_c = branch_c.bzrdir.open_workingtree()
 
130
        self.build_tree(['branch_a/b'])
 
131
        tree_a.add('b')
 
132
        tree_a.commit('commit b')
 
133
        self.build_tree(['branch_c/c'])
 
134
        tree_c.add('c')
 
135
        tree_c.commit('commit c')
 
136
        # reset parent
 
137
        parent = branch_b.get_parent()
 
138
        branch_b.set_parent(None)
 
139
        self.assertEqual(None, branch_b.get_parent())
 
140
        # test merge for failure without parent set
 
141
        os.chdir('branch_b')
 
142
        out = self.runbzr('merge', retcode=3)
 
143
        self.assertEquals(out,
 
144
                ('','bzr: ERROR: No merge branch known or specified.\n'))
 
145
        # test implicit --remember when no parent set, this merge conflicts
 
146
        self.build_tree(['d'])
 
147
        tree_b.add('d')
 
148
        out = self.runbzr('merge ../branch_a', retcode=3)
 
149
        self.assertEquals(out,
 
150
                ('','bzr: ERROR: Working tree has uncommitted changes.\n'))
 
151
        self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
 
152
        # test implicit --remember after resolving conflict
 
153
        tree_b.commit('commit d')
 
154
        out, err = self.runbzr('merge')
 
155
        self.assertEquals(out, 'Using saved branch: ../branch_a\n')
 
156
        self.assertEquals(err, 'All changes applied successfully.\n')
 
157
        self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
 
158
        # re-open tree as external runbzr modified it
 
159
        tree_b = branch_b.bzrdir.open_workingtree()
 
160
        tree_b.commit('merge branch_a')
 
161
        # test explicit --remember
 
162
        out, err = self.runbzr('merge ../branch_c --remember')
 
163
        self.assertEquals(out, '')
 
164
        self.assertEquals(err, 'All changes applied successfully.\n')
 
165
        self.assertEquals(abspath(branch_b.get_parent()),
 
166
                          abspath(branch_c.bzrdir.root_transport.base))
 
167
        # re-open tree as external runbzr modified it
 
168
        tree_b = branch_b.bzrdir.open_workingtree()
 
169
        tree_b.commit('merge branch_c')
 
170
 
 
171
    def test_merge_bundle(self):
 
172
        from bzrlib.testament import Testament
 
173
        tree_a = self.make_branch_and_tree('branch_a')
 
174
        f = file('branch_a/a', 'wb')
 
175
        f.write('hello')
 
176
        f.close()
 
177
        tree_a.add('a')
 
178
        tree_a.commit('message')
 
179
 
 
180
        tree_b = tree_a.bzrdir.sprout('branch_b').open_workingtree()
 
181
        f = file('branch_a/a', 'wb')
 
182
        f.write('hey there')
 
183
        f.close()
 
184
        tree_a.commit('message')
 
185
 
 
186
        f = file('branch_b/a', 'wb')
 
187
        f.write('goodbye')
 
188
        f.close()
 
189
        tree_b.commit('message')
 
190
        os.chdir('branch_b')
 
191
        file('../bundle', 'wb').write(self.runbzr('bundle ../branch_a')[0])
 
192
        os.chdir('../branch_a')
 
193
        self.runbzr('merge ../bundle', retcode=1)
 
194
        testament_a = Testament.from_revision(tree_a.branch.repository, 
 
195
                                              tree_b.last_revision())
 
196
        testament_b = Testament.from_revision(tree_b.branch.repository,
 
197
                                              tree_b.last_revision())
 
198
        self.assertEqualDiff(testament_a.as_text(),
 
199
                         testament_b.as_text())