~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)
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
73
        self.run_bzr('merge ../b -r last:1..last:1 --merge-type lca')
74
        a_tree.revert(backups=False)
2665.2.1 by Michael Hudson
test and fix for a NameError in merge --weave --show-base
75
        self.run_bzr_error(['Show-base is not supported for this merge type'],
76
                           'merge ../b -r last:1..last:1 --merge-type weave'
77
                           ' --show-base')
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..last:1 --reprocess')
2796.1.4 by Aaron Bentley
Fix up various test cases
80
        a_tree.revert(backups=False)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
81
        self.run_bzr('merge ../b -r last:1')
1551.6.16 by Aaron Bentley
Merge from bzr.dev
82
        self.check_file_contents('goodbye', 'quux')
83
        # Merging a branch pulls its revision into the tree
84
        b = Branch.open('../b')
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
85
        b_tip = b.last_revision()
86
        self.failUnless(a.branch.repository.has_revision(b_tip))
87
        self.assertEqual([a_tip, b_tip], a.get_parent_ids())
2796.1.4 by Aaron Bentley
Fix up various test cases
88
        a_tree.revert(backups=False)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
89
        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.
90
        self.assertTrue("Not a branch" in err)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
91
        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.
92
                    %(ancestor,b.revno()))
1551.8.25 by Aaron Bentley
Fix deprecated use of pending_merges
93
        self.assertEquals(a.get_parent_ids(), 
94
                          [a.branch.last_revision(), b.last_revision()])
1907.4.12 by Matthieu Moy
Made merge work with two revisions in different branches.
95
        self.check_file_contents('goodbye', 'quux')
2796.1.4 by Aaron Bentley
Fix up various test cases
96
        a_tree.revert(backups=False)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
97
        self.run_bzr('merge -r revno:%d:../b'%b.revno())
1551.8.25 by Aaron Bentley
Fix deprecated use of pending_merges
98
        self.assertEquals(a.get_parent_ids(),
99
                          [a.branch.last_revision(), b.last_revision()])
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
100
        a_tip = a.commit('merged')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
101
        self.run_bzr('merge ../b -r last:1')
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
102
        self.assertEqual([a_tip], a.get_parent_ids())
1551.6.16 by Aaron Bentley
Merge from bzr.dev
103
104
    def test_merge_with_missing_file(self):
105
        """Merge handles missing file conflicts"""
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
106
        self.build_tree_contents([
2738.3.4 by Daniel Watkins
Fixed tuple spacing.
107
            ('a/',),
108
            ('a/sub/',),
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
109
            ('a/sub/a.txt', 'hello\n'),
2738.3.3 by Daniel Watkins
Minor reformatting per abentley's mailing list comments.
110
            ('a/b.txt', 'hello\n'),
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
111
            ('a/sub/c.txt', 'hello\n')])
112
        a_tree = self.make_branch_and_tree('a')
113
        a_tree.add(['sub', 'b.txt', 'sub/c.txt', 'sub/a.txt'])
114
        a_tree.commit(message='added a')
115
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
116
        self.build_tree_contents([
117
            ('a/sub/a.txt', 'hello\nthere\n'),
2738.3.3 by Daniel Watkins
Minor reformatting per abentley's mailing list comments.
118
            ('a/b.txt', 'hello\nthere\n'),
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
119
            ('a/sub/c.txt', 'hello\nthere\n')])
120
        a_tree.commit(message='Added there')
121
        os.remove('a/sub/a.txt')
122
        os.remove('a/sub/c.txt')
123
        os.rmdir('a/sub')
124
        os.remove('a/b.txt')
125
        a_tree.commit(message='Removed a.txt')
126
        self.build_tree_contents([
127
            ('b/sub/a.txt', 'hello\nsomething\n'),
2738.3.3 by Daniel Watkins
Minor reformatting per abentley's mailing list comments.
128
            ('b/b.txt', 'hello\nsomething\n'),
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
129
            ('b/sub/c.txt', 'hello\nsomething\n')])
130
        b_tree.commit(message='Modified a.txt')
131
        os.chdir('b')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
132
        self.run_bzr('merge ../a/', retcode=1)
2738.3.2 by Daniel Watkins
Modified as per abentley's comments.
133
        self.failUnlessExists('sub/a.txt.THIS')
134
        self.failUnlessExists('sub/a.txt.BASE')
1551.6.16 by Aaron Bentley
Merge from bzr.dev
135
        os.chdir('../a')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
136
        self.run_bzr('merge ../b/', retcode=1)
2738.3.2 by Daniel Watkins
Modified as per abentley's comments.
137
        self.failUnlessExists('sub/a.txt.OTHER')
138
        self.failUnlessExists('sub/a.txt.BASE')
1551.6.16 by Aaron Bentley
Merge from bzr.dev
139
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
140
    def test_merge_remember(self):
1551.20.2 by Aaron Bentley
Merge prefers submit branch, but falls back to parent branch
141
        """Merge changes from one branch to another, test submit location."""
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
142
        tree_a = self.make_branch_and_tree('branch_a')
143
        branch_a = tree_a.branch
144
        self.build_tree(['branch_a/a'])
145
        tree_a.add('a')
146
        tree_a.commit('commit a')
147
        branch_b = branch_a.bzrdir.sprout('branch_b').open_branch()
148
        tree_b = branch_b.bzrdir.open_workingtree()
149
        branch_c = branch_a.bzrdir.sprout('branch_c').open_branch()
150
        tree_c = branch_c.bzrdir.open_workingtree()
151
        self.build_tree(['branch_a/b'])
152
        tree_a.add('b')
153
        tree_a.commit('commit b')
154
        self.build_tree(['branch_c/c'])
155
        tree_c.add('c')
156
        tree_c.commit('commit c')
1614.2.6 by Olaf Conradi
Add testcase for --remember when merge fails. It should still remember
157
        # reset parent
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
158
        parent = branch_b.get_parent()
159
        branch_b.set_parent(None)
160
        self.assertEqual(None, branch_b.get_parent())
1614.2.6 by Olaf Conradi
Add testcase for --remember when merge fails. It should still remember
161
        # test merge for failure without parent set
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
162
        os.chdir('branch_b')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
163
        out = self.run_bzr('merge', retcode=3)
1614.2.5 by Olaf Conradi
Added testcase for bzr merge --remember.
164
        self.assertEquals(out,
1685.1.59 by Martin Pool
[broken] Fix up & refactor display of remembered urls to unescape properly
165
                ('','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
166
        # test implicit --remember when no parent set, this merge conflicts
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
167
        self.build_tree(['d'])
168
        tree_b.add('d')
2796.2.14 by Aaron Bentley
Updates from review
169
        self.run_bzr_error(['Working tree ".*" has uncommitted changes'],
170
                           'merge ../branch_a')
1551.20.2 by Aaron Bentley
Merge prefers submit branch, but falls back to parent branch
171
        self.assertEquals(abspath(branch_b.get_submit_branch()),
172
                          abspath(parent))
1614.2.6 by Olaf Conradi
Add testcase for --remember when merge fails. It should still remember
173
        # test implicit --remember after resolving conflict
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
174
        tree_b.commit('commit d')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
175
        out, err = self.run_bzr('merge')
1685.1.38 by John Arbash Meinel
Fix merge_remember to use a complete path.
176
        
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
177
        base = urlutils.local_path_from_url(branch_a.base)
3249.2.2 by Ian Clatworthy
Fix merge redirection when remembered location used - tweak tests
178
        self.assertStartsWith(err,
1551.20.2 by Aaron Bentley
Merge prefers submit branch, but falls back to parent branch
179
                          'Merging from remembered location %s\n' % (base,))
3249.2.2 by Ian Clatworthy
Fix merge redirection when remembered location used - tweak tests
180
        self.assertEndsWith(err, '+N  b\nAll changes applied successfully.\n')
1551.20.2 by Aaron Bentley
Merge prefers submit branch, but falls back to parent branch
181
        self.assertEquals(abspath(branch_b.get_submit_branch()),
182
                          abspath(parent))
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
183
        # re-open tree as external run_bzr modified it
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
184
        tree_b = branch_b.bzrdir.open_workingtree()
185
        tree_b.commit('merge branch_a')
1614.2.6 by Olaf Conradi
Add testcase for --remember when merge fails. It should still remember
186
        # test explicit --remember
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
187
        out, err = self.run_bzr('merge ../branch_c --remember')
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
188
        self.assertEquals(out, '')
1551.11.11 by Aaron Bentley
Get tests passing
189
        self.assertEquals(err, '+N  c\nAll changes applied successfully.\n')
1551.20.2 by Aaron Bentley
Merge prefers submit branch, but falls back to parent branch
190
        self.assertEquals(abspath(branch_b.get_submit_branch()),
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
191
                          abspath(branch_c.bzrdir.root_transport.base))
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
192
        # re-open tree as external run_bzr modified it
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
193
        tree_b = branch_b.bzrdir.open_workingtree()
194
        tree_b.commit('merge branch_c')
1185.82.22 by Aaron Bentley
Start getting changeset merging under test
195
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
196
    def test_merge_bundle(self):
1185.82.33 by Aaron Bentley
Strengthen tests
197
        from bzrlib.testament import Testament
1185.82.22 by Aaron Bentley
Start getting changeset merging under test
198
        tree_a = self.make_branch_and_tree('branch_a')
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
199
        self.build_tree_contents([('branch_a/a', 'hello')])
1185.82.22 by Aaron Bentley
Start getting changeset merging under test
200
        tree_a.add('a')
201
        tree_a.commit('message')
202
203
        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.
204
        self.build_tree_contents([('branch_a/a', 'hey there')])
1185.82.23 by Aaron Bentley
Switch the fetcher
205
        tree_a.commit('message')
206
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
207
        self.build_tree_contents([('branch_b/a', 'goodbye')])
1185.82.22 by Aaron Bentley
Start getting changeset merging under test
208
        tree_b.commit('message')
209
        os.chdir('branch_b')
2654.3.1 by Aaron Bentley
Rename submit to send, make -o required, support -o- for stdout
210
        self.run_bzr('bundle ../branch_a -o ../bundle')
1185.82.26 by Aaron Bentley
Get changeset merges closer to working
211
        os.chdir('../branch_a')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
212
        self.run_bzr('merge ../bundle', retcode=1)
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
213
        testament_a = Testament.from_revision(tree_a.branch.repository,
214
                                              tree_b.get_parent_ids()[0])
1185.82.33 by Aaron Bentley
Strengthen tests
215
        testament_b = Testament.from_revision(tree_b.branch.repository,
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
216
                                              tree_b.get_parent_ids()[0])
1185.82.33 by Aaron Bentley
Strengthen tests
217
        self.assertEqualDiff(testament_a.as_text(),
218
                         testament_b.as_text())
1185.82.141 by Aaron Bentley
Ensure bzr works when you merge an already-merged bundle
219
        tree_a.set_conflicts(ConflictList())
220
        tree_a.commit('message')
221
        # 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
222
        output = self.run_bzr('merge ../bundle')[1]
1185.82.141 by Aaron Bentley
Ensure bzr works when you merge an already-merged bundle
223
        # but it does nothing
1852.10.3 by Robert Collins
Remove all uses of compare_trees and replace with Tree.changes_from throughout bzrlib.
224
        self.assertFalse(tree_a.changes_from(tree_a.basis_tree()).has_changed())
1185.82.142 by Aaron Bentley
Update for review comments
225
        self.assertEqual('Nothing to do.\n', output)
1910.1.1 by Aaron Bentley
Merge takes --uncommitted parameter
226
227
    def test_merge_uncommitted(self):
228
        """Check that merge --uncommitted behaves properly"""
229
        tree_a = self.make_branch_and_tree('a')
230
        self.build_tree(['a/file_1', 'a/file_2'])
231
        tree_a.add(['file_1', 'file_2'])
232
        tree_a.commit('commit 1')
233
        tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
234
        self.failUnlessExists('b/file_1')
235
        tree_a.rename_one('file_1', 'file_i')
236
        tree_a.commit('commit 2')
237
        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)
238
        ## os.chdir('b')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
239
        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)
240
        self.failUnlessExists('b/file_1')
241
        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'
242
        tree_b.revert()
2279.3.1 by mbp at sourcefrog
Add a -d option to push, pull, merge (ported from tags branch)
243
        self.run_bzr_error(('Cannot use --uncommitted and --revision',),
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
244
                           'merge /a --uncommitted -r1 -d b')
2149.2.1 by Jan Hudec
Option --pull for merge command.
245
3017.3.1 by Aaron Bentley
merge --uncommit can now specify single files (#136890)
246
    def test_merge_uncommitted_file(self):
247
        """It should be possible to merge changes from a single file."""
248
        tree_a = self.make_branch_and_tree('tree_a')
249
        tree_a.commit('initial commit')
250
        tree_a.bzrdir.sprout('tree_b')
251
        self.build_tree(['tree_a/file1', 'tree_a/file2'])
252
        tree_a.add(['file1', 'file2'])
253
        os.chdir('tree_b')
254
        self.run_bzr(['merge', '--uncommitted', '../tree_a/file1'])
255
        self.failUnlessExists('file1')
256
        self.failIfExists('file2')
257
2149.2.1 by Jan Hudec
Option --pull for merge command.
258
    def pullable_branch(self):
259
        tree_a = self.make_branch_and_tree('a')
260
        self.build_tree(['a/file'])
261
        tree_a.add(['file'])
262
        self.id1 = tree_a.commit('commit 1')
2664.12.1 by Daniel Watkins
tests.blackbox.test_merge now uses internals where appropriate.
263
2149.2.1 by Jan Hudec
Option --pull for merge command.
264
        tree_b = self.make_branch_and_tree('b')
265
        tree_b.pull(tree_a.branch)
266
        file('b/file', 'wb').write('foo')
267
        self.id2 = tree_b.commit('commit 2')
268
269
    def test_merge_pull(self):
270
        self.pullable_branch()
271
        os.chdir('a')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
272
        (out, err) = self.run_bzr('merge --pull ../b')
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
273
        self.assertContainsRe(out, 'Now on revision 2\\.')
2149.2.1 by Jan Hudec
Option --pull for merge command.
274
        tree_a = WorkingTree.open('.')
275
        self.assertEqual([self.id2], tree_a.get_parent_ids())
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
276
277
    def test_merge_kind_change(self):
278
        tree_a = self.make_branch_and_tree('tree_a')
279
        self.build_tree_contents([('tree_a/file', 'content_1')])
280
        tree_a.add('file', 'file-id')
281
        tree_a.commit('added file')
282
        tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
283
        os.unlink('tree_a/file')
284
        self.build_tree(['tree_a/file/'])
285
        tree_a.commit('changed file to directory')
286
        os.chdir('tree_b')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
287
        self.run_bzr('merge ../tree_a')
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
288
        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'
289
        tree_b.revert()
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
290
        self.assertEqual('file', file_kind('file'))
291
        self.build_tree_contents([('file', 'content_2')])
292
        tree_b.commit('content change')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
293
        self.run_bzr('merge ../tree_a', retcode=1)
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
294
        self.assertEqual(tree_b.conflicts(),
295
                         [ContentsConflict('file', file_id='file-id')])
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
296
297
    def test_directive_cherrypick(self):
298
        source = self.make_branch_and_tree('source')
299
        self.build_tree(['source/a'])
300
        source.add('a')
301
        source.commit('Added a', rev_id='rev1')
302
        self.build_tree(['source/b'])
303
        source.add('b')
304
        source.commit('Added b', rev_id='rev2')
305
        target = self.make_branch_and_tree('target')
306
        target.commit('empty commit')
2520.4.111 by Aaron Bentley
Ensure that damaged preview patches produce a warning in merge
307
        self.write_directive('directive', source.branch, 'target', 'rev2',
308
                             'rev1')
1551.19.22 by Aaron Bentley
Add warning when merge directives cause cherrypicks
309
        out, err = self.run_bzr('merge -d target directive')
2520.4.110 by Aaron Bentley
Implement cherrypick support for merge directives
310
        self.failIfExists('target/a')
311
        self.failUnlessExists('target/b')
1551.19.22 by Aaron Bentley
Add warning when merge directives cause cherrypicks
312
        self.assertContainsRe(err, 'Performing cherrypick')
2520.4.111 by Aaron Bentley
Ensure that damaged preview patches produce a warning in merge
313
314
    def write_directive(self, filename, source, target, revision_id,
315
                        base_revision_id=None, mangle_patch=False):
316
        md = merge_directive.MergeDirective2.from_objects(
2520.4.112 by Aaron Bentley
Make cherry-pick merge directives possible
317
            source.repository, revision_id, 0, 0, target,
318
            base_revision_id=base_revision_id)
2520.4.111 by Aaron Bentley
Ensure that damaged preview patches produce a warning in merge
319
        if mangle_patch:
320
            md.patch = 'asdf\n'
321
        self.build_tree_contents([(filename, ''.join(md.to_lines()))])
322
323
    def test_directive_verify_warning(self):
324
        source = self.make_branch_and_tree('source')
325
        self.build_tree(['source/a'])
326
        source.add('a')
327
        source.commit('Added a', rev_id='rev1')
328
        target = self.make_branch_and_tree('target')
329
        target.commit('empty commit')
330
        self.write_directive('directive', source.branch, 'target', 'rev1')
331
        err = self.run_bzr('merge -d target directive')[1]
332
        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'
333
        target.revert()
2520.4.111 by Aaron Bentley
Ensure that damaged preview patches produce a warning in merge
334
        self.write_directive('directive', source.branch, 'target', 'rev1',
335
                             mangle_patch=True)
336
        err = self.run_bzr('merge -d target directive')[1]
2520.7.1 by Aaron Bentley
Reactivate patch verification
337
        self.assertContainsRe(err, 'Preview patch does not match changes')
1551.15.66 by Aaron Bentley
Improve behavior with revision ids
338
339
    def test_merge_arbitrary(self):
340
        target = self.make_branch_and_tree('target')
341
        target.commit('empty')
342
        # We need a revision that has no integer revno
343
        branch_a = target.bzrdir.sprout('branch_a').open_workingtree()
344
        self.build_tree(['branch_a/file1'])
345
        branch_a.add('file1')
346
        branch_a.commit('added file1', rev_id='rev2a')
347
        branch_b = target.bzrdir.sprout('branch_b').open_workingtree()
348
        self.build_tree(['branch_b/file2'])
349
        branch_b.add('file2')
350
        branch_b.commit('added file2', rev_id='rev2b')
351
        branch_b.merge_from_branch(branch_a.branch)
352
        self.failUnlessExists('branch_b/file1')
353
        branch_b.commit('merged branch_a', rev_id='rev3b')
354
355
        # It works if the revid has an interger revno
356
        self.run_bzr('merge -d target -r revid:rev2a branch_a')
357
        self.failUnlessExists('target/file1')
358
        self.failIfExists('target/file2')
2748.3.2 by Aaron Bentley
Fix revert, remove-tree, and various tests to use None for 'no files specified'
359
        target.revert()
1551.15.66 by Aaron Bentley
Improve behavior with revision ids
360
361
        # It should work if the revid has no integer revno
362
        self.run_bzr('merge -d target -r revid:rev2a branch_b')
363
        self.failUnlessExists('target/file1')
364
        self.failIfExists('target/file2')
2839.5.1 by Alexander Belchenko
add -c option to merge command
365
366
    def assertDirectoryContent(self, directory, entries, message=''):
2839.5.2 by Alexander Belchenko
tweaks suggested by Ian
367
        """Assert whether entries (file or directories) exist in a directory.
368
        
369
        It also checks that there are no extra entries.
2839.5.1 by Alexander Belchenko
add -c option to merge command
370
        """
2839.5.2 by Alexander Belchenko
tweaks suggested by Ian
371
        ondisk = os.listdir(directory)
2839.5.1 by Alexander Belchenko
add -c option to merge command
372
        if set(ondisk) == set(entries):
373
            return
374
        if message:
375
            message += '\n'
376
        raise AssertionError(
377
            '%s"%s" directory content is different:\na = %s\nb = %s\n'
2839.5.2 by Alexander Belchenko
tweaks suggested by Ian
378
            % (message, directory, sorted(entries), sorted(ondisk)))
2839.5.1 by Alexander Belchenko
add -c option to merge command
379
380
    def test_cherrypicking_merge(self):
381
        # make source branch
382
        source = self.make_branch_and_tree('source')
383
        for f in ('a', 'b', 'c', 'd'):
384
            self.build_tree(['source/'+f])
385
            source.add(f)
386
            source.commit('added '+f, rev_id='rev_'+f)
387
        # target branch
388
        target = source.bzrdir.sprout('target', 'rev_a').open_workingtree()
389
        self.assertDirectoryContent('target', ['.bzr', 'a'])
390
        # pick 1 revision
391
        self.run_bzr('merge -d target -r revid:rev_b..revid:rev_c source')
392
        self.assertDirectoryContent('target', ['.bzr', 'a', 'c'])
393
        target.revert()
394
        # pick 2 revisions
395
        self.run_bzr('merge -d target -r revid:rev_b..revid:rev_d source')
396
        self.assertDirectoryContent('target', ['.bzr', 'a', 'c', 'd'])
397
        target.revert()
398
        # pick 1 revision with option --changes
399
        self.run_bzr('merge -d target -c revid:rev_d source')
400
        self.assertDirectoryContent('target', ['.bzr', 'a', 'd'])
1551.19.10 by Aaron Bentley
Merge now warns when it encounters a criss-cross
401
402
    def test_merge_criss_cross(self):
403
        tree_a = self.make_branch_and_tree('a')
404
        tree_a.commit('', rev_id='rev1')
405
        tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
406
        tree_a.commit('', rev_id='rev2a')
407
        tree_b.commit('', rev_id='rev2b')
408
        tree_a.merge_from_branch(tree_b.branch)
409
        tree_b.merge_from_branch(tree_a.branch)
410
        tree_a.commit('', rev_id='rev3a')
411
        tree_b.commit('', rev_id='rev3b')
412
        graph = tree_a.branch.repository.get_graph(tree_b.branch.repository)
413
        out, err = self.run_bzr(['merge', '-d', 'a', 'b'])
414
        self.assertContainsRe(err, 'Warning: criss-cross merge encountered.')
3062.2.5 by Aaron Bentley
Merge bzr.dev
415
1551.20.2 by Aaron Bentley
Merge prefers submit branch, but falls back to parent branch
416
    def test_merge_from_submit(self):
417
        tree_a = self.make_branch_and_tree('a')
418
        tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
419
        tree_c = tree_a.bzrdir.sprout('c').open_workingtree()
420
        out, err = self.run_bzr(['merge', '-d', 'c'])
3249.2.2 by Ian Clatworthy
Fix merge redirection when remembered location used - tweak tests
421
        self.assertContainsRe(err, 'Merging from remembered location .*a\/')
1551.20.2 by Aaron Bentley
Merge prefers submit branch, but falls back to parent branch
422
        tree_c.branch.set_submit_branch(tree_b.bzrdir.root_transport.base)
423
        out, err = self.run_bzr(['merge', '-d', 'c'])
3249.2.2 by Ian Clatworthy
Fix merge redirection when remembered location used - tweak tests
424
        self.assertContainsRe(err, 'Merging from remembered location .*b\/')
1551.20.2 by Aaron Bentley
Merge prefers submit branch, but falls back to parent branch
425
426
    def test_remember_sets_submit(self):
427
        tree_a = self.make_branch_and_tree('a')
428
        tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
429
        self.assertIs(tree_b.branch.get_submit_branch(), None)
430
431
        # Remember should not happen if using default from parent
432
        out, err = self.run_bzr(['merge', '-d', 'b'])
433
        self.assertIs(tree_b.branch.get_submit_branch(), None)
434
435
        # Remember should happen if user supplies location
436
        out, err = self.run_bzr(['merge', '-d', 'b', 'a'])
437
        self.assertEqual(tree_b.branch.get_submit_branch(),
438
                         tree_a.bzrdir.root_transport.base)
1551.19.25 by Aaron Bentley
Merge bzr.dev
439
3062.2.4 by Aaron Bentley
Start supporting merge-with-base
440
    def test_weave_cherrypick(self):
441
        this_tree = self.make_branch_and_tree('this')
442
        self.build_tree_contents([('this/file', "a\n")])
443
        this_tree.add('file')
444
        this_tree.commit('rev1')
445
        other_tree = this_tree.bzrdir.sprout('other').open_workingtree()
446
        self.build_tree_contents([('other/file', "a\nb\n")])
447
        other_tree.commit('rev2b')
448
        self.build_tree_contents([('other/file', "c\na\nb\n")])
449
        other_tree.commit('rev3b')
3062.2.6 by Aaron Bentley
Get cherrypick-on-weave working
450
        self.run_bzr('merge --weave -d this other -r -2..-1')
3062.2.4 by Aaron Bentley
Start supporting merge-with-base
451
        self.assertFileEqual('c\na\n', 'this/file')
3008.1.24 by Aaron Bentley
Add merge --preview to show diff
452
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
453
    def test_lca_merge_criss_cross(self):
454
        tree_a = self.make_branch_and_tree('a')
455
        self.build_tree_contents([('a/file', 'base-contents\n')])
456
        tree_a.add('file')
457
        tree_a.commit('', rev_id='rev1')
458
        tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
459
        self.build_tree_contents([('a/file',
460
                                   'base-contents\nthis-contents\n')])
461
        tree_a.commit('', rev_id='rev2a')
462
        self.build_tree_contents([('b/file',
463
                                   'base-contents\nother-contents\n')])
464
        tree_b.commit('', rev_id='rev2b')
465
        tree_a.merge_from_branch(tree_b.branch)
466
        self.build_tree_contents([('a/file',
467
                                   'base-contents\nthis-contents\n')])
468
        tree_a.set_conflicts(ConflictList())
469
        tree_b.merge_from_branch(tree_a.branch)
470
        self.build_tree_contents([('b/file',
471
                                   'base-contents\nother-contents\n')])
472
        tree_b.set_conflicts(ConflictList())
473
        tree_a.commit('', rev_id='rev3a')
474
        tree_b.commit('', rev_id='rev3b')
475
        out, err = self.run_bzr(['merge', '-d', 'a', 'b', '--lca'], retcode=1)
476
        self.assertFileEqual('base-contents\n<<<<<<< TREE\nthis-contents\n'
3144.3.2 by Aaron Bentley
Get conflict handling working
477
                             '=======\nother-contents\n>>>>>>> MERGE-SOURCE\n',
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
478
                             'a/file')
3008.1.27 by Aaron Bentley
Merge bzr.dev
479
3008.1.24 by Aaron Bentley
Add merge --preview to show diff
480
    def test_merge_preview(self):
481
        this_tree = self.make_branch_and_tree('this')
482
        this_tree.commit('rev1')
483
        other_tree = this_tree.bzrdir.sprout('other').open_workingtree()
484
        self.build_tree_contents([('other/file', 'new line')])
485
        other_tree.add('file')
486
        other_tree.commit('rev2a')
487
        this_tree.commit('rev2b')
488
        out, err = self.run_bzr(['merge', '-d', 'this', 'other', '--preview'])
489
        self.assertContainsRe(out, '\+new line')
490
        self.assertNotContainsRe(err, '\+N  file\n')
491
        this_tree.lock_read()
492
        self.addCleanup(this_tree.unlock)
493
        self.assertEqual([],
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
494
                         list(this_tree.iter_changes(this_tree.basis_tree())))