13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
# Author: Aaron Bentley <aaron.bentley@utoronto.ca>
44
44
tree.commit(message='setup')
47
def create_conflicting_branches(self):
48
"""Create two branches which have overlapping modifications.
50
:return: (tree, other_branch) Where merging other_branch causes a file
53
builder = self.make_branch_builder('branch')
54
builder.build_snapshot('rev1', None,
55
[('add', ('', 'root-id', 'directory', None)),
56
('add', ('fname', 'f-id', 'file', 'a\nb\nc\n'))])
57
builder.build_snapshot('rev2other', ['rev1'],
58
[('modify', ('f-id', 'a\nB\nD\n'))])
59
other = builder.get_branch().bzrdir.sprout('other').open_branch()
60
builder.build_snapshot('rev2this', ['rev1'],
61
[('modify', ('f-id', 'a\nB\nC\n'))])
62
tree = builder.get_branch().create_checkout('tree', lightweight=True)
65
47
def test_merge_reprocess(self):
66
48
d = BzrDir.create_standalone_workingtree('.')
108
90
self.assertTrue("Not a branch" in err)
109
91
self.run_bzr('merge -r revno:%d:./..revno:%d:../b'
110
92
%(ancestor,b.revno()))
111
self.assertEquals(a.get_parent_ids(),
93
self.assertEquals(a.get_parent_ids(),
112
94
[a.branch.last_revision(), b.last_revision()])
113
95
self.check_file_contents('goodbye', 'quux')
114
96
a_tree.revert(backups=False)
119
101
self.run_bzr('merge ../b -r last:1')
120
102
self.assertEqual([a_tip], a.get_parent_ids())
122
def test_merge_defaults_to_reprocess(self):
123
tree, other = self.create_conflicting_branches()
124
# The default merge algorithm should enable 'reprocess' because
125
# 'show-base' is not set
126
self.run_bzr('merge ../other', working_dir='tree',
128
self.assertEqualDiff('a\n'
134
'>>>>>>> MERGE-SOURCE\n',
135
tree.get_file_text('f-id'))
137
def test_merge_explicit_reprocess_show_base(self):
138
tree, other = self.create_conflicting_branches()
139
# Explicitly setting --reprocess, and --show-base is an error
140
self.run_bzr_error(['Cannot do conflict reduction and show base'],
141
'merge ../other --reprocess --show-base',
144
def test_merge_override_reprocess(self):
145
tree, other = self.create_conflicting_branches()
146
# Explicitly disable reprocess
147
self.run_bzr('merge ../other --no-reprocess', working_dir='tree',
149
self.assertEqualDiff('a\n'
156
'>>>>>>> MERGE-SOURCE\n',
157
tree.get_file_text('f-id'))
159
def test_merge_override_show_base(self):
160
tree, other = self.create_conflicting_branches()
161
# Setting '--show-base' will auto-disable '--reprocess'
162
self.run_bzr('merge ../other --show-base', working_dir='tree',
164
self.assertEqualDiff('a\n'
168
'||||||| BASE-REVISION\n'
174
'>>>>>>> MERGE-SOURCE\n',
175
tree.get_file_text('f-id'))
177
104
def test_merge_with_missing_file(self):
178
105
"""Merge handles missing file conflicts"""
179
106
self.build_tree_contents([
236
163
out = self.run_bzr('merge', retcode=3)
237
164
self.assertEquals(out,
238
165
('','bzr: ERROR: No location specified or remembered\n'))
240
# test uncommitted changes
166
# test implicit --remember when no parent set, this merge conflicts
241
167
self.build_tree(['d'])
243
169
self.run_bzr_error(['Working tree ".*" has uncommitted changes'],
246
# merge should now pass and implicitly remember merge location
171
self.assertEquals(abspath(branch_b.get_submit_branch()),
173
# test implicit --remember after resolving conflict
247
174
tree_b.commit('commit d')
248
out, err = self.run_bzr('merge ../branch_a')
175
out, err = self.run_bzr('merge')
250
177
base = urlutils.local_path_from_url(branch_a.base)
251
self.assertEndsWith(err, '+N b\nAll changes applied successfully.\n')
252
self.assertEquals(abspath(branch_b.get_submit_branch()),
254
# test implicit --remember when committing new file
255
self.build_tree(['e'])
257
tree_b.commit('commit e')
258
out, err = self.run_bzr('merge')
259
178
self.assertStartsWith(err,
260
179
'Merging from remembered submit location %s\n' % (base,))
180
self.assertEndsWith(err, '+N b\nAll changes applied successfully.\n')
181
self.assertEquals(abspath(branch_b.get_submit_branch()),
261
183
# re-open tree as external run_bzr modified it
262
184
tree_b = branch_b.bzrdir.open_workingtree()
263
185
tree_b.commit('merge branch_a')
375
297
def test_directive_cherrypick(self):
376
298
source = self.make_branch_and_tree('source')
377
source.commit("nothing")
378
# see https://bugs.edge.launchpad.net/bzr/+bug/409688 - trying to
379
# cherrypick from one branch into another unrelated branch with a
380
# different root id will give shape conflicts. as a workaround we
381
# make sure they share the same root id.
382
target = source.bzrdir.sprout('target').open_workingtree()
383
299
self.build_tree(['source/a'])
385
301
source.commit('Added a', rev_id='rev1')
386
302
self.build_tree(['source/b'])
388
304
source.commit('Added b', rev_id='rev2')
305
target = self.make_branch_and_tree('target')
389
306
target.commit('empty commit')
390
307
self.write_directive('directive', source.branch, 'target', 'rev2',
449
366
def assertDirectoryContent(self, directory, entries, message=''):
450
367
"""Assert whether entries (file or directories) exist in a directory.
452
369
It also checks that there are no extra entries.
454
371
ondisk = os.listdir(directory)
496
413
out, err = self.run_bzr(['merge', '-d', 'a', 'b'])
497
414
self.assertContainsRe(err, 'Warning: criss-cross merge encountered.')
499
def test_merge_force(self):
500
tree_a = self.make_branch_and_tree('a')
501
self.build_tree(['a/foo'])
503
tree_a.commit('add file')
504
tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
505
self.build_tree_contents([('a/foo', 'change 1')])
506
tree_a.commit('change file')
507
tree_b.merge_from_branch(tree_a.branch)
508
tree_a.commit('empty change to allow merge to run')
509
self.run_bzr(['merge', '../a', '--force'], working_dir='b')
511
416
def test_merge_from_submit(self):
512
417
tree_a = self.make_branch_and_tree('a')
513
418
tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
587
492
self.addCleanup(this_tree.unlock)
588
493
self.assertEqual([],
589
494
list(this_tree.iter_changes(this_tree.basis_tree())))
591
def test_merge_missing_second_revision_spec(self):
592
"""Merge uses branch basis when the second revision is unspecified."""
593
this = self.make_branch_and_tree('this')
595
other = self.make_branch_and_tree('other')
596
self.build_tree(['other/other_file'])
597
other.add('other_file')
598
other.commit('rev1b')
599
self.run_bzr('merge -d this other -r0..')
600
self.failUnlessExists('this/other_file')