~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-05-05 08:29:29 UTC
  • mfrom: (1697.1.1 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20060505082929-a037ee137f1ff240
Merge break-lock command.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 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
23
23
 
24
24
from bzrlib.branch import Branch
25
25
from bzrlib.bzrdir import BzrDir
26
 
from bzrlib.conflicts import ConflictList, ContentsConflict
27
 
from bzrlib.osutils import abspath, file_kind
 
26
from bzrlib.osutils import abspath
28
27
from bzrlib.tests.blackbox import ExternalBase
29
 
import bzrlib.urlutils as urlutils
30
28
from bzrlib.workingtree import WorkingTree
31
29
 
32
30
 
33
31
class TestMerge(ExternalBase):
34
32
 
35
33
    def example_branch(test):
36
 
        test.run_bzr('init')
 
34
        test.runbzr('init')
37
35
        file('hello', 'wt').write('foo')
38
 
        test.run_bzr('add hello')
39
 
        test.run_bzr('commit -m setup hello')
 
36
        test.runbzr('add hello')
 
37
        test.runbzr('commit -m setup hello')
40
38
        file('goodbye', 'wt').write('baz')
41
 
        test.run_bzr('add goodbye')
42
 
        test.run_bzr('commit -m setup goodbye')
 
39
        test.runbzr('add goodbye')
 
40
        test.runbzr('commit -m setup goodbye')
43
41
 
44
42
    def test_merge_reprocess(self):
45
43
        d = BzrDir.create_standalone_workingtree('.')
46
44
        d.commit('h')
47
 
        self.run_bzr('merge . --reprocess --merge-type weave')
 
45
        self.run_bzr('merge', '.', '--reprocess', '--merge-type', 'weave')
48
46
 
49
47
    def test_merge(self):
50
48
        from bzrlib.branch import Branch
52
50
        os.mkdir('a')
53
51
        os.chdir('a')
54
52
        self.example_branch()
55
 
        ancestor = Branch.open('.').revno()
56
53
        os.chdir('..')
57
 
        self.run_bzr('branch a b')
 
54
        self.runbzr('branch a b')
58
55
        os.chdir('b')
59
56
        file('goodbye', 'wt').write('quux')
60
 
        self.run_bzr(['commit',  '-m',  "more u's are always good"])
 
57
        self.runbzr(['commit',  '-m',  "more u's are always good"])
61
58
 
62
59
        os.chdir('../a')
63
60
        file('hello', 'wt').write('quuux')
64
61
        # We can't merge when there are in-tree changes
65
 
        self.run_bzr('merge ../b', retcode=3)
66
 
        a = WorkingTree.open('.')
67
 
        a_tip = a.commit("Like an epidemic of u's")
68
 
        self.run_bzr('merge ../b -r last:1..last:1 --merge-type blooof',
 
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',
69
65
                    retcode=3)
70
 
        self.run_bzr('merge ../b -r last:1..last:1 --merge-type merge3')
71
 
        self.run_bzr('revert --no-backup')
72
 
        self.run_bzr('merge ../b -r last:1..last:1 --merge-type weave')
73
 
        self.run_bzr('revert --no-backup')
74
 
        self.run_bzr('merge ../b -r last:1..last:1 --reprocess')
75
 
        self.run_bzr('revert --no-backup')
76
 
        self.run_bzr('merge ../b -r last:1')
 
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')
77
73
        self.check_file_contents('goodbye', 'quux')
78
74
        # Merging a branch pulls its revision into the tree
 
75
        a = WorkingTree.open('.')
79
76
        b = Branch.open('../b')
80
 
        b_tip = b.last_revision()
81
 
        self.failUnless(a.branch.repository.has_revision(b_tip))
82
 
        self.assertEqual([a_tip, b_tip], a.get_parent_ids())
83
 
        self.run_bzr('revert --no-backup')
84
 
        out, err = self.run_bzr('merge -r revno:1:./hello', retcode=3)
85
 
        self.assertTrue("Not a branch" in err)
86
 
        self.run_bzr('merge -r revno:%d:./..revno:%d:../b'
87
 
                    %(ancestor,b.revno()))
88
 
        self.assertEquals(a.get_parent_ids(), 
89
 
                          [a.branch.last_revision(), b.last_revision()])
90
 
        self.check_file_contents('goodbye', 'quux')
91
 
        self.run_bzr('revert --no-backup')
92
 
        self.run_bzr('merge -r revno:%d:../b'%b.revno())
93
 
        self.assertEquals(a.get_parent_ids(),
94
 
                          [a.branch.last_revision(), b.last_revision()])
95
 
        a_tip = a.commit('merged')
96
 
        self.run_bzr('merge ../b -r last:1')
97
 
        self.assertEqual([a_tip], a.get_parent_ids())
 
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(), [])
98
84
 
99
85
    def test_merge_with_missing_file(self):
100
86
        """Merge handles missing file conflicts"""
104
90
        print >> file('sub/a.txt', 'wb'), "hello"
105
91
        print >> file('b.txt', 'wb'), "hello"
106
92
        print >> file('sub/c.txt', 'wb'), "hello"
107
 
        self.run_bzr('init')
108
 
        self.run_bzr('add')
109
 
        self.run_bzr(['commit', '-m', 'added a'])
110
 
        self.run_bzr('branch . ../b')
 
93
        self.runbzr('init')
 
94
        self.runbzr('add')
 
95
        self.runbzr(('commit', '-m', 'added a'))
 
96
        self.runbzr('branch . ../b')
111
97
        print >> file('sub/a.txt', 'ab'), "there"
112
98
        print >> file('b.txt', 'ab'), "there"
113
99
        print >> file('sub/c.txt', 'ab'), "there"
114
 
        self.run_bzr(['commit', '-m', 'Added there'])
 
100
        self.runbzr(('commit', '-m', 'Added there'))
115
101
        os.unlink('sub/a.txt')
116
102
        os.unlink('sub/c.txt')
117
103
        os.rmdir('sub')
118
104
        os.unlink('b.txt')
119
 
        self.run_bzr(['commit', '-m', 'Removed a.txt'])
 
105
        self.runbzr(('commit', '-m', 'Removed a.txt'))
120
106
        os.chdir('../b')
121
107
        print >> file('sub/a.txt', 'ab'), "something"
122
108
        print >> file('b.txt', 'ab'), "something"
123
109
        print >> file('sub/c.txt', 'ab'), "something"
124
 
        self.run_bzr(['commit', '-m', 'Modified a.txt'])
125
 
        self.run_bzr('merge ../a/', retcode=1)
 
110
        self.runbzr(('commit', '-m', 'Modified a.txt'))
 
111
        self.runbzr('merge ../a/', retcode=1)
126
112
        self.assert_(os.path.exists('sub/a.txt.THIS'))
127
113
        self.assert_(os.path.exists('sub/a.txt.BASE'))
128
114
        os.chdir('../a')
129
 
        self.run_bzr('merge ../b/', retcode=1)
 
115
        self.runbzr('merge ../b/', retcode=1)
130
116
        self.assert_(os.path.exists('sub/a.txt.OTHER'))
131
117
        self.assert_(os.path.exists('sub/a.txt.BASE'))
132
118
 
153
139
        self.assertEqual(None, branch_b.get_parent())
154
140
        # test merge for failure without parent set
155
141
        os.chdir('branch_b')
156
 
        out = self.run_bzr('merge', retcode=3)
 
142
        out = self.runbzr('merge', retcode=3)
157
143
        self.assertEquals(out,
158
 
                ('','bzr: ERROR: No location specified or remembered\n'))
 
144
                ('','bzr: ERROR: No merge branch known or specified.\n'))
159
145
        # test implicit --remember when no parent set, this merge conflicts
160
146
        self.build_tree(['d'])
161
147
        tree_b.add('d')
162
 
        out = self.run_bzr('merge ../branch_a', retcode=3)
 
148
        out = self.runbzr('merge ../branch_a', retcode=3)
163
149
        self.assertEquals(out,
164
150
                ('','bzr: ERROR: Working tree has uncommitted changes.\n'))
165
151
        self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
166
152
        # test implicit --remember after resolving conflict
167
153
        tree_b.commit('commit d')
168
 
        out, err = self.run_bzr('merge')
169
 
        
170
 
        base = urlutils.local_path_from_url(branch_a.base)
171
 
        self.assertEquals(out, 'Merging from remembered location %s\n' % (base,))
172
 
        self.assertEquals(err, '+N  b\nAll changes applied successfully.\n')
 
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')
173
157
        self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
174
 
        # re-open tree as external run_bzr modified it
 
158
        # re-open tree as external runbzr modified it
175
159
        tree_b = branch_b.bzrdir.open_workingtree()
176
160
        tree_b.commit('merge branch_a')
177
161
        # test explicit --remember
178
 
        out, err = self.run_bzr('merge ../branch_c --remember')
 
162
        out, err = self.runbzr('merge ../branch_c --remember')
179
163
        self.assertEquals(out, '')
180
 
        self.assertEquals(err, '+N  c\nAll changes applied successfully.\n')
 
164
        self.assertEquals(err, 'All changes applied successfully.\n')
181
165
        self.assertEquals(abspath(branch_b.get_parent()),
182
166
                          abspath(branch_c.bzrdir.root_transport.base))
183
 
        # re-open tree as external run_bzr modified it
 
167
        # re-open tree as external runbzr modified it
184
168
        tree_b = branch_b.bzrdir.open_workingtree()
185
169
        tree_b.commit('merge branch_c')
186
 
 
187
 
    def test_merge_bundle(self):
188
 
        from bzrlib.testament import Testament
189
 
        tree_a = self.make_branch_and_tree('branch_a')
190
 
        f = file('branch_a/a', 'wb')
191
 
        f.write('hello')
192
 
        f.close()
193
 
        tree_a.add('a')
194
 
        tree_a.commit('message')
195
 
 
196
 
        tree_b = tree_a.bzrdir.sprout('branch_b').open_workingtree()
197
 
        f = file('branch_a/a', 'wb')
198
 
        f.write('hey there')
199
 
        f.close()
200
 
        tree_a.commit('message')
201
 
 
202
 
        f = file('branch_b/a', 'wb')
203
 
        f.write('goodbye')
204
 
        f.close()
205
 
        tree_b.commit('message')
206
 
        os.chdir('branch_b')
207
 
        file('../bundle', 'wb').write(self.run_bzr('bundle ../branch_a')[0])
208
 
        os.chdir('../branch_a')
209
 
        self.run_bzr('merge ../bundle', retcode=1)
210
 
        testament_a = Testament.from_revision(tree_a.branch.repository,
211
 
                                              tree_b.get_parent_ids()[0])
212
 
        testament_b = Testament.from_revision(tree_b.branch.repository,
213
 
                                              tree_b.get_parent_ids()[0])
214
 
        self.assertEqualDiff(testament_a.as_text(),
215
 
                         testament_b.as_text())
216
 
        tree_a.set_conflicts(ConflictList())
217
 
        tree_a.commit('message')
218
 
        # it is legal to attempt to merge an already-merged bundle
219
 
        output = self.run_bzr('merge ../bundle')[1]
220
 
        # but it does nothing
221
 
        self.assertFalse(tree_a.changes_from(tree_a.basis_tree()).has_changed())
222
 
        self.assertEqual('Nothing to do.\n', output)
223
 
 
224
 
    def test_merge_uncommitted(self):
225
 
        """Check that merge --uncommitted behaves properly"""
226
 
        tree_a = self.make_branch_and_tree('a')
227
 
        self.build_tree(['a/file_1', 'a/file_2'])
228
 
        tree_a.add(['file_1', 'file_2'])
229
 
        tree_a.commit('commit 1')
230
 
        tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
231
 
        self.failUnlessExists('b/file_1')
232
 
        tree_a.rename_one('file_1', 'file_i')
233
 
        tree_a.commit('commit 2')
234
 
        tree_a.rename_one('file_2', 'file_ii')
235
 
        ## os.chdir('b')
236
 
        self.run_bzr('merge a --uncommitted -d b')
237
 
        self.failUnlessExists('b/file_1')
238
 
        self.failUnlessExists('b/file_ii')
239
 
        tree_b.revert([])
240
 
        self.run_bzr_error(('Cannot use --uncommitted and --revision',),
241
 
                           'merge /a --uncommitted -r1 -d b')
242
 
 
243
 
    def pullable_branch(self):
244
 
        os.mkdir('a')
245
 
        os.chdir('a')
246
 
        self.example_branch()
247
 
        os.chdir('..')
248
 
        self.run_bzr('branch a b')
249
 
        os.chdir('b')
250
 
        file('goodbye', 'wt').write('quux')
251
 
        self.run_bzr(['commit', '-m', "mode u's are always good"])
252
 
        os.chdir('../a')
253
 
 
254
 
    def pullable_branch(self):
255
 
        tree_a = self.make_branch_and_tree('a')
256
 
        self.build_tree(['a/file'])
257
 
        tree_a.add(['file'])
258
 
        self.id1 = tree_a.commit('commit 1')
259
 
        
260
 
        tree_b = self.make_branch_and_tree('b')
261
 
        tree_b.pull(tree_a.branch)
262
 
        file('b/file', 'wb').write('foo')
263
 
        self.id2 = tree_b.commit('commit 2')
264
 
 
265
 
    def test_merge_pull(self):
266
 
        self.pullable_branch()
267
 
        os.chdir('a')
268
 
        (out, err) = self.run_bzr('merge --pull ../b')
269
 
        self.assertContainsRe(err, 'Now on revision 2\\.')
270
 
        tree_a = WorkingTree.open('.')
271
 
        self.assertEqual([self.id2], tree_a.get_parent_ids())
272
 
 
273
 
    def test_merge_kind_change(self):
274
 
        tree_a = self.make_branch_and_tree('tree_a')
275
 
        self.build_tree_contents([('tree_a/file', 'content_1')])
276
 
        tree_a.add('file', 'file-id')
277
 
        tree_a.commit('added file')
278
 
        tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
279
 
        os.unlink('tree_a/file')
280
 
        self.build_tree(['tree_a/file/'])
281
 
        tree_a.commit('changed file to directory')
282
 
        os.chdir('tree_b')
283
 
        self.run_bzr('merge ../tree_a')
284
 
        self.assertEqual('directory', file_kind('file'))
285
 
        tree_b.revert([])
286
 
        self.assertEqual('file', file_kind('file'))
287
 
        self.build_tree_contents([('file', 'content_2')])
288
 
        tree_b.commit('content change')
289
 
        self.run_bzr('merge ../tree_a', retcode=1)
290
 
        self.assertEqual(tree_b.conflicts(),
291
 
                         [ContentsConflict('file', file_id='file-id')])