600
587
bar1_abspath = self.wt.abspath('bar')
601
588
self.assertEqual([bar1_abspath], stat_paths)
603
def test_iter_changes(self):
604
self.wt.set_root_id('eert_toor')
605
transform, root = self.get_transform()
606
transform.new_file('old', root, 'blah', 'id-1', True)
608
transform, root = self.get_transform()
610
self.assertEqual([], list(transform._iter_changes()))
611
old = transform.trans_id_tree_file_id('id-1')
612
transform.unversion_file(old)
613
self.assertEqual([('id-1', ('old', None), False, (True, False),
614
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
615
(True, True))], list(transform._iter_changes()))
616
transform.new_directory('new', root, 'id-1')
617
self.assertEqual([('id-1', ('old', 'new'), True, (True, True),
618
('eert_toor', 'eert_toor'), ('old', 'new'),
619
('file', 'directory'),
620
(True, False))], list(transform._iter_changes()))
624
def test_iter_changes_new(self):
625
self.wt.set_root_id('eert_toor')
626
transform, root = self.get_transform()
627
transform.new_file('old', root, 'blah')
629
transform, root = self.get_transform()
631
old = transform.trans_id_tree_path('old')
632
transform.version_file('id-1', old)
633
self.assertEqual([('id-1', (None, 'old'), False, (False, True),
634
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
635
(False, False))], list(transform._iter_changes()))
639
def test_iter_changes_modifications(self):
640
self.wt.set_root_id('eert_toor')
641
transform, root = self.get_transform()
642
transform.new_file('old', root, 'blah', 'id-1')
643
transform.new_file('new', root, 'blah')
644
transform.new_directory('subdir', root, 'subdir-id')
646
transform, root = self.get_transform()
648
old = transform.trans_id_tree_path('old')
649
subdir = transform.trans_id_tree_file_id('subdir-id')
650
new = transform.trans_id_tree_path('new')
651
self.assertEqual([], list(transform._iter_changes()))
654
transform.delete_contents(old)
655
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
656
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', None),
657
(False, False))], list(transform._iter_changes()))
660
transform.create_file('blah', old)
661
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
662
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
663
(False, False))], list(transform._iter_changes()))
664
transform.cancel_deletion(old)
665
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
666
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
667
(False, False))], list(transform._iter_changes()))
668
transform.cancel_creation(old)
670
# move file_id to a different file
671
self.assertEqual([], list(transform._iter_changes()))
672
transform.unversion_file(old)
673
transform.version_file('id-1', new)
674
transform.adjust_path('old', root, new)
675
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
676
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
677
(False, False))], list(transform._iter_changes()))
678
transform.cancel_versioning(new)
679
transform._removed_id = set()
682
self.assertEqual([], list(transform._iter_changes()))
683
transform.set_executability(True, old)
684
self.assertEqual([('id-1', ('old', 'old'), False, (True, True),
685
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
686
(False, True))], list(transform._iter_changes()))
687
transform.set_executability(None, old)
690
self.assertEqual([], list(transform._iter_changes()))
691
transform.adjust_path('new', root, old)
692
transform._new_parent = {}
693
self.assertEqual([('id-1', ('old', 'new'), False, (True, True),
694
('eert_toor', 'eert_toor'), ('old', 'new'), ('file', 'file'),
695
(False, False))], list(transform._iter_changes()))
696
transform._new_name = {}
699
self.assertEqual([], list(transform._iter_changes()))
700
transform.adjust_path('new', subdir, old)
701
transform._new_name = {}
702
self.assertEqual([('id-1', ('old', 'subdir/old'), False,
703
(True, True), ('eert_toor', 'subdir-id'), ('old', 'old'),
704
('file', 'file'), (False, False))],
705
list(transform._iter_changes()))
706
transform._new_path = {}
711
def test_iter_changes_modified_bleed(self):
712
self.wt.set_root_id('eert_toor')
713
"""Modified flag should not bleed from one change to another"""
714
# unfortunately, we have no guarantee that file1 (which is modified)
715
# will be applied before file2. And if it's applied after file2, it
716
# obviously can't bleed into file2's change output. But for now, it
718
transform, root = self.get_transform()
719
transform.new_file('file1', root, 'blah', 'id-1')
720
transform.new_file('file2', root, 'blah', 'id-2')
722
transform, root = self.get_transform()
724
transform.delete_contents(transform.trans_id_file_id('id-1'))
725
transform.set_executability(True,
726
transform.trans_id_file_id('id-2'))
727
self.assertEqual([('id-1', (u'file1', u'file1'), True, (True, True),
728
('eert_toor', 'eert_toor'), ('file1', u'file1'),
729
('file', None), (False, False)),
730
('id-2', (u'file2', u'file2'), False, (True, True),
731
('eert_toor', 'eert_toor'), ('file2', u'file2'),
732
('file', 'file'), (False, True))],
733
list(transform._iter_changes()))
737
def test_iter_changes_move_missing(self):
738
"""Test moving ids with no files around"""
739
self.wt.set_root_id('toor_eert')
740
# Need two steps because versioning a non-existant file is a conflict.
741
transform, root = self.get_transform()
742
transform.new_directory('floater', root, 'floater-id')
744
transform, root = self.get_transform()
745
transform.delete_contents(transform.trans_id_tree_path('floater'))
747
transform, root = self.get_transform()
748
floater = transform.trans_id_tree_path('floater')
750
transform.adjust_path('flitter', root, floater)
751
self.assertEqual([('floater-id', ('floater', 'flitter'), False,
752
(True, True), ('toor_eert', 'toor_eert'), ('floater', 'flitter'),
753
(None, None), (False, False))], list(transform._iter_changes()))
757
def test_iter_changes_pointless(self):
758
"""Ensure that no-ops are not treated as modifications"""
759
self.wt.set_root_id('eert_toor')
760
transform, root = self.get_transform()
761
transform.new_file('old', root, 'blah', 'id-1')
762
transform.new_directory('subdir', root, 'subdir-id')
764
transform, root = self.get_transform()
766
old = transform.trans_id_tree_path('old')
767
subdir = transform.trans_id_tree_file_id('subdir-id')
768
self.assertEqual([], list(transform._iter_changes()))
769
transform.delete_contents(subdir)
770
transform.create_directory(subdir)
771
transform.set_executability(False, old)
772
transform.unversion_file(old)
773
transform.version_file('id-1', old)
774
transform.adjust_path('old', root, old)
775
self.assertEqual([], list(transform._iter_changes()))
779
def test_rename_count(self):
780
transform, root = self.get_transform()
781
transform.new_file('name1', root, 'contents')
782
self.assertEqual(transform.rename_count, 0)
784
self.assertEqual(transform.rename_count, 1)
785
transform2, root = self.get_transform()
786
transform2.adjust_path('name2', root,
787
transform2.trans_id_tree_path('name1'))
788
self.assertEqual(transform2.rename_count, 0)
790
self.assertEqual(transform2.rename_count, 2)
792
def test_change_parent(self):
793
"""Ensure that after we change a parent, the results are still right.
795
Renames and parent changes on pending transforms can happen as part
796
of conflict resolution, and are explicitly permitted by the
799
This test ensures they work correctly with the rename-avoidance
802
transform, root = self.get_transform()
803
parent1 = transform.new_directory('parent1', root)
804
child1 = transform.new_file('child1', parent1, 'contents')
805
parent2 = transform.new_directory('parent2', root)
806
transform.adjust_path('child1', parent2, child1)
808
self.failIfExists(self.wt.abspath('parent1/child1'))
809
self.failUnlessExists(self.wt.abspath('parent2/child1'))
810
# rename limbo/new-1 => parent1, rename limbo/new-3 => parent2
811
# no rename for child1 (counting only renames during apply)
812
self.failUnlessEqual(2, transform.rename_count)
814
def test_cancel_parent(self):
815
"""Cancelling a parent doesn't cause deletion of a non-empty directory
817
This is like the test_change_parent, except that we cancel the parent
818
before adjusting the path. The transform must detect that the
819
directory is non-empty, and move children to safe locations.
821
transform, root = self.get_transform()
822
parent1 = transform.new_directory('parent1', root)
823
child1 = transform.new_file('child1', parent1, 'contents')
824
child2 = transform.new_file('child2', parent1, 'contents')
826
transform.cancel_creation(parent1)
828
self.fail('Failed to move child1 before deleting parent1')
829
transform.cancel_creation(child2)
830
transform.create_directory(parent1)
832
transform.cancel_creation(parent1)
833
# If the transform incorrectly believes that child2 is still in
834
# parent1's limbo directory, it will try to rename it and fail
835
# because was already moved by the first cancel_creation.
837
self.fail('Transform still thinks child2 is a child of parent1')
838
parent2 = transform.new_directory('parent2', root)
839
transform.adjust_path('child1', parent2, child1)
841
self.failIfExists(self.wt.abspath('parent1'))
842
self.failUnlessExists(self.wt.abspath('parent2/child1'))
843
# rename limbo/new-3 => parent2, rename limbo/new-2 => child1
844
self.failUnlessEqual(2, transform.rename_count)
846
def test_adjust_and_cancel(self):
847
"""Make sure adjust_path keeps track of limbo children properly"""
848
transform, root = self.get_transform()
849
parent1 = transform.new_directory('parent1', root)
850
child1 = transform.new_file('child1', parent1, 'contents')
851
parent2 = transform.new_directory('parent2', root)
852
transform.adjust_path('child1', parent2, child1)
853
transform.cancel_creation(child1)
855
transform.cancel_creation(parent1)
856
# if the transform thinks child1 is still in parent1's limbo
857
# directory, it will attempt to move it and fail.
859
self.fail('Transform still thinks child1 is a child of parent1')
862
def test_noname_contents(self):
863
"""TreeTransform should permit deferring naming files."""
864
transform, root = self.get_transform()
865
parent = transform.trans_id_file_id('parent-id')
867
transform.create_directory(parent)
869
self.fail("Can't handle contents with no name")
872
def test_noname_contents_nested(self):
873
"""TreeTransform should permit deferring naming files."""
874
transform, root = self.get_transform()
875
parent = transform.trans_id_file_id('parent-id')
877
transform.create_directory(parent)
879
self.fail("Can't handle contents with no name")
880
child = transform.new_directory('child', parent)
881
transform.adjust_path('parent', root, parent)
883
self.failUnlessExists(self.wt.abspath('parent/child'))
884
self.assertEqual(1, transform.rename_count)
886
def test_reuse_name(self):
887
"""Avoid reusing the same limbo name for different files"""
888
transform, root = self.get_transform()
889
parent = transform.new_directory('parent', root)
890
child1 = transform.new_directory('child', parent)
892
child2 = transform.new_directory('child', parent)
894
self.fail('Tranform tried to use the same limbo name twice')
895
transform.adjust_path('child2', parent, child2)
897
# limbo/new-1 => parent, limbo/new-3 => parent/child2
898
# child2 is put into top-level limbo because child1 has already
899
# claimed the direct limbo path when child2 is created. There is no
900
# advantage in renaming files once they're in top-level limbo, except
902
self.assertEqual(2, transform.rename_count)
904
def test_reuse_when_first_moved(self):
905
"""Don't avoid direct paths when it is safe to use them"""
906
transform, root = self.get_transform()
907
parent = transform.new_directory('parent', root)
908
child1 = transform.new_directory('child', parent)
909
transform.adjust_path('child1', parent, child1)
910
child2 = transform.new_directory('child', parent)
912
# limbo/new-1 => parent
913
self.assertEqual(1, transform.rename_count)
915
def test_reuse_after_cancel(self):
916
"""Don't avoid direct paths when it is safe to use them"""
917
transform, root = self.get_transform()
918
parent2 = transform.new_directory('parent2', root)
919
child1 = transform.new_directory('child1', parent2)
920
transform.cancel_creation(parent2)
921
transform.create_directory(parent2)
922
child2 = transform.new_directory('child1', parent2)
923
transform.adjust_path('child2', parent2, child1)
925
# limbo/new-1 => parent2, limbo/new-2 => parent2/child1
926
self.assertEqual(2, transform.rename_count)
928
def test_finalize_order(self):
929
"""Finalize must be done in child-to-parent order"""
930
transform, root = self.get_transform()
931
parent = transform.new_directory('parent', root)
932
child = transform.new_directory('child', parent)
936
self.fail('Tried to remove parent before child1')
938
def test_cancel_with_cancelled_child_should_succeed(self):
939
transform, root = self.get_transform()
940
parent = transform.new_directory('parent', root)
941
child = transform.new_directory('child', parent)
942
transform.cancel_creation(child)
943
transform.cancel_creation(parent)
946
def test_change_entry(self):
947
txt = 'bzrlib.transform.change_entry was deprecated in version 0.19.'
948
self.callDeprecated([txt], change_entry, None, None, None, None, None,
952
591
class TransformGroup(object):
953
592
def __init__(self, dirname, root_id):