87
87
def test_set_one_ghost_parent_rejects(self):
88
88
t = self.make_branch_and_tree('.')
89
89
self.assertRaises(errors.GhostRevisionUnusableHere,
90
t.set_parent_trees, [(b'missing-revision-id', None)])
90
t.set_parent_trees, [(b'missing-revision-id', None)])
92
92
def test_set_one_ghost_parent_force(self):
93
93
t = self.make_branch_and_tree('.')
94
94
if t._format.supports_leftmost_parent_id_as_ghost:
95
95
t.set_parent_trees([(b'missing-revision-id', None)],
96
allow_leftmost_as_ghost=True)
96
allow_leftmost_as_ghost=True)
97
97
self.assertConsistentParents([b'missing-revision-id'], t)
99
99
self.assertRaises(errors.GhostRevisionUnusableHere,
100
t.set_parent_trees, [(b'missing-revision-id', None)])
100
t.set_parent_trees, [(b'missing-revision-id', None)])
101
101
self.assertConsistentParents([], t)
103
103
def test_set_two_parents_one_ghost(self):
108
108
rev_tree = t.branch.repository.revision_tree(revision_in_repo)
109
109
if t._format.supports_righthand_parent_id_as_ghost:
110
110
t.set_parent_trees([(revision_in_repo, rev_tree),
111
(b'another-missing', None)])
112
self.assertConsistentParents([revision_in_repo, b'another-missing'], t)
111
(b'another-missing', None)])
112
self.assertConsistentParents(
113
[revision_in_repo, b'another-missing'], t)
114
115
self.assertRaises(errors.GhostRevisionUnusableHere,
115
t.set_parent_trees, [(revision_in_repo, rev_tree),
116
(b'another-missing', None)])
116
t.set_parent_trees, [(revision_in_repo, rev_tree),
117
(b'another-missing', None)])
118
119
def test_set_three_parents(self):
119
120
t = self.make_branch_and_tree('.')
127
128
rev_tree2 = t.branch.repository.revision_tree(second_revision)
128
129
rev_tree3 = t.branch.repository.revision_tree(third_revision)
129
130
t.set_parent_trees([(first_revision, rev_tree1),
130
(second_revision, rev_tree2),
131
(third_revision, rev_tree3)])
131
(second_revision, rev_tree2),
132
(third_revision, rev_tree3)])
132
133
self.assertConsistentParents(
133
134
[first_revision, second_revision, third_revision], t)
144
145
def test_set_one_ghost_parent_ids_rejects(self):
145
146
t = self.make_branch_and_tree('.')
146
147
self.assertRaises(errors.GhostRevisionUnusableHere,
147
t.set_parent_ids, [b'missing-revision-id'])
148
t.set_parent_ids, [b'missing-revision-id'])
149
150
def test_set_one_ghost_parent_ids_force(self):
150
151
t = self.make_branch_and_tree('.')
151
152
if t._format.supports_leftmost_parent_id_as_ghost:
152
153
t.set_parent_ids([b'missing-revision-id'],
153
allow_leftmost_as_ghost=True)
154
allow_leftmost_as_ghost=True)
154
155
self.assertConsistentParents([b'missing-revision-id'], t)
156
157
self.assertRaises(
165
166
rev_tree = t.branch.repository.revision_tree(revision_in_repo)
166
167
if t._format.supports_righthand_parent_id_as_ghost:
167
168
t.set_parent_ids([revision_in_repo, b'another-missing'])
168
self.assertConsistentParents([revision_in_repo, b'another-missing'], t)
169
self.assertConsistentParents(
170
[revision_in_repo, b'another-missing'], t)
170
172
self.assertRaises(errors.GhostRevisionUnusableHere,
171
t.set_parent_ids, [revision_in_repo, b'another-missing'])
173
t.set_parent_ids, [revision_in_repo, b'another-missing'])
173
175
def test_set_three_parents_ids(self):
174
176
t = self.make_branch_and_tree('.')
292
294
"""Test adding the first parent id - as a ghost"""
293
295
tree = self.make_branch_and_tree('.')
294
296
self.assertRaises(errors.GhostRevisionUnusableHere,
295
tree.add_parent_tree_id, b'first-revision')
297
tree.add_parent_tree_id, b'first-revision')
297
299
def test_add_first_parent_id_ghost_force(self):
298
300
"""Test adding the first parent id - as a ghost"""
299
301
tree = self.make_branch_and_tree('.')
301
tree.add_parent_tree_id(b'first-revision', allow_leftmost_as_ghost=True)
303
tree.add_parent_tree_id(
304
b'first-revision', allow_leftmost_as_ghost=True)
302
305
except errors.GhostRevisionUnusableHere:
303
306
self.assertFalse(tree._format.supports_leftmost_parent_id_as_ghost)
342
346
first_revision = tree.commit('first post')
343
347
uncommit(tree.branch, tree=tree)
344
348
tree.add_parent_tree((first_revision,
345
tree.branch.repository.revision_tree(first_revision)))
349
tree.branch.repository.revision_tree(first_revision)))
346
350
self.assertConsistentParents([first_revision], tree)
348
352
def test_add_first_parent_tree_ghost_rejects(self):
349
353
"""Test adding the first parent id - as a ghost"""
350
354
tree = self.make_branch_and_tree('.')
351
355
self.assertRaises(errors.GhostRevisionUnusableHere,
352
tree.add_parent_tree, (b'first-revision', None))
356
tree.add_parent_tree, (b'first-revision', None))
354
358
def test_add_first_parent_tree_ghost_force(self):
355
359
"""Test adding the first parent id - as a ghost"""
356
360
tree = self.make_branch_and_tree('.')
358
362
tree.add_parent_tree((b'first-revision', None),
359
allow_leftmost_as_ghost=True)
363
allow_leftmost_as_ghost=True)
360
364
except errors.GhostRevisionUnusableHere:
361
365
self.assertFalse(tree._format.supports_leftmost_parent_id_as_ghost)
419
423
for file_id in deletes:
420
424
delta.append((old.id2path(file_id), None, file_id, None))
421
425
for file_id in adds:
422
delta.append((None, new.id2path(file_id), file_id, new.get_entry(file_id)))
426
delta.append((None, new.id2path(file_id),
427
file_id, new.get_entry(file_id)))
423
428
for file_id in common:
424
429
if old.get_entry(file_id) != new.get_entry(file_id):
425
430
delta.append((old.id2path(file_id), new.id2path(file_id),
426
file_id, new.get_entry(file_id)))
431
file_id, new.get_entry(file_id)))
429
434
def fake_up_revision(self, tree, revid, shape):
452
457
if shape.root.revision is None:
453
458
shape.root.revision = revid
454
459
builder = tree.branch.get_commit_builder(
458
committer="Foo Bar <foo@example.com>",
463
committer="Foo Bar <foo@example.com>",
460
465
shape_tree = ShapeTree(shape)
461
466
base_tree = tree.branch.repository.revision_tree(
462
_mod_revision.NULL_REVISION)
467
_mod_revision.NULL_REVISION)
463
468
changes = shape_tree.iter_changes(
465
470
list(builder.record_iter_changes(shape_tree,
466
base_tree.get_revision_id(), changes))
471
base_tree.get_revision_id(), changes))
467
472
builder.finish_inventory()
468
473
builder.commit("Message")
493
498
self.add_dir(new_shape, new_revid, b'root-id', None, '')
495
500
def assertTransitionFromBasisToShape(self, basis_shape, basis_revid,
496
new_shape, new_revid, extra_parent=None, set_current_inventory=True):
501
new_shape, new_revid, extra_parent=None, set_current_inventory=True):
497
502
# set the inventory revision ids.
498
503
basis_shape.revision_id = basis_revid
499
504
new_shape.revision_id = new_revid
528
533
basis_shape = Inventory(root_id=None) # empty tree
529
534
new_shape = Inventory() # tree with a root
530
535
self.assertTransitionFromBasisToShape(basis_shape, None, new_shape,
533
538
def test_no_parents_full_tree(self):
534
539
"""Test doing a regular initial commit with files and dirs."""
535
basis_shape = Inventory(root_id=None) # empty tree
540
basis_shape = Inventory(root_id=None) # empty tree
536
541
revid = b'new-parent'
537
542
new_shape = Inventory(root_id=None)
538
543
self.add_dir(new_shape, revid, b'root-id', None, '')
539
self.add_link(new_shape, revid, b'link-id', b'root-id', 'link', 'target')
544
self.add_link(new_shape, revid, b'link-id',
545
b'root-id', 'link', 'target')
540
546
self.add_file(new_shape, revid, b'file-id', b'root-id', 'file', b'1' * 32,
542
548
self.add_dir(new_shape, revid, b'dir-id', b'root-id', 'dir')
543
549
self.add_file(new_shape, revid, b'subfile-id', b'dir-id', 'subfile',
545
551
self.assertTransitionFromBasisToShape(basis_shape, None, new_shape,
548
554
def test_file_content_change(self):
549
555
old_revid = b'old-parent'
550
556
basis_shape = Inventory(root_id=None)
551
557
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
552
558
self.add_file(basis_shape, old_revid, b'file-id', b'root-id', 'file',
554
560
new_revid = b'new-parent'
555
561
new_shape = Inventory(root_id=None)
556
562
self.add_new_root(new_shape, old_revid, new_revid)
557
563
self.add_file(new_shape, new_revid, b'file-id', b'root-id', 'file',
559
565
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
560
new_shape, new_revid)
566
new_shape, new_revid)
562
568
def test_link_content_change(self):
563
569
old_revid = b'old-parent'
564
570
basis_shape = Inventory(root_id=None)
565
571
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
566
572
self.add_link(basis_shape, old_revid, b'link-id', b'root-id', 'link',
568
574
new_revid = b'new-parent'
569
575
new_shape = Inventory(root_id=None)
570
576
self.add_new_root(new_shape, old_revid, new_revid)
571
577
self.add_link(new_shape, new_revid, b'link-id', b'root-id', 'link',
573
579
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
574
new_shape, new_revid)
580
new_shape, new_revid)
576
582
def test_kind_changes(self):
577
583
def do_file(inv, revid):
578
584
self.add_file(inv, revid, b'path-id', b'root-id', 'path', b'1' * 32,
581
587
def do_link(inv, revid):
582
588
self.add_link(inv, revid, b'path-id', b'root-id', 'path', 'target')
597
603
self.add_new_root(new_shape, old_revid, new_revid)
598
604
new_factory(new_shape, new_revid)
599
605
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
600
new_shape, new_revid)
606
new_shape, new_revid)
602
608
def test_content_from_second_parent_is_dropped(self):
603
609
left_revid = b'left-parent'
604
610
basis_shape = Inventory(root_id=None)
605
611
self.add_dir(basis_shape, left_revid, b'root-id', None, '')
606
612
self.add_link(basis_shape, left_revid, b'link-id', b'root-id', 'link',
608
614
# the right shape has content - file, link, subdir with a child,
609
615
# that should all be discarded by the call.
610
616
right_revid = b'right-parent'
611
617
right_shape = Inventory(root_id=None)
612
618
self.add_dir(right_shape, left_revid, b'root-id', None, '')
613
619
self.add_link(right_shape, right_revid, b'link-id', b'root-id', 'link',
615
621
self.add_dir(right_shape, right_revid, b'subdir-id', b'root-id', 'dir')
616
622
self.add_file(right_shape, right_revid, b'file-id', b'subdir-id', 'file',
618
624
new_revid = b'new-parent'
619
625
new_shape = Inventory(root_id=None)
620
626
self.add_new_root(new_shape, left_revid, new_revid)
621
627
self.add_link(new_shape, new_revid, b'link-id', b'root-id', 'link',
623
629
self.assertTransitionFromBasisToShape(basis_shape, left_revid,
624
new_shape, new_revid, right_revid)
630
new_shape, new_revid, right_revid)
626
632
def test_parent_id_changed(self):
627
633
# test that when the only change to an entry is its parent id changing
629
635
old_revid = b'old-parent'
630
636
basis_shape = Inventory(root_id=None)
631
637
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
632
self.add_dir(basis_shape, old_revid, b'orig-parent-id', b'root-id', 'dir')
633
self.add_dir(basis_shape, old_revid, b'dir-id', b'orig-parent-id', 'dir')
638
self.add_dir(basis_shape, old_revid,
639
b'orig-parent-id', b'root-id', 'dir')
640
self.add_dir(basis_shape, old_revid, b'dir-id',
641
b'orig-parent-id', 'dir')
634
642
new_revid = b'new-parent'
635
643
new_shape = Inventory(root_id=None)
636
644
self.add_new_root(new_shape, old_revid, new_revid)
637
645
self.add_dir(new_shape, new_revid, b'new-parent-id', b'root-id', 'dir')
638
646
self.add_dir(new_shape, new_revid, b'dir-id', b'new-parent-id', 'dir')
639
647
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
640
new_shape, new_revid)
648
new_shape, new_revid)
642
650
def test_name_changed(self):
643
651
# test that when the only change to an entry is its name changing that
645
653
old_revid = b'old-parent'
646
654
basis_shape = Inventory(root_id=None)
647
655
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
648
self.add_dir(basis_shape, old_revid, b'parent-id', b'root-id', 'origdir')
656
self.add_dir(basis_shape, old_revid,
657
b'parent-id', b'root-id', 'origdir')
649
658
self.add_dir(basis_shape, old_revid, b'dir-id', b'parent-id', 'olddir')
650
659
new_revid = b'new-parent'
651
660
new_shape = Inventory(root_id=None)
662
671
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
663
672
self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
664
673
self.add_dir(basis_shape, old_revid, b'dir-id-B', b'dir-id-A', 'B')
665
self.add_link(basis_shape, old_revid, b'link-id-C', b'dir-id-B', 'C', 'C')
674
self.add_link(basis_shape, old_revid,
675
b'link-id-C', b'dir-id-B', 'C', 'C')
666
676
new_revid = b'new-parent'
667
677
new_shape = Inventory(root_id=None)
668
678
self.add_new_root(new_shape, old_revid, new_revid)
669
679
self.add_dir(new_shape, new_revid, b'dir-id-B', b'root-id', 'A')
670
680
self.add_dir(new_shape, new_revid, b'dir-id-A', b'dir-id-B', 'B')
671
self.add_link(new_shape, new_revid, b'link-id-C', b'dir-id-A', 'C', 'C')
681
self.add_link(new_shape, new_revid, b'link-id-C',
682
b'dir-id-A', 'C', 'C')
672
683
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
673
new_shape, new_revid)
684
new_shape, new_revid)
675
686
def test_parent_deleted_child_renamed(self):
676
687
# test a A->None and A/B->A.
679
690
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
680
691
self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
681
692
self.add_dir(basis_shape, old_revid, b'dir-id-B', b'dir-id-A', 'B')
682
self.add_link(basis_shape, old_revid, b'link-id-C', b'dir-id-B', 'C', 'C')
693
self.add_link(basis_shape, old_revid,
694
b'link-id-C', b'dir-id-B', 'C', 'C')
683
695
new_revid = b'new-parent'
684
696
new_shape = Inventory(root_id=None)
685
697
self.add_new_root(new_shape, old_revid, new_revid)
686
698
self.add_dir(new_shape, new_revid, b'dir-id-B', b'root-id', 'A')
687
self.add_link(new_shape, old_revid, b'link-id-C', b'dir-id-B', 'C', 'C')
699
self.add_link(new_shape, old_revid, b'link-id-C',
700
b'dir-id-B', 'C', 'C')
688
701
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
689
new_shape, new_revid)
702
new_shape, new_revid)
691
704
def test_dir_to_root(self):
694
707
basis_shape = Inventory(root_id=None)
695
708
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
696
709
self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
697
self.add_link(basis_shape, old_revid, b'link-id-B', b'dir-id-A', 'B', 'B')
710
self.add_link(basis_shape, old_revid,
711
b'link-id-B', b'dir-id-A', 'B', 'B')
698
712
new_revid = b'new-parent'
699
713
new_shape = Inventory(root_id=None)
700
714
self.add_dir(new_shape, new_revid, b'dir-id-A', None, '')
701
self.add_link(new_shape, old_revid, b'link-id-B', b'dir-id-A', 'B', 'B')
715
self.add_link(new_shape, old_revid, b'link-id-B',
716
b'dir-id-A', 'B', 'B')
702
717
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
703
new_shape, new_revid)
718
new_shape, new_revid)
705
720
def test_path_swap(self):
706
721
# test a A->B and B->A path swap.
709
724
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
710
725
self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
711
726
self.add_dir(basis_shape, old_revid, b'dir-id-B', b'root-id', 'B')
712
self.add_link(basis_shape, old_revid, b'link-id-C', b'root-id', 'C', 'C')
713
self.add_link(basis_shape, old_revid, b'link-id-D', b'root-id', 'D', 'D')
727
self.add_link(basis_shape, old_revid,
728
b'link-id-C', b'root-id', 'C', 'C')
729
self.add_link(basis_shape, old_revid,
730
b'link-id-D', b'root-id', 'D', 'D')
714
731
self.add_file(basis_shape, old_revid, b'file-id-E', b'root-id', 'E',
716
733
self.add_file(basis_shape, old_revid, b'file-id-F', b'root-id', 'F',
718
735
new_revid = b'new-parent'
719
736
new_shape = Inventory(root_id=None)
720
737
self.add_new_root(new_shape, old_revid, new_revid)
723
740
self.add_link(new_shape, new_revid, b'link-id-C', b'root-id', 'D', 'C')
724
741
self.add_link(new_shape, new_revid, b'link-id-D', b'root-id', 'C', 'D')
725
742
self.add_file(new_shape, new_revid, b'file-id-E', b'root-id', 'F',
727
744
self.add_file(new_shape, new_revid, b'file-id-F', b'root-id', 'E',
729
746
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
730
new_shape, new_revid)
747
new_shape, new_revid)
732
749
def test_adds(self):
733
750
# test adding paths and dirs, including adding to a newly added dir.
741
758
self.add_dir(new_shape, new_revid, b'dir-id-A', b'root-id', 'A')
742
759
self.add_link(new_shape, new_revid, b'link-id-B', b'root-id', 'B', 'C')
743
760
self.add_file(new_shape, new_revid, b'file-id-C', b'root-id', 'C',
745
762
self.add_file(new_shape, new_revid, b'file-id-D', b'dir-id-A', 'D',
747
764
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
748
new_shape, new_revid)
765
new_shape, new_revid)
750
767
def test_removes(self):
751
768
# test removing paths, including paths that are within other also
754
771
basis_shape = Inventory(root_id=None)
755
772
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
756
773
self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
757
self.add_link(basis_shape, old_revid, b'link-id-B', b'root-id', 'B', 'C')
774
self.add_link(basis_shape, old_revid,
775
b'link-id-B', b'root-id', 'B', 'C')
758
776
self.add_file(basis_shape, old_revid, b'file-id-C', b'root-id', 'C',
760
778
self.add_file(basis_shape, old_revid, b'file-id-D', b'dir-id-A', 'D',
762
780
new_revid = b'new-parent'
763
781
new_shape = Inventory(root_id=None)
764
782
self.add_new_root(new_shape, old_revid, new_revid)
765
783
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
766
new_shape, new_revid)
784
new_shape, new_revid)
768
786
def test_move_to_added_dir(self):
769
787
old_revid = b'old-parent'
770
788
basis_shape = Inventory(root_id=None)
771
789
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
772
self.add_link(basis_shape, old_revid, b'link-id-B', b'root-id', 'B', 'C')
790
self.add_link(basis_shape, old_revid,
791
b'link-id-B', b'root-id', 'B', 'C')
773
792
new_revid = b'new-parent'
774
793
new_shape = Inventory(root_id=None)
775
794
self.add_new_root(new_shape, old_revid, new_revid)
776
795
self.add_dir(new_shape, new_revid, b'dir-id-A', b'root-id', 'A')
777
self.add_link(new_shape, new_revid, b'link-id-B', b'dir-id-A', 'B', 'C')
796
self.add_link(new_shape, new_revid, b'link-id-B',
797
b'dir-id-A', 'B', 'C')
778
798
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
779
new_shape, new_revid)
799
new_shape, new_revid)
781
801
def test_move_from_removed_dir(self):
782
802
old_revid = b'old-parent'
783
803
basis_shape = Inventory(root_id=None)
784
804
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
785
805
self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
786
self.add_link(basis_shape, old_revid, b'link-id-B', b'dir-id-A', 'B', 'C')
806
self.add_link(basis_shape, old_revid,
807
b'link-id-B', b'dir-id-A', 'B', 'C')
787
808
new_revid = b'new-parent'
788
809
new_shape = Inventory(root_id=None)
789
810
self.add_new_root(new_shape, old_revid, new_revid)
790
811
self.add_link(new_shape, new_revid, b'link-id-B', b'root-id', 'B', 'C')
791
812
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
792
new_shape, new_revid)
813
new_shape, new_revid)
794
815
def test_move_moves_children_recursively(self):
795
816
old_revid = b'old-parent'
797
818
self.add_dir(basis_shape, old_revid, b'root-id', None, '')
798
819
self.add_dir(basis_shape, old_revid, b'dir-id-A', b'root-id', 'A')
799
820
self.add_dir(basis_shape, old_revid, b'dir-id-B', b'dir-id-A', 'B')
800
self.add_link(basis_shape, old_revid, b'link-id-C', b'dir-id-B', 'C', 'D')
821
self.add_link(basis_shape, old_revid,
822
b'link-id-C', b'dir-id-B', 'C', 'D')
801
823
new_revid = b'new-parent'
802
824
new_shape = Inventory(root_id=None)
803
825
self.add_new_root(new_shape, old_revid, new_revid)
805
827
self.add_dir(new_shape, new_revid, b'dir-id-A', b'root-id', 'B')
806
828
# unmoved children.
807
829
self.add_dir(new_shape, old_revid, b'dir-id-B', b'dir-id-A', 'B')
808
self.add_link(new_shape, old_revid, b'link-id-C', b'dir-id-B', 'C', 'D')
830
self.add_link(new_shape, old_revid, b'link-id-C',
831
b'dir-id-B', 'C', 'D')
809
832
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
810
new_shape, new_revid)
833
new_shape, new_revid)
812
835
def test_add_files_to_empty_directory(self):
813
836
old_revid = b'old-parent'
819
842
self.add_new_root(new_shape, old_revid, new_revid)
820
843
self.add_dir(new_shape, old_revid, b'dir-id-A', b'root-id', 'A')
821
844
self.add_file(new_shape, new_revid, b'file-id-B', b'dir-id-A', 'B',
823
846
self.assertTransitionFromBasisToShape(basis_shape, old_revid,
824
new_shape, new_revid, set_current_inventory=False)
847
new_shape, new_revid, set_current_inventory=False)