1
# Copyright (C) 2005, 2006 Canonical Ltd
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.
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.
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
6
26
from bzrlib.add import smart_add_tree
7
27
from bzrlib.builtins import merge
8
28
from bzrlib.conflicts import ContentsConflict, TextConflict, PathConflict
10
30
WorkingTreeNotRevision, BzrCommandError, NoDiff3)
11
31
import bzrlib.inventory as inventory
12
32
from bzrlib.merge import Merge3Merger, Diff3Merger, WeaveMerger
13
from bzrlib.osutils import (file_kind, getcwd, mkdtemp, pathjoin, rename, rmtree,
33
from bzrlib.osutils import (file_kind, getcwd, pathjoin, rename,
16
36
from bzrlib.transform import TreeTransform
17
37
from bzrlib.tests import TestCaseWithTransport, TestCase, TestSkipped
176
206
def test_change_name(self):
177
207
"""Test renames"""
178
208
builder = MergeBuilder(getcwd())
179
builder.add_file("1", "TREE_ROOT", "name1", "hello1", True)
209
builder.add_file("1", builder.tree_root, "name1", "hello1", True)
180
210
builder.change_name("1", other="name2")
181
builder.add_file("2", "TREE_ROOT", "name3", "hello2", True)
211
builder.add_file("2", builder.tree_root, "name3", "hello2", True)
182
212
builder.change_name("2", base="name4")
183
builder.add_file("3", "TREE_ROOT", "name5", "hello3", True)
213
builder.add_file("3", builder.tree_root, "name5", "hello3", True)
184
214
builder.change_name("3", this="name6")
186
216
builder.cleanup()
187
217
builder = MergeBuilder(getcwd())
188
builder.add_file("1", "TREE_ROOT", "name1", "hello1", False)
218
builder.add_file("1", builder.tree_root, "name1", "hello1", False)
189
219
builder.change_name("1", other="name2", this="name3")
190
220
conflicts = builder.merge()
191
221
self.assertEqual(conflicts, [PathConflict('name3', 'name2', '1')])
194
224
def test_merge_one(self):
195
225
builder = MergeBuilder(getcwd())
196
builder.add_file("1", "TREE_ROOT", "name1", "hello1", True)
226
builder.add_file("1", builder.tree_root, "name1", "hello1", True)
197
227
builder.change_contents("1", other="text4")
198
builder.add_file("2", "TREE_ROOT", "name2", "hello1", True)
228
builder.add_file("2", builder.tree_root, "name2", "hello1", True)
199
229
builder.change_contents("2", other="text4")
200
230
builder.merge(interesting_ids=["1"])
201
231
self.assertEqual(builder.this.get_file("1").read(), "text4" )
205
235
def test_file_moves(self):
207
237
builder = MergeBuilder(getcwd())
208
builder.add_dir("1", "TREE_ROOT", "dir1")
209
builder.add_dir("2", "TREE_ROOT", "dir2")
238
builder.add_dir("1", builder.tree_root, "dir1")
239
builder.add_dir("2", builder.tree_root, "dir2")
210
240
builder.add_file("3", "1", "file1", "hello1", True)
211
241
builder.add_file("4", "1", "file2", "hello2", True)
212
242
builder.add_file("5", "1", "file3", "hello3", True)
217
247
builder.cleanup()
219
249
builder = MergeBuilder(getcwd())
220
builder.add_dir("1", "TREE_ROOT", "dir1")
221
builder.add_dir("2", "TREE_ROOT", "dir2")
222
builder.add_dir("3", "TREE_ROOT", "dir3")
250
builder.add_dir("1", builder.tree_root, "dir1")
251
builder.add_dir("2", builder.tree_root, "dir2")
252
builder.add_dir("3", builder.tree_root, "dir3")
223
253
builder.add_file("4", "1", "file1", "hello1", False)
224
254
builder.change_parent("4", other="2", this="3")
225
255
conflicts = builder.merge()
274
307
def contents_test_success(self, merge_factory):
275
308
builder = MergeBuilder(getcwd())
276
builder.add_file("1", "TREE_ROOT", "name1", "text1", True)
309
builder.add_file("1", builder.tree_root, "name1", "text1", True)
277
310
builder.change_contents("1", other="text4")
278
builder.add_file("2", "TREE_ROOT", "name3", "text2", False)
311
builder.add_file("2", builder.tree_root, "name3", "text2", False)
279
312
builder.change_contents("2", base="text5")
280
builder.add_file("3", "TREE_ROOT", "name5", "text3", True)
281
builder.add_file("4", "TREE_ROOT", "name6", "text4", True)
313
builder.add_file("3", builder.tree_root, "name5", "text3", True)
314
builder.add_file("4", builder.tree_root, "name6", "text4", True)
282
315
builder.remove_file("4", base=True)
283
builder.add_file("5", "TREE_ROOT", "name7", "a\nb\nc\nd\ne\nf\n", True)
316
builder.add_file("5", builder.tree_root, "name7", "a\nb\nc\nd\ne\nf\n",
284
318
builder.change_contents("5", other="a\nz\nc\nd\ne\nf\n",
285
319
this="a\nb\nc\nd\ne\nz\n")
286
builder.merge(merge_factory)
287
self.assertEqual(builder.this.get_file("1").read(), "text4" )
288
self.assertEqual(builder.this.get_file("2").read(), "text2" )
289
self.assertEqual(builder.this.get_file("5").read(),
290
"a\nz\nc\nd\ne\nz\n")
291
self.assertIs(builder.this.is_executable("1"), True)
292
self.assertIs(builder.this.is_executable("2"), False)
293
self.assertIs(builder.this.is_executable("3"), True)
320
conflicts = builder.merge(merge_factory)
322
self.assertEqual([], conflicts)
323
self.assertEqual("text4", builder.this.get_file("1").read())
324
self.assertEqual("text2", builder.this.get_file("2").read())
325
self.assertEqual("a\nz\nc\nd\ne\nz\n",
326
builder.this.get_file("5").read())
327
self.assertTrue(builder.this.is_executable("1"))
328
self.assertFalse(builder.this.is_executable("2"))
329
self.assertTrue(builder.this.is_executable("3"))
296
335
def contents_test_conflicts(self, merge_factory):
297
336
builder = MergeBuilder(getcwd())
298
builder.add_file("1", "TREE_ROOT", "name1", "text1", True)
337
builder.add_file("1", builder.tree_root, "name1", "text1", True)
299
338
builder.change_contents("1", other="text4", this="text3")
300
builder.add_file("2", "TREE_ROOT", "name2", "text1", True)
339
builder.add_file("2", builder.tree_root, "name2", "text1", True)
301
340
builder.change_contents("2", other="\x00", this="text3")
302
builder.add_file("3", "TREE_ROOT", "name3", "text5", False)
341
builder.add_file("3", builder.tree_root, "name3", "text5", False)
303
342
builder.change_perms("3", this=True)
304
343
builder.change_contents('3', this='moretext')
305
344
builder.remove_file('3', other=True)
323
362
def test_symlink_merge(self):
324
363
if sys.platform != "win32":
325
364
builder = MergeBuilder(getcwd())
326
builder.add_symlink("1", "TREE_ROOT", "name1", "target1")
327
builder.add_symlink("2", "TREE_ROOT", "name2", "target1")
328
builder.add_symlink("3", "TREE_ROOT", "name3", "target1")
365
builder.add_symlink("1", builder.tree_root, "name1", "target1")
366
builder.add_symlink("2", builder.tree_root, "name2", "target1")
367
builder.add_symlink("3", builder.tree_root, "name3", "target1")
329
368
builder.change_target("1", this="target2")
330
369
builder.change_target("2", base="target2")
331
370
builder.change_target("3", other="target2")
338
377
def test_no_passive_add(self):
339
378
builder = MergeBuilder(getcwd())
340
builder.add_file("1", "TREE_ROOT", "name1", "text1", True)
379
builder.add_file("1", builder.tree_root, "name1", "text1", True)
341
380
builder.remove_file("1", this=True)
343
382
builder.cleanup()
345
384
def test_perms_merge(self):
346
385
builder = MergeBuilder(getcwd())
347
builder.add_file("1", "TREE_ROOT", "name1", "text1", True)
386
builder.add_file("1", builder.tree_root, "name1", "text1", True)
348
387
builder.change_perms("1", other=False)
349
builder.add_file("2", "TREE_ROOT", "name2", "text2", True)
388
builder.add_file("2", builder.tree_root, "name2", "text2", True)
350
389
builder.change_perms("2", base=False)
351
builder.add_file("3", "TREE_ROOT", "name3", "text3", True)
390
builder.add_file("3", builder.tree_root, "name3", "text3", True)
352
391
builder.change_perms("3", this=False)
353
builder.add_file('4', 'TREE_ROOT', 'name4', 'text4', False)
392
builder.add_file('4', builder.tree_root, 'name4', 'text4', False)
354
393
builder.change_perms('4', this=True)
355
394
builder.remove_file('4', base=True)
362
401
def test_new_suffix(self):
363
402
builder = MergeBuilder(getcwd())
364
builder.add_file("1", "TREE_ROOT", "name1", "text1", True)
403
builder.add_file("1", builder.tree_root, "name1", "text1", True)
365
404
builder.change_contents("1", other="text3")
366
builder.add_file("2", "TREE_ROOT", "name1.new", "text2", True)
405
builder.add_file("2", builder.tree_root, "name1.new", "text2", True)
368
407
os.lstat(builder.this.id2abspath("2"))
369
408
builder.cleanup()
371
410
def test_spurious_conflict(self):
372
411
builder = MergeBuilder(getcwd())
373
builder.add_file("1", "TREE_ROOT", "name1", "text1", False)
412
builder.add_file("1", builder.tree_root, "name1", "text1", False)
374
413
builder.remove_file("1", other=True)
375
builder.add_file("2", "TREE_ROOT", "name1", "text1", False, this=False,
414
builder.add_file("2", builder.tree_root, "name1", "text1", False,
415
this=False, base=False)
377
416
conflicts = builder.merge()
378
417
self.assertEqual(conflicts, [])
379
418
builder.cleanup()
513
552
a_wt = self.make_branch_and_tree('a')
514
553
file('a/un','wb').write('UN')
515
554
file('a/deux','wb').write('DEUX')
517
a_wt.add('deux', 'deux')
555
a_wt.add('un', 'un-id')
556
a_wt.add('deux', 'deux-id')
518
557
a_wt.commit('r0', rev_id='r0')
519
self.run_bzr('branch', 'a', 'b')
558
self.run_bzr(['branch', 'a', 'b'])
520
559
b_wt = WorkingTree.open('b')
521
560
b_wt.rename_one('un','tmp')
522
561
b_wt.rename_one('deux','un')