161
125
self.assertEqual(conflicts.ConflictList([]), tree.conflicts())
164
class TestConflictStanzas(tests.TestCase):
128
class TestPerConflict(tests.TestCase):
130
scenarios = scenarios.multiply_scenarios(vary_by_conflicts())
132
def test_stringification(self):
133
text = unicode(self.conflict)
134
self.assertContainsString(text, self.conflict.path)
135
self.assertContainsString(text.lower(), "conflict")
136
self.assertContainsString(repr(self.conflict),
137
self.conflict.__class__.__name__)
166
139
def test_stanza_roundtrip(self):
167
# write and read our example stanza.
168
stanza_iter = example_conflicts.to_stanzas()
169
processed = conflicts.ConflictList.from_stanzas(stanza_iter)
170
for o, p in zip(processed, example_conflicts):
171
self.assertEqual(o, p)
173
self.assertIsInstance(o.path, unicode)
175
if o.file_id is not None:
176
self.assertIsInstance(o.file_id, str)
178
conflict_path = getattr(o, 'conflict_path', None)
179
if conflict_path is not None:
180
self.assertIsInstance(conflict_path, unicode)
182
conflict_file_id = getattr(o, 'conflict_file_id', None)
183
if conflict_file_id is not None:
184
self.assertIsInstance(conflict_file_id, str)
141
o = conflicts.Conflict.factory(**p.as_stanza().as_dict())
142
self.assertEqual(o, p)
144
self.assertIsInstance(o.path, unicode)
146
if o.file_id is not None:
147
self.assertIsInstance(o.file_id, str)
149
conflict_path = getattr(o, 'conflict_path', None)
150
if conflict_path is not None:
151
self.assertIsInstance(conflict_path, unicode)
153
conflict_file_id = getattr(o, 'conflict_file_id', None)
154
if conflict_file_id is not None:
155
self.assertIsInstance(conflict_file_id, str)
186
157
def test_stanzification(self):
187
for stanza in example_conflicts.to_stanzas():
188
if 'file_id' in stanza:
189
# In Stanza form, the file_id has to be unicode.
190
self.assertStartsWith(stanza['file_id'], u'\xeed')
191
self.assertStartsWith(stanza['path'], u'p\xe5th')
192
if 'conflict_path' in stanza:
193
self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
194
if 'conflict_file_id' in stanza:
195
self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')
158
stanza = self.conflict.as_stanza()
159
if 'file_id' in stanza:
160
# In Stanza form, the file_id has to be unicode.
161
self.assertStartsWith(stanza['file_id'], u'\xeed')
162
self.assertStartsWith(stanza['path'], u'p\xe5th')
163
if 'conflict_path' in stanza:
164
self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
165
if 'conflict_file_id' in stanza:
166
self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')
169
class TestConflictList(tests.TestCase):
171
def test_stanzas_roundtrip(self):
172
stanzas_iter = example_conflicts.to_stanzas()
173
processed = conflicts.ConflictList.from_stanzas(stanzas_iter)
174
self.assertEqual(example_conflicts, processed)
176
def test_stringification(self):
177
for text, o in zip(example_conflicts.to_strings(), example_conflicts):
178
self.assertEqual(text, unicode(o))
198
181
# FIXME: The shell-like tests should be converted to real whitebox tests... or
320
325
def _get_check(self, name):
321
326
return getattr(self, 'check_%s' % name)
323
def do_nothing(self):
324
return (None, None, [])
326
def do_create_file(self):
327
return ('file', 'file-id',
328
[('add', ('file', 'file-id', 'file', 'trunk content\n'))])
330
def do_create_file_a(self):
331
return ('file', 'file-a-id',
332
[('add', ('file', 'file-a-id', 'file', 'file a content\n'))])
334
def check_file_content_a(self):
335
self.assertFileEqual('file a content\n', 'branch/file')
337
def do_create_file_b(self):
338
return ('file', 'file-b-id',
339
[('add', ('file', 'file-b-id', 'file', 'file b content\n'))])
341
def check_file_content_b(self):
342
self.assertFileEqual('file b content\n', 'branch/file')
344
def do_create_dir(self):
345
return ('dir', 'dir-id', [('add', ('dir', 'dir-id', 'directory', ''))])
347
def do_modify_file(self):
348
return ('file', 'file-id',
349
[('modify', ('file-id', 'trunk content\nmore content\n'))])
351
def check_file_has_more_content(self):
352
self.assertFileEqual('trunk content\nmore content\n', 'branch/file')
354
def do_delete_file(self):
355
return ('file', 'file-id', [('unversion', 'file-id')])
357
def check_file_doesnt_exist(self):
358
self.failIfExists('branch/file')
360
def do_rename_file(self):
361
return ('new-file', 'file-id', [('rename', ('file', 'new-file'))])
363
def check_file_renamed(self):
364
self.failIfExists('branch/file')
365
self.failUnlessExists('branch/new-file')
367
def do_rename_file2(self):
368
return ('new-file2', 'file-id', [('rename', ('file', 'new-file2'))])
370
def check_file_renamed2(self):
371
self.failIfExists('branch/file')
372
self.failUnlessExists('branch/new-file2')
374
def do_rename_dir(self):
375
return ('new-dir', 'dir-id', [('rename', ('dir', 'new-dir'))])
377
def check_dir_renamed(self):
378
self.failIfExists('branch/dir')
379
self.failUnlessExists('branch/new-dir')
381
def do_rename_dir2(self):
382
return ('new-dir2', 'dir-id', [('rename', ('dir', 'new-dir2'))])
384
def check_dir_renamed2(self):
385
self.failIfExists('branch/dir')
386
self.failUnlessExists('branch/new-dir2')
388
def do_delete_dir(self):
389
return ('<deleted>', 'dir-id', [('unversion', 'dir-id')])
391
def check_dir_doesnt_exist(self):
392
self.failIfExists('branch/dir')
394
328
def _merge_other_into_this(self):
395
329
b = self.builder.get_branch()
396
330
wt = b.bzrdir.sprout('branch').open_workingtree()
418
352
wt = self._merge_other_into_this()
419
353
self.assertConflict(wt)
420
354
self.check_resolved(wt, 'take_this')
421
check_this = self._get_check(self._check_this)
355
check_this = self._get_check(self._this['check'])
424
358
def test_resolve_taking_other(self):
425
359
wt = self._merge_other_into_this()
426
360
self.assertConflict(wt)
427
361
self.check_resolved(wt, 'take_other')
428
check_other = self._get_check(self._check_other)
362
check_other = self._get_check(self._other['check'])
366
class TestResolveTextConflicts(TestParametrizedResolveConflicts):
368
_conflict_type = conflicts.TextConflict
370
# Set by the scenarios
371
# path and file-id for the file involved in the conflict
375
scenarios = mirror_scenarios(
377
# File modified on both sides
378
(dict(_base_actions='create_file',
379
_path='file', _file_id='file-id'),
381
dict(actions='modify_file_A', check='file_has_content_A')),
383
dict(actions='modify_file_B', check='file_has_content_B')),),
384
# File modified on both sides in dir
385
(dict(_base_actions='create_file_in_dir',
386
_path='dir/file', _file_id='file-id'),
387
('filed_modified_A_in_dir',
388
dict(actions='modify_file_A',
389
check='file_in_dir_has_content_A')),
391
dict(actions='modify_file_B',
392
check='file_in_dir_has_content_B')),),
395
def do_create_file(self, path='file'):
396
return [('add', (path, 'file-id', 'file', 'trunk content\n'))]
398
def do_modify_file_A(self):
399
return [('modify', ('file-id', 'trunk content\nfeature A\n'))]
401
def do_modify_file_B(self):
402
return [('modify', ('file-id', 'trunk content\nfeature B\n'))]
404
def check_file_has_content_A(self, path='file'):
405
self.assertFileEqual('trunk content\nfeature A\n',
406
osutils.pathjoin('branch', path))
408
def check_file_has_content_B(self, path='file'):
409
self.assertFileEqual('trunk content\nfeature B\n',
410
osutils.pathjoin('branch', path))
412
def do_create_file_in_dir(self):
413
return [('add', ('dir', 'dir-id', 'directory', '')),
414
] + self.do_create_file('dir/file')
416
def check_file_in_dir_has_content_A(self):
417
self.check_file_has_content_A('dir/file')
419
def check_file_in_dir_has_content_B(self):
420
self.check_file_has_content_B('dir/file')
422
def _get_resolve_path_arg(self, wt, action):
425
def assertTextConflict(self, wt, c):
426
self.assertEqual(self._file_id, c.file_id)
427
self.assertEqual(self._path, c.path)
428
_assert_conflict = assertTextConflict
432
431
class TestResolveContentsConflict(TestParametrizedResolveConflicts):
434
_conflict_type = conflicts.ContentsConflict,
436
def scenarios(klass):
438
(('file_modified', dict(actions='modify_file',
439
check='file_has_more_content')),
440
('file_deleted', dict(actions='delete_file',
441
check='file_doesnt_exist')),
442
dict(_actions_base='create_file', _item_path='file')),
444
return klass.mirror_scenarios(base_scenarios)
433
_conflict_type = conflicts.ContentsConflict
435
# Set by the scenarios
436
# path and file-id for the file involved in the conflict
440
scenarios = mirror_scenarios(
442
# File modified/deleted
443
(dict(_base_actions='create_file',
444
_path='file', _file_id='file-id'),
446
dict(actions='modify_file', check='file_has_more_content')),
448
dict(actions='delete_file', check='file_doesnt_exist')),),
449
# File renamed-modified/deleted
450
(dict(_base_actions='create_file',
451
_path='new-file', _file_id='file-id'),
452
('file_renamed_and_modified',
453
dict(actions='modify_and_rename_file',
454
check='file_renamed_and_more_content')),
456
dict(actions='delete_file', check='file_doesnt_exist')),),
457
# File modified/deleted in dir
458
(dict(_base_actions='create_file_in_dir',
459
_path='dir/file', _file_id='file-id'),
460
('file_modified_in_dir',
461
dict(actions='modify_file_in_dir',
462
check='file_in_dir_has_more_content')),
463
('file_deleted_in_dir',
464
dict(actions='delete_file',
465
check='file_in_dir_doesnt_exist')),),
468
def do_create_file(self):
469
return [('add', ('file', 'file-id', 'file', 'trunk content\n'))]
471
def do_modify_file(self):
472
return [('modify', ('file-id', 'trunk content\nmore content\n'))]
474
def do_modify_and_rename_file(self):
475
return [('modify', ('file-id', 'trunk content\nmore content\n')),
476
('rename', ('file', 'new-file'))]
478
def check_file_has_more_content(self):
479
self.assertFileEqual('trunk content\nmore content\n', 'branch/file')
481
def check_file_renamed_and_more_content(self):
482
self.assertFileEqual('trunk content\nmore content\n', 'branch/new-file')
484
def do_delete_file(self):
485
return [('unversion', 'file-id')]
487
def check_file_doesnt_exist(self):
488
self.assertPathDoesNotExist('branch/file')
490
def do_create_file_in_dir(self):
491
return [('add', ('dir', 'dir-id', 'directory', '')),
492
('add', ('dir/file', 'file-id', 'file', 'trunk content\n'))]
494
def do_modify_file_in_dir(self):
495
return [('modify', ('file-id', 'trunk content\nmore content\n'))]
497
def check_file_in_dir_has_more_content(self):
498
self.assertFileEqual('trunk content\nmore content\n', 'branch/dir/file')
500
def check_file_in_dir_doesnt_exist(self):
501
self.assertPathDoesNotExist('branch/dir/file')
503
def _get_resolve_path_arg(self, wt, action):
446
506
def assertContentsConflict(self, wt, c):
447
self.assertEqual(self._other_id, c.file_id)
448
self.assertEqual(self._other_path, c.path)
507
self.assertEqual(self._file_id, c.file_id)
508
self.assertEqual(self._path, c.path)
449
509
_assert_conflict = assertContentsConflict
453
512
class TestResolvePathConflict(TestParametrizedResolveConflicts):
455
_conflict_type = conflicts.PathConflict,
458
def scenarios(klass):
459
for_file = dict(_actions_base='create_file',
460
_item_path='new-file', _item_id='file-id',)
461
for_dir = dict(_actions_base='create_dir',
462
_item_path='new-dir', _item_id='dir-id',)
465
dict(actions='rename_file', check='file_renamed')),
467
dict(actions='delete_file', check='file_doesnt_exist')),
470
dict(actions='rename_file', check='file_renamed')),
514
_conflict_type = conflicts.PathConflict
516
def do_nothing(self):
519
# Each side dict additionally defines:
520
# - path path involved (can be '<deleted>')
522
scenarios = mirror_scenarios(
524
# File renamed/deleted
525
(dict(_base_actions='create_file'),
527
dict(actions='rename_file', check='file_renamed',
528
path='new-file', file_id='file-id')),
530
dict(actions='delete_file', check='file_doesnt_exist',
531
# PathConflicts deletion handling requires a special
533
path='<deleted>', file_id='file-id')),),
534
# File renamed/deleted in dir
535
(dict(_base_actions='create_file_in_dir'),
536
('file_renamed_in_dir',
537
dict(actions='rename_file_in_dir', check='file_in_dir_renamed',
538
path='dir/new-file', file_id='file-id')),
540
dict(actions='delete_file', check='file_in_dir_doesnt_exist',
541
# PathConflicts deletion handling requires a special
543
path='<deleted>', file_id='file-id')),),
544
# File renamed/renamed differently
545
(dict(_base_actions='create_file'),
547
dict(actions='rename_file', check='file_renamed',
548
path='new-file', file_id='file-id')),
471
549
('file_renamed2',
472
dict(actions='rename_file2', check='file_renamed2')),
475
dict(actions='rename_dir', check='dir_renamed')),
550
dict(actions='rename_file2', check='file_renamed2',
551
path='new-file2', file_id='file-id')),),
552
# Dir renamed/deleted
553
(dict(_base_actions='create_dir'),
555
dict(actions='rename_dir', check='dir_renamed',
556
path='new-dir', file_id='dir-id')),
477
dict(actions='delete_dir', check='dir_doesnt_exist')),
480
dict(actions='rename_dir', check='dir_renamed')),
558
dict(actions='delete_dir', check='dir_doesnt_exist',
559
# PathConflicts deletion handling requires a special
561
path='<deleted>', file_id='dir-id')),),
562
# Dir renamed/renamed differently
563
(dict(_base_actions='create_dir'),
565
dict(actions='rename_dir', check='dir_renamed',
566
path='new-dir', file_id='dir-id')),
482
dict(actions='rename_dir2', check='dir_renamed2')),
485
return klass.mirror_scenarios(base_scenarios)
568
dict(actions='rename_dir2', check='dir_renamed2',
569
path='new-dir2', file_id='dir-id')),),
572
def do_create_file(self):
573
return [('add', ('file', 'file-id', 'file', 'trunk content\n'))]
575
def do_create_dir(self):
576
return [('add', ('dir', 'dir-id', 'directory', ''))]
578
def do_rename_file(self):
579
return [('rename', ('file', 'new-file'))]
581
def check_file_renamed(self):
582
self.assertPathDoesNotExist('branch/file')
583
self.assertPathExists('branch/new-file')
585
def do_rename_file2(self):
586
return [('rename', ('file', 'new-file2'))]
588
def check_file_renamed2(self):
589
self.assertPathDoesNotExist('branch/file')
590
self.assertPathExists('branch/new-file2')
592
def do_rename_dir(self):
593
return [('rename', ('dir', 'new-dir'))]
595
def check_dir_renamed(self):
596
self.assertPathDoesNotExist('branch/dir')
597
self.assertPathExists('branch/new-dir')
599
def do_rename_dir2(self):
600
return [('rename', ('dir', 'new-dir2'))]
602
def check_dir_renamed2(self):
603
self.assertPathDoesNotExist('branch/dir')
604
self.assertPathExists('branch/new-dir2')
487
606
def do_delete_file(self):
488
sup = super(TestResolvePathConflict, self).do_delete_file()
489
# PathConflicts handle deletion differently and requires a special
491
return ('<deleted>',) + sup[1:]
607
return [('unversion', 'file-id')]
609
def check_file_doesnt_exist(self):
610
self.assertPathDoesNotExist('branch/file')
612
def do_delete_dir(self):
613
return [('unversion', 'dir-id')]
615
def check_dir_doesnt_exist(self):
616
self.assertPathDoesNotExist('branch/dir')
618
def do_create_file_in_dir(self):
619
return [('add', ('dir', 'dir-id', 'directory', '')),
620
('add', ('dir/file', 'file-id', 'file', 'trunk content\n'))]
622
def do_rename_file_in_dir(self):
623
return [('rename', ('dir/file', 'dir/new-file'))]
625
def check_file_in_dir_renamed(self):
626
self.assertPathDoesNotExist('branch/dir/file')
627
self.assertPathExists('branch/dir/new-file')
629
def check_file_in_dir_doesnt_exist(self):
630
self.assertPathDoesNotExist('branch/dir/file')
632
def _get_resolve_path_arg(self, wt, action):
633
tpath = self._this['path']
634
opath = self._other['path']
635
if tpath == '<deleted>':
493
641
def assertPathConflict(self, wt, c):
494
self.assertEqual(self._item_id, c.file_id)
495
self.assertEqual(self._this_path, c.path)
496
self.assertEqual(self._other_path, c.conflict_path)
642
tpath = self._this['path']
643
tfile_id = self._this['file_id']
644
opath = self._other['path']
645
ofile_id = self._other['file_id']
646
self.assertEqual(tfile_id, ofile_id) # Sanity check
647
self.assertEqual(tfile_id, c.file_id)
648
self.assertEqual(tpath, c.path)
649
self.assertEqual(opath, c.conflict_path)
497
650
_assert_conflict = assertPathConflict
667
846
def test_keep_them_all(self):
668
847
self.run_script("""
669
848
$ bzr resolve dir
670
$ bzr commit --strict -m 'No more conflicts nor unknown files'
849
2>2 conflict(s) resolved, 0 remaining
850
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
673
853
def test_adopt_child(self):
674
854
self.run_script("""
675
$ bzr mv dir/file2 file2
855
$ bzr mv -q dir/file2 file2
856
$ bzr rm -q dir --force
677
857
$ bzr resolve dir
678
$ bzr commit --strict -m 'No more conflicts nor unknown files'
858
2>2 conflict(s) resolved, 0 remaining
859
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
681
862
def test_kill_them_all(self):
682
863
self.run_script("""
864
$ bzr rm -q dir --force
684
865
$ bzr resolve dir
685
$ bzr commit --strict -m 'No more conflicts nor unknown files'
866
2>2 conflict(s) resolved, 0 remaining
867
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
688
870
def test_resolve_taking_this(self):
689
871
self.run_script("""
690
872
$ bzr resolve --take-this dir
691
$ bzr commit --strict -m 'No more conflicts nor unknown files'
873
2>2 conflict(s) resolved, 0 remaining
874
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
694
877
def test_resolve_taking_other(self):
695
878
self.run_script("""
696
879
$ bzr resolve --take-other dir
697
$ bzr commit --strict -m 'No more conflicts nor unknown files'
882
2>2 conflict(s) resolved, 0 remaining
883
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
701
887
class TestResolveParentLoop(TestParametrizedResolveConflicts):
703
_conflict_type = conflicts.ParentLoop,
705
def scenarios(klass):
707
(('dir1_into_dir2', dict(actions='move_dir1_into_dir2',
708
check='dir1_moved')),
709
('dir2_into_dir1', dict(actions='move_dir2_into_dir1',
710
check='dir2_moved')),
711
dict(_actions_base='create_dir1_dir2')),
712
(('dir1_into_dir4', dict(actions='move_dir1_into_dir4',
713
check='dir1_2_moved')),
714
('dir3_into_dir2', dict(actions='move_dir3_into_dir2',
715
check='dir3_4_moved')),
716
dict(_actions_base='create_dir1_4')),
718
return klass.mirror_scenarios(base_scenarios)
889
_conflict_type = conflicts.ParentLoop
894
# Each side dict additionally defines:
895
# - dir_id: the directory being moved
896
# - target_id: The target directory
897
# - xfail: whether the test is expected to fail if the action is
898
# involved as 'other'
899
scenarios = mirror_scenarios(
901
# Dirs moved into each other
902
(dict(_base_actions='create_dir1_dir2'),
904
dict(actions='move_dir1_into_dir2', check='dir1_moved',
905
dir_id='dir1-id', target_id='dir2-id', xfail=False)),
907
dict(actions='move_dir2_into_dir1', check='dir2_moved',
908
dir_id='dir2-id', target_id='dir1-id', xfail=False))),
909
# Subdirs moved into each other
910
(dict(_base_actions='create_dir1_4'),
912
dict(actions='move_dir1_into_dir4', check='dir1_2_moved',
913
dir_id='dir1-id', target_id='dir4-id', xfail=True)),
915
dict(actions='move_dir3_into_dir2', check='dir3_4_moved',
916
dir_id='dir3-id', target_id='dir2-id', xfail=True))),
720
919
def do_create_dir1_dir2(self):
722
[('add', ('dir1', 'dir1-id', 'directory', '')),
723
('add', ('dir2', 'dir2-id', 'directory', '')),
920
return [('add', ('dir1', 'dir1-id', 'directory', '')),
921
('add', ('dir2', 'dir2-id', 'directory', '')),]
726
923
def do_move_dir1_into_dir2(self):
727
# The arguments are the file-id to move and the targeted file-id dir.
728
return ('dir1-id', 'dir2-id', [('rename', ('dir1', 'dir2/dir1'))])
924
return [('rename', ('dir1', 'dir2/dir1'))]
730
926
def check_dir1_moved(self):
731
self.failIfExists('branch/dir1')
732
self.failUnlessExists('branch/dir2/dir1')
927
self.assertPathDoesNotExist('branch/dir1')
928
self.assertPathExists('branch/dir2/dir1')
734
930
def do_move_dir2_into_dir1(self):
735
# The arguments are the file-id to move and the targeted file-id dir.
736
return ('dir2-id', 'dir1-id', [('rename', ('dir2', 'dir1/dir2'))])
931
return [('rename', ('dir2', 'dir1/dir2'))]
738
933
def check_dir2_moved(self):
739
self.failIfExists('branch/dir2')
740
self.failUnlessExists('branch/dir1/dir2')
934
self.assertPathDoesNotExist('branch/dir2')
935
self.assertPathExists('branch/dir1/dir2')
742
937
def do_create_dir1_4(self):
744
[('add', ('dir1', 'dir1-id', 'directory', '')),
745
('add', ('dir1/dir2', 'dir2-id', 'directory', '')),
746
('add', ('dir3', 'dir3-id', 'directory', '')),
747
('add', ('dir3/dir4', 'dir4-id', 'directory', '')),
938
return [('add', ('dir1', 'dir1-id', 'directory', '')),
939
('add', ('dir1/dir2', 'dir2-id', 'directory', '')),
940
('add', ('dir3', 'dir3-id', 'directory', '')),
941
('add', ('dir3/dir4', 'dir4-id', 'directory', '')),]
750
943
def do_move_dir1_into_dir4(self):
751
# The arguments are the file-id to move and the targeted file-id dir.
752
return ('dir1-id', 'dir4-id',
753
[('rename', ('dir1', 'dir3/dir4/dir1'))])
944
return [('rename', ('dir1', 'dir3/dir4/dir1'))]
755
946
def check_dir1_2_moved(self):
756
self.failIfExists('branch/dir1')
757
self.failUnlessExists('branch/dir3/dir4/dir1')
758
self.failUnlessExists('branch/dir3/dir4/dir1/dir2')
947
self.assertPathDoesNotExist('branch/dir1')
948
self.assertPathExists('branch/dir3/dir4/dir1')
949
self.assertPathExists('branch/dir3/dir4/dir1/dir2')
760
951
def do_move_dir3_into_dir2(self):
761
# The arguments are the file-id to move and the targeted file-id dir.
762
return ('dir3-id', 'dir2-id',
763
[('rename', ('dir3', 'dir1/dir2/dir3'))])
952
return [('rename', ('dir3', 'dir1/dir2/dir3'))]
765
954
def check_dir3_4_moved(self):
766
self.failIfExists('branch/dir3')
767
self.failUnlessExists('branch/dir1/dir2/dir3')
768
self.failUnlessExists('branch/dir1/dir2/dir3/dir4')
955
self.assertPathDoesNotExist('branch/dir3')
956
self.assertPathExists('branch/dir1/dir2/dir3')
957
self.assertPathExists('branch/dir1/dir2/dir3/dir4')
770
959
def _get_resolve_path_arg(self, wt, action):
771
# ParentLoop is unsual as it says:
772
# moving <conflict_path> into <path>. Cancelled move.
960
# ParentLoop says: moving <conflict_path> into <path>. Cancelled move.
773
961
# But since <path> doesn't exist in the working tree, we need to use
774
# <conflict_path> instead
775
path = wt.id2path(self._other_id)
962
# <conflict_path> instead, and that, in turn, is given by dir_id. Pfew.
963
return wt.id2path(self._other['dir_id'])
778
965
def assertParentLoop(self, wt, c):
779
if 'taking_other(' in self.id() and 'dir4' in self.id():
780
raise tests.KnownFailure(
781
"ParentLoop doesn't carry enough info to resolve")
782
# The relevant file-ids are other_args swapped (which is the main
783
# reason why they should be renamed other_args instead of Other_path
784
# and other_id). In the conflict object, they represent:
785
# c.file_id: the directory being moved
786
# c.conflict_id_id: The target directory
787
self.assertEqual(self._other_path, c.file_id)
788
self.assertEqual(self._other_id, c.conflict_file_id)
966
self.assertEqual(self._other['dir_id'], c.file_id)
967
self.assertEqual(self._other['target_id'], c.conflict_file_id)
789
968
# The conflict paths are irrelevant (they are deterministic but not
790
969
# worth checking since they don't provide the needed information
971
if self._other['xfail']:
972
# It's a bit hackish to raise from here relying on being called for
973
# both tests but this avoid overriding test_resolve_taking_other
975
"ParentLoop doesn't carry enough info to resolve --take-other")
792
976
_assert_conflict = assertParentLoop
795
class OldTestResolveParentLoop(TestResolveConflicts):
802
$ bzr commit -m 'Create trunk'
805
$ bzr commit -m 'Moved dir2 into dir1'
807
$ bzr branch . -r 1 ../branch
810
$ bzr commit -m 'Moved dir1 into dir2'
813
2>Conflict moving dir2 into dir2/dir1. Cancelled move.
814
2>1 conflicts encountered.
817
def test_take_this(self):
820
$ bzr commit --strict -m 'No more conflicts nor unknown files'
823
def test_take_other(self):
825
$ bzr mv dir2/dir1 dir1
828
$ bzr commit --strict -m 'No more conflicts nor unknown files'
831
def test_resolve_taking_this(self):
833
$ bzr resolve --take-this dir2
834
$ bzr commit --strict -m 'No more conflicts nor unknown files'
836
self.failUnlessExists('dir2')
838
def test_resolve_taking_other(self):
840
$ bzr resolve --take-other dir2
841
$ bzr commit --strict -m 'No more conflicts nor unknown files'
843
self.failUnlessExists('dir1')
846
979
class TestResolveNonDirectoryParent(TestResolveConflicts):
852
$ bzr commit -m 'Create trunk'
987
$ bzr commit -m 'Create trunk' -q
853
988
$ echo "Boing" >foo/bar
855
$ bzr commit -m 'Add foo/bar'
857
$ bzr branch . -r 1 ../branch
990
$ bzr commit -q -m 'Add foo/bar'
991
$ bzr branch -q . -r 1 ../branch
860
994
$ echo "Boo!" >foo
861
$ bzr commit -m 'foo is now a file'
995
$ bzr commit -q -m 'foo is now a file'
863
996
$ bzr merge ../trunk
865
998
2>RK foo => foo.new/