~bzr-pqm/bzr/bzr.dev

2279.3.1 by mbp at sourcefrog
Add a -d option to push, pull, merge (ported from tags branch)
1
# Copyright (C) 2006, 2007 Canonical Ltd
1551.6.16 by Aaron Bentley
Merge from bzr.dev
2
#
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
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.
1551.6.16 by Aaron Bentley
Merge from bzr.dev
7
#
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
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.
1551.6.16 by Aaron Bentley
Merge from bzr.dev
12
#
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
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
1551.6.16 by Aaron Bentley
Merge from bzr.dev
16
#
17
# Author: Aaron Bentley <aaron.bentley@utoronto.ca>
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
18
19
"""Black-box tests for bzr merge.
20
"""
21
22
import os
23
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
24
from bzrlib import merge_directive
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
25
from bzrlib.branch import Branch
1551.6.16 by Aaron Bentley
Merge from bzr.dev
26
from bzrlib.bzrdir import BzrDir
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
27
from bzrlib.conflicts import ConflictList, ContentsConflict
2738.3.2 by Daniel Watkins
Modified as per abentley's comments.
28
from bzrlib.osutils import abspath, file_kind, pathjoin
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
29
from bzrlib.tests.blackbox import ExternalBase
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
30
import bzrlib.urlutils as urlutils
1551.6.16 by Aaron Bentley
Merge from bzr.dev
31
from bzrlib.workingtree import WorkingTree
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
32
1614.2.6 by Olaf Conradi
Add testcase for --remember when merge fails. It should still remember
33
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
34
class TestMerge(ExternalBase):
35
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
36
    def example_branch(self, path='.'):
37
        tree = self.make_branch_and_tree(path)
38
        self.build_tree_contents([
2738.3.3 by Daniel Watkins
Minor reformatting per abentley's mailing list comments.
39
            (pathjoin(path, 'hello'), 'foo'),
2738.3.2 by Daniel Watkins
Modified as per abentley's comments.
40
            (pathjoin(path, 'goodbye'), 'baz')])
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
41
        tree.add('hello')
42
        tree.commit(message='setup')
43
        tree.add('goodbye')
44
        tree.commit(message='setup')
45
        return tree
1551.6.16 by Aaron Bentley
Merge from bzr.dev
46
47
    def test_merge_reprocess(self):
48
        d = BzrDir.create_standalone_workingtree('.')
49
        d.commit('h')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
50
        self.run_bzr('merge . --reprocess --merge-type weave')
1551.6.16 by Aaron Bentley
Merge from bzr.dev
51
52
    def test_merge(self):
53
        from bzrlib.branch import Branch
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
54
55
        a_tree = self.example_branch('a')
2738.3.2 by Daniel Watkins
Modified as per abentley's comments.
56
        ancestor = a_tree.branch.revno()
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
57
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
58
        self.build_tree_contents([('b/goodbye', 'quux')])
59
        b_tree.commit(message="more u's are always good")
60
61
        self.build_tree_contents([('a/hello', 'quuux')])
1551.6.16 by Aaron Bentley
Merge from bzr.dev
62
        # We can't merge when there are in-tree changes
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
63
        os.chdir('a')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
64
        self.run_bzr('merge ../b', retcode=3)
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
65
        a = WorkingTree.open('.')
66
        a_tip = a.commit("Like an epidemic of u's")
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
67
        self.run_bzr('merge ../b -r last:1..last:1 --merge-type blooof',
1551.6.16 by Aaron Bentley
Merge from bzr.dev
68
                    retcode=3)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
69
        self.run_bzr('merge ../b -r last:1..last:1 --merge-type merge3')
2796.1.4 by Aaron Bentley
Fix up various test cases
70
        a_tree.revert(backups=False)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
71
        self.run_bzr('merge ../b -r last:1..last:1 --merge-type weave')
2796.1.4 by Aaron Bentley
Fix up various test cases
72
        a_tree.revert(backups=False)
2665.2.1 by Michael Hudson
test and fix for a NameError in merge --weave --show-base
73
        self.run_bzr_error(['Show-base is not supported for this merge type'],
74
                           'merge ../b -r last:1..last:1 --merge-type weave'
75
                           ' --show-base')
2796.1.4 by Aaron Bentley
Fix up various test cases
76
        a_tree.revert(backups=False)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
77
        self.run_bzr('merge ../b -r last:1..last:1 --reprocess')
2796.1.4 by Aaron Bentley
Fix up various test cases
78
        a_tree.revert(backups=False)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
79
        self.run_bzr('merge ../b -r last:1')
1551.6.16 by Aaron Bentley
Merge from bzr.dev
80
        self.check_file_contents('goodbye', 'quux')
81
        # Merging a branch pulls its revision into the tree
82
        b = Branch.open('../b')
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
83
        b_tip = b.last_revision()
84
        self.failUnless(a.branch.repository.has_revision(b_tip))
85
        self.assertEqual([a_tip, b_tip], a.get_parent_ids())
2796.1.4 by Aaron Bentley
Fix up various test cases
86
        a_tree.revert(backups=False)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
87
        out, err = self.run_bzr('merge -r revno:1:./hello', retcode=3)
1907.4.13 by Matthieu Moy
Better testcase for revno:N:branch/path error.
88
        self.assertTrue("Not a branch" in err)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
89
        self.run_bzr('merge -r revno:%d:./..revno:%d:../b'
1907.4.12 by Matthieu Moy
Made merge work with two revisions in different branches.
90
                    %(ancestor,b.revno()))
1551.8.25 by Aaron Bentley
Fix deprecated use of pending_merges
91
        self.assertEquals(a.get_parent_ids(), 
92
                          [a.branch.last_revision(), b.last_revision()])
1907.4.12 by Matthieu Moy
Made merge work with two revisions in different branches.
93
        self.check_file_contents('goodbye', 'quux')
2796.1.4 by Aaron Bentley
Fix up various test cases
94
        a_tree.revert(backups=False)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
95
        self.run_bzr('merge -r revno:%d:../b'%b.revno())
1551.8.25 by Aaron Bentley
Fix deprecated use of pending_merges
96
        self.assertEquals(a.get_parent_ids(),
97
                          [a.branch.last_revision(), b.last_revision()])
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
98
        a_tip = a.commit('merged')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
99
        self.run_bzr('merge ../b -r last:1')
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
100
        self.assertEqual([a_tip], a.get_parent_ids())
1551.6.16 by Aaron Bentley
Merge from bzr.dev
101
102
    def test_merge_with_missing_file(self):
103
        """Merge handles missing file conflicts"""
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
104
        self.build_tree_contents([
2738.3.4 by Daniel Watkins
Fixed tuple spacing.
105
            ('a/',),
106
            ('a/sub/',),
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
107
            ('a/sub/a.txt', 'hello\n'),
2738.3.3 by Daniel Watkins
Minor reformatting per abentley's mailing list comments.
108
            ('a/b.txt', 'hello\n'),
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
109
            ('a/sub/c.txt', 'hello\n')])
110
        a_tree = self.make_branch_and_tree('a')
111
        a_tree.add(['sub', 'b.txt', 'sub/c.txt', 'sub/a.txt'])
112
        a_tree.commit(message='added a')
113
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
114
        self.build_tree_contents([
115
            ('a/sub/a.txt', 'hello\nthere\n'),
2738.3.3 by Daniel Watkins
Minor reformatting per abentley's mailing list comments.
116
            ('a/b.txt', 'hello\nthere\n'),
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
117
            ('a/sub/c.txt', 'hello\nthere\n')])
118
        a_tree.commit(message='Added there')
119
        os.remove('a/sub/a.txt')
120
        os.remove('a/sub/c.txt')
121
        os.rmdir('a/sub')
122
        os.remove('a/b.txt')
123
        a_tree.commit(message='Removed a.txt')
124
        self.build_tree_contents([
125
            ('b/sub/a.txt', 'hello\nsomething\n'),
2738.3.3 by Daniel Watkins
Minor reformatting per abentley's mailing list comments.
126
            ('b/b.txt', 'hello\nsomething\n'),
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
127
            ('b/sub/c.txt', 'hello\nsomething\n')])
128
        b_tree.commit(message='Modified a.txt')
129
        os.chdir('b')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
130
        self.run_bzr('merge ../a/', retcode=1)
2738.3.2 by Daniel Watkins
Modified as per abentley's comments.
131
        self.failUnlessExists('sub/a.txt.THIS')
132
        self.failUnlessExists('sub/a.txt.BASE')
1551.6.16 by Aaron Bentley
Merge from bzr.dev
133
        os.chdir('../a')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
134
        self.run_bzr('merge ../b/', retcode=1)
2738.3.2 by Daniel Watkins
Modified as per abentley's comments.
135
        self.failUnlessExists('sub/a.txt.OTHER')
136
        self.failUnlessExists('sub/a.txt.BASE')
1551.6.16 by Aaron Bentley
Merge from bzr.dev
137
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
138
    def test_merge_remember(self):
139
        """Merge changes from one branch to another and test parent location."""
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
140
        tree_a = self.make_branch_and_tree('branch_a')
141
        branch_a = tree_a.branch
142
        self.build_tree(['branch_a/a'])
143
        tree_a.add('a')
144
        tree_a.commit('commit a')
145
        branch_b = branch_a.bzrdir.sprout('branch_b').open_branch()
146
        tree_b = branch_b.bzrdir.open_workingtree()
147
        branch_c = branch_a.bzrdir.sprout('branch_c').open_branch()
148
        tree_c = branch_c.bzrdir.open_workingtree()
149
        self.build_tree(['branch_a/b'])
150
        tree_a.add('b')
151
        tree_a.commit('commit b')
152
        self.build_tree(['branch_c/c'])
153
        tree_c.add('c')
154
        tree_c.commit('commit c')
1614.2.6 by Olaf Conradi
Add testcase for --remember when merge fails. It should still remember
155
        # reset parent
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
156
        parent = branch_b.get_parent()
157
        branch_b.set_parent(None)
158
        self.assertEqual(None, branch_b.get_parent())
1614.2.6 by Olaf Conradi
Add testcase for --remember when merge fails. It should still remember
159
        # test merge for failure without parent set
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
160
        os.chdir('branch_b')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
161
        out = self.run_bzr('merge', retcode=3)
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
162
        self.assertEquals(out,
1685.1.59 by Martin Pool
[broken] Fix up & refactor display of remembered urls to unescape properly
163
                ('','bzr: ERROR: No location specified or remembered\n'))
1614.2.6 by Olaf Conradi
Add testcase for --remember when merge fails. It should still remember
164
        # test implicit --remember when no parent set, this merge conflicts
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
165
        self.build_tree(['d'])
166
        tree_b.add('d')
2796.2.14 by Aaron Bentley
Updates from review
167
        self.run_bzr_error(['Working tree ".*" has uncommitted changes'],
168
                           'merge ../branch_a')
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
169
        self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
1614.2.6 by Olaf Conradi
Add testcase for --remember when merge fails. It should still remember
170
        # test implicit --remember after resolving conflict
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
171
        tree_b.commit('commit d')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
172
        out, err = self.run_bzr('merge')
1685.1.38 by John Arbash Meinel
Fix merge_remember to use a complete path.
173
        
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
174
        base = urlutils.local_path_from_url(branch_a.base)
1685.1.59 by Martin Pool
[broken] Fix up & refactor display of remembered urls to unescape properly
175
        self.assertEquals(out, 'Merging from remembered location %s\n' % (base,))
1551.11.11 by Aaron Bentley
Get tests passing
176
        self.assertEquals(err, '+N  b\nAll changes applied successfully.\n')
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
177
        self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
178
        # re-open tree as external run_bzr modified it
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
179
        tree_b = branch_b.bzrdir.open_workingtree()
180
        tree_b.commit('merge branch_a')
1614.2.6 by Olaf Conradi
Add testcase for --remember when merge fails. It should still remember
181
        # test explicit --remember
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
182
        out, err = self.run_bzr('merge ../branch_c --remember')
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
183
        self.assertEquals(out, '')
1551.11.11 by Aaron Bentley
Get tests passing
184
        self.assertEquals(err, '+N  c\nAll changes applied successfully.\n')
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
185
        self.assertEquals(abspath(branch_b.get_parent()),
186
                          abspath(branch_c.bzrdir.root_transport.base))
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
187
        # re-open tree as external run_bzr modified it
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
188
        tree_b = branch_b.bzrdir.open_workingtree()
189
        tree_b.commit('merge branch_c')
1185.82.22 by Aaron Bentley
Start getting changeset merging under test
190
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
191
    def test_merge_bundle(self):
1185.82.33 by Aaron Bentley
Strengthen tests
192
        from bzrlib.testament import Testament
1185.82.22 by Aaron Bentley
Start getting changeset merging under test
193
        tree_a = self.make_branch_and_tree('branch_a')
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
194
        self.build_tree_contents([('branch_a/a', 'hello')])
1185.82.22 by Aaron Bentley
Start getting changeset merging under test
195
        tree_a.add('a')
196
        tree_a.commit('message')
197
198
        tree_b = tree_a.bzrdir.sprout('branch_b').open_workingtree()
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
199
        self.build_tree_contents([('branch_a/a', 'hey there')])
1185.82.23 by Aaron Bentley
Switch the fetcher
200
        tree_a.commit('message')
201
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
202
        self.build_tree_contents([('branch_b/a', 'goodbye')])
1185.82.22 by Aaron Bentley
Start getting changeset merging under test
203
        tree_b.commit('message')
204
        os.chdir('branch_b')
2654.3.1 by Aaron Bentley
Rename submit to send, make -o required, support -o- for stdout
205
        self.run_bzr('bundle ../branch_a -o ../bundle')
1185.82.26 by Aaron Bentley
Get changeset merges closer to working
206
        os.chdir('../branch_a')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
207
        self.run_bzr('merge ../bundle', retcode=1)
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
208
        testament_a = Testament.from_revision(tree_a.branch.repository,
209
                                              tree_b.get_parent_ids()[0])
1185.82.33 by Aaron Bentley
Strengthen tests
210
        testament_b = Testament.from_revision(tree_b.branch.repository,
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
211
                                              tree_b.get_parent_ids()[0])
1185.82.33 by Aaron Bentley
Strengthen tests
212
        self.assertEqualDiff(testament_a.as_text(),
213
                         testament_b.as_text())
1185.82.141 by Aaron Bentley
Ensure bzr works when you merge an already-merged bundle
214
        tree_a.set_conflicts(ConflictList())
215
        tree_a.commit('message')
216
        # it is legal to attempt to merge an already-merged bundle
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
217
        output = self.run_bzr('merge ../bundle')[1]
1185.82.141 by Aaron Bentley
Ensure bzr works when you merge an already-merged bundle
218
        # but it does nothing
1852.10.3 by Robert Collins
Remove all uses of compare_trees and replace with Tree.changes_from throughout bzrlib.
219
        self.assertFalse(tree_a.changes_from(tree_a.basis_tree()).has_changed())
1185.82.142 by Aaron Bentley
Update for review comments
220
        self.assertEqual('Nothing to do.\n', output)
1910.1.1 by Aaron Bentley
Merge takes --uncommitted parameter
221
222
    def test_merge_uncommitted(self):
223
        """Check that merge --uncommitted behaves properly"""
224
        tree_a = self.make_branch_and_tree('a')
225
        self.build_tree(['a/file_1', 'a/file_2'])
226
        tree_a.add(['file_1', 'file_2'])
227
        tree_a.commit('commit 1')
228
        tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
229
        self.failUnlessExists('b/file_1')
230
        tree_a.rename_one('file_1', 'file_i')
231
        tree_a.commit('commit 2')
232
        tree_a.rename_one('file_2', 'file_ii')
2279.3.1 by mbp at sourcefrog
Add a -d option to push, pull, merge (ported from tags branch)
233
        ## os.chdir('b')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
234
        self.run_bzr('merge a --uncommitted -d b')
2279.3.1 by mbp at sourcefrog
Add a -d option to push, pull, merge (ported from tags branch)
235
        self.failUnlessExists('b/file_1')
236
        self.failUnlessExists('b/file_ii')
2748.3.2 by Aaron Bentley
Fix revert, remove-tree, and various tests to use None for 'no files specified'
237
        tree_b.revert()
2279.3.1 by mbp at sourcefrog
Add a -d option to push, pull, merge (ported from tags branch)
238
        self.run_bzr_error(('Cannot use --uncommitted and --revision',),
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
239
                           'merge /a --uncommitted -r1 -d b')
2149.2.1 by Jan Hudec
Option --pull for merge command.
240
3017.3.1 by Aaron Bentley
merge --uncommit can now specify single files (#136890)
241
    def test_merge_uncommitted_file(self):
242
        """It should be possible to merge changes from a single file."""
243
        tree_a = self.make_branch_and_tree('tree_a')
244
        tree_a.commit('initial commit')
245
        tree_a.bzrdir.sprout('tree_b')
246
        self.build_tree(['tree_a/file1', 'tree_a/file2'])
247
        tree_a.add(['file1', 'file2'])
248
        os.chdir('tree_b')
249
        self.run_bzr(['merge', '--uncommitted', '../tree_a/file1'])
250
        self.failUnlessExists('file1')
251
        self.failIfExists('file2')
252
2149.2.1 by Jan Hudec
Option --pull for merge command.
253
    def pullable_branch(self):
254
        tree_a = self.make_branch_and_tree('a')
255
        self.build_tree(['a/file'])
256
        tree_a.add(['file'])
257
        self.id1 = tree_a.commit('commit 1')
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
258
2149.2.1 by Jan Hudec
Option --pull for merge command.
259
        tree_b = self.make_branch_and_tree('b')
260
        tree_b.pull(tree_a.branch)
261
        file('b/file', 'wb').write('foo')
262
        self.id2 = tree_b.commit('commit 2')
263
264
    def test_merge_pull(self):
265
        self.pullable_branch()
266
        os.chdir('a')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
267
        (out, err) = self.run_bzr('merge --pull ../b')
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
268
        self.assertContainsRe(out, 'Now on revision 2\\.')
2149.2.1 by Jan Hudec
Option --pull for merge command.
269
        tree_a = WorkingTree.open('.')
270
        self.assertEqual([self.id2], tree_a.get_parent_ids())
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
271
272
    def test_merge_kind_change(self):
273
        tree_a = self.make_branch_and_tree('tree_a')
274
        self.build_tree_contents([('tree_a/file', 'content_1')])
275
        tree_a.add('file', 'file-id')
276
        tree_a.commit('added file')
277
        tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
278
        os.unlink('tree_a/file')
279
        self.build_tree(['tree_a/file/'])
280
        tree_a.commit('changed file to directory')
281
        os.chdir('tree_b')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
282
        self.run_bzr('merge ../tree_a')
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
283
        self.assertEqual('directory', file_kind('file'))
2748.3.2 by Aaron Bentley
Fix revert, remove-tree, and various tests to use None for 'no files specified'
284
        tree_b.revert()
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
285
        self.assertEqual('file', file_kind('file'))
286
        self.build_tree_contents([('file', 'content_2')])
287
        tree_b.commit('content change')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
288
        self.run_bzr('merge ../tree_a', retcode=1)
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
289
        self.assertEqual(tree_b.conflicts(),
290
                         [ContentsConflict('file', file_id='file-id')])
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
291
292
    def test_directive_cherrypick(self):
293
        source = self.make_branch_and_tree('source')
294
        self.build_tree(['source/a'])
295
        source.add('a')
296
        source.commit('Added a', rev_id='rev1')
297
        self.build_tree(['source/b'])
298
        source.add('b')
299
        source.commit('Added b', rev_id='rev2')
300
        target = self.make_branch_and_tree('target')
301
        target.commit('empty commit')
2520.4.111 by Aaron Bentley
Ensure that damaged preview patches produce a warning in merge
302
        self.write_directive('directive', source.branch, 'target', 'rev2',
303
                             'rev1')
1551.19.22 by Aaron Bentley
Add warning when merge directives cause cherrypicks
304
        out, err = self.run_bzr('merge -d target directive')
2520.4.110 by Aaron Bentley
Implement cherrypick support for merge directives
305
        self.failIfExists('target/a')
306
        self.failUnlessExists('target/b')
1551.19.22 by Aaron Bentley
Add warning when merge directives cause cherrypicks
307
        self.assertContainsRe(err, 'Performing cherrypick')
2520.4.111 by Aaron Bentley
Ensure that damaged preview patches produce a warning in merge
308
309
    def write_directive(self, filename, source, target, revision_id,
310
                        base_revision_id=None, mangle_patch=False):
311
        md = merge_directive.MergeDirective2.from_objects(
2520.4.112 by Aaron Bentley
Make cherry-pick merge directives possible
312
            source.repository, revision_id, 0, 0, target,
313
            base_revision_id=base_revision_id)
2520.4.111 by Aaron Bentley
Ensure that damaged preview patches produce a warning in merge
314
        if mangle_patch:
315
            md.patch = 'asdf\n'
316
        self.build_tree_contents([(filename, ''.join(md.to_lines()))])
317
318
    def test_directive_verify_warning(self):
319
        source = self.make_branch_and_tree('source')
320
        self.build_tree(['source/a'])
321
        source.add('a')
322
        source.commit('Added a', rev_id='rev1')
323
        target = self.make_branch_and_tree('target')
324
        target.commit('empty commit')
325
        self.write_directive('directive', source.branch, 'target', 'rev1')
326
        err = self.run_bzr('merge -d target directive')[1]
327
        self.assertNotContainsRe(err, 'Preview patch does not match changes')
2748.3.2 by Aaron Bentley
Fix revert, remove-tree, and various tests to use None for 'no files specified'
328
        target.revert()
2520.4.111 by Aaron Bentley
Ensure that damaged preview patches produce a warning in merge
329
        self.write_directive('directive', source.branch, 'target', 'rev1',
330
                             mangle_patch=True)
331
        err = self.run_bzr('merge -d target directive')[1]
2520.7.1 by Aaron Bentley
Reactivate patch verification
332
        self.assertContainsRe(err, 'Preview patch does not match changes')
1551.15.66 by Aaron Bentley
Improve behavior with revision ids
333
334
    def test_merge_arbitrary(self):
335
        target = self.make_branch_and_tree('target')
336
        target.commit('empty')
337
        # We need a revision that has no integer revno
338
        branch_a = target.bzrdir.sprout('branch_a').open_workingtree()
339
        self.build_tree(['branch_a/file1'])
340
        branch_a.add('file1')
341
        branch_a.commit('added file1', rev_id='rev2a')
342
        branch_b = target.bzrdir.sprout('branch_b').open_workingtree()
343
        self.build_tree(['branch_b/file2'])
344
        branch_b.add('file2')
345
        branch_b.commit('added file2', rev_id='rev2b')
346
        branch_b.merge_from_branch(branch_a.branch)
347
        self.failUnlessExists('branch_b/file1')
348
        branch_b.commit('merged branch_a', rev_id='rev3b')
349
350
        # It works if the revid has an interger revno
351
        self.run_bzr('merge -d target -r revid:rev2a branch_a')
352
        self.failUnlessExists('target/file1')
353
        self.failIfExists('target/file2')
2748.3.2 by Aaron Bentley
Fix revert, remove-tree, and various tests to use None for 'no files specified'
354
        target.revert()
1551.15.66 by Aaron Bentley
Improve behavior with revision ids
355
356
        # It should work if the revid has no integer revno
357
        self.run_bzr('merge -d target -r revid:rev2a branch_b')
358
        self.failUnlessExists('target/file1')
359
        self.failIfExists('target/file2')
2839.5.1 by Alexander Belchenko
add -c option to merge command
360
361
    def assertDirectoryContent(self, directory, entries, message=''):
2839.5.2 by Alexander Belchenko
tweaks suggested by Ian
362
        """Assert whether entries (file or directories) exist in a directory.
363
        
364
        It also checks that there are no extra entries.
2839.5.1 by Alexander Belchenko
add -c option to merge command
365
        """
2839.5.2 by Alexander Belchenko
tweaks suggested by Ian
366
        ondisk = os.listdir(directory)
2839.5.1 by Alexander Belchenko
add -c option to merge command
367
        if set(ondisk) == set(entries):
368
            return
369
        if message:
370
            message += '\n'
371
        raise AssertionError(
372
            '%s"%s" directory content is different:\na = %s\nb = %s\n'
2839.5.2 by Alexander Belchenko
tweaks suggested by Ian
373
            % (message, directory, sorted(entries), sorted(ondisk)))
2839.5.1 by Alexander Belchenko
add -c option to merge command
374
375
    def test_cherrypicking_merge(self):
376
        # make source branch
377
        source = self.make_branch_and_tree('source')
378
        for f in ('a', 'b', 'c', 'd'):
379
            self.build_tree(['source/'+f])
380
            source.add(f)
381
            source.commit('added '+f, rev_id='rev_'+f)
382
        # target branch
383
        target = source.bzrdir.sprout('target', 'rev_a').open_workingtree()
384
        self.assertDirectoryContent('target', ['.bzr', 'a'])
385
        # pick 1 revision
386
        self.run_bzr('merge -d target -r revid:rev_b..revid:rev_c source')
387
        self.assertDirectoryContent('target', ['.bzr', 'a', 'c'])
388
        target.revert()
389
        # pick 2 revisions
390
        self.run_bzr('merge -d target -r revid:rev_b..revid:rev_d source')
391
        self.assertDirectoryContent('target', ['.bzr', 'a', 'c', 'd'])
392
        target.revert()
393
        # pick 1 revision with option --changes
394
        self.run_bzr('merge -d target -c revid:rev_d source')
395
        self.assertDirectoryContent('target', ['.bzr', 'a', 'd'])
1551.19.10 by Aaron Bentley
Merge now warns when it encounters a criss-cross
396
397
    def test_merge_criss_cross(self):
398
        tree_a = self.make_branch_and_tree('a')
399
        tree_a.commit('', rev_id='rev1')
400
        tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
401
        tree_a.commit('', rev_id='rev2a')
402
        tree_b.commit('', rev_id='rev2b')
403
        tree_a.merge_from_branch(tree_b.branch)
404
        tree_b.merge_from_branch(tree_a.branch)
405
        tree_a.commit('', rev_id='rev3a')
406
        tree_b.commit('', rev_id='rev3b')
407
        graph = tree_a.branch.repository.get_graph(tree_b.branch.repository)
408
        out, err = self.run_bzr(['merge', '-d', 'a', 'b'])
409
        self.assertContainsRe(err, 'Warning: criss-cross merge encountered.')
3062.2.5 by Aaron Bentley
Merge bzr.dev
410
3062.2.4 by Aaron Bentley
Start supporting merge-with-base
411
    def test_weave_cherrypick(self):
412
        this_tree = self.make_branch_and_tree('this')
413
        self.build_tree_contents([('this/file', "a\n")])
414
        this_tree.add('file')
415
        this_tree.commit('rev1')
416
        other_tree = this_tree.bzrdir.sprout('other').open_workingtree()
417
        self.build_tree_contents([('other/file', "a\nb\n")])
418
        other_tree.commit('rev2b')
419
        self.build_tree_contents([('other/file', "c\na\nb\n")])
420
        other_tree.commit('rev3b')
3062.2.6 by Aaron Bentley
Get cherrypick-on-weave working
421
        self.run_bzr('merge --weave -d this other -r -2..-1')
3062.2.4 by Aaron Bentley
Start supporting merge-with-base
422
        self.assertFileEqual('c\na\n', 'this/file')