554
554
def added(self, tree, file_id):
555
555
path, entry = self.get_path_entry(tree, file_id)
556
return (file_id, (None, path), True, (False, True), (None, entry.parent_id),
557
(None, entry.name), (None, entry.kind),
558
(None, entry.executable))
557
file_id, (None, path), True, (False, True), (None, entry.parent_id),
558
(None, entry.name), (None, entry.kind),
559
(None, entry.executable))
561
562
def get_path_entry(tree, file_id):
570
571
def content_changed(self, tree, file_id):
571
572
path, entry = self.get_path_entry(tree, file_id)
572
return (file_id, (path, path), True, (True, True),
573
(entry.parent_id, entry.parent_id),
574
(entry.name, entry.name), (entry.kind, entry.kind),
575
(entry.executable, entry.executable))
574
file_id, (path, path), True, (True, True),
575
(entry.parent_id, entry.parent_id),
576
(entry.name, entry.name), (entry.kind, entry.kind),
577
(entry.executable, entry.executable))
577
579
def kind_changed(self, from_tree, to_tree, file_id):
578
580
from_path, old_entry = self.get_path_entry(from_tree, file_id)
579
581
path, new_entry = self.get_path_entry(to_tree, file_id)
580
return (file_id, (from_path, path), True, (True, True),
581
(old_entry.parent_id, new_entry.parent_id),
582
(old_entry.name, new_entry.name),
583
(old_entry.kind, new_entry.kind),
584
(old_entry.executable, new_entry.executable))
583
file_id, (from_path, path), True, (True, True),
584
(old_entry.parent_id, new_entry.parent_id),
585
(old_entry.name, new_entry.name),
586
(old_entry.kind, new_entry.kind),
587
(old_entry.executable, new_entry.executable))
586
589
def missing(self, file_id, from_path, to_path, parent_id, kind):
587
590
_, from_basename = os.path.split(from_path)
588
591
_, to_basename = os.path.split(to_path)
589
592
# missing files have both paths, but no kind.
590
return (file_id, (from_path, to_path), True, (True, True),
591
(parent_id, parent_id),
592
(from_basename, to_basename), (kind, None), (False, False))
594
file_id, (from_path, to_path), True, (True, True),
595
(parent_id, parent_id),
596
(from_basename, to_basename), (kind, None), (False, False))
594
598
def deleted(self, tree, file_id):
595
599
entry = tree.root_inventory.get_entry(file_id)
596
600
path = tree.id2path(file_id)
597
return (file_id, (path, None), True, (True, False), (entry.parent_id, None),
598
(entry.name, None), (entry.kind, None),
599
(entry.executable, None))
602
file_id, (path, None), True, (True, False), (entry.parent_id, None),
603
(entry.name, None), (entry.kind, None),
604
(entry.executable, None))
601
606
def renamed(self, from_tree, to_tree, file_id, content_changed):
602
607
from_path, from_entry = self.get_path_entry(from_tree, file_id)
603
608
to_path, to_entry = self.get_path_entry(to_tree, file_id)
604
return (file_id, (from_path, to_path), content_changed, (True, True),
605
(from_entry.parent_id, to_entry.parent_id),
606
(from_entry.name, to_entry.name),
607
(from_entry.kind, to_entry.kind),
608
(from_entry.executable, to_entry.executable))
610
file_id, (from_path, to_path), content_changed, (True, True),
611
(from_entry.parent_id, to_entry.parent_id),
612
(from_entry.name, to_entry.name),
613
(from_entry.kind, to_entry.kind),
614
(from_entry.executable, to_entry.executable))
610
616
def unchanged(self, tree, file_id):
611
617
path, entry = self.get_path_entry(tree, file_id)
613
619
name = entry.name
614
620
kind = entry.kind
615
621
executable = entry.executable
616
return (file_id, (path, path), False, (True, True),
617
(parent, parent), (name, name), (kind, kind),
618
(executable, executable))
623
file_id, (path, path), False, (True, True),
624
(parent, parent), (name, name), (kind, kind),
625
(executable, executable))
620
627
def unversioned(self, tree, path):
621
628
"""Create an unversioned result."""
622
629
_, basename = os.path.split(path)
623
630
kind = tree._comparison_data(None, path)[0]
624
return (None, (None, path), True, (False, False), (None, None),
625
(None, basename), (None, kind),
632
None, (None, path), True, (False, False), (None, None),
633
(None, basename), (None, kind),
628
636
def sorted(self, changes):
629
637
return sorted(changes, key=_change_key)
1086
1094
tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1087
1095
self.not_applicable_if_missing_in('file', tree1)
1088
1096
root_id = tree1.path2id('')
1089
expected = [(b'file-id', ('file', None), False, (True, False),
1090
(root_id, None), ('file', None), (None, None), (False, None))]
1098
TreeChange(b'file-id', ('file', None), False, (True, False),
1099
(root_id, None), ('file', None), (None, None), (False, None))]
1091
1100
self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
1093
1102
def test_only_in_target_and_missing(self):
1100
1109
tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1101
1110
self.not_applicable_if_missing_in('file', tree2)
1102
1111
root_id = tree1.path2id('')
1103
expected = [(b'file-id', (None, 'file'), False, (False, True),
1104
(None, root_id), (None, 'file'), (None, None), (None, False))]
1113
TreeChange(b'file-id', (None, 'file'), False, (False, True),
1114
(None, root_id), (None, 'file'), (None, None), (None, False))]
1105
1115
self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
1107
1117
def test_only_in_target_missing_subtree_specific_bug_367632(self):
1116
1126
self.not_applicable_if_missing_in('a-dir', tree2)
1117
1127
root_id = tree1.path2id('')
1119
(b'dir-id', (None, 'a-dir'), False, (False, True),
1120
(None, root_id), (None, 'a-dir'), (None, None), (None, False)),
1121
(b'file-id', (None, 'a-dir/a-file'), False, (False, True),
1122
(None, b'dir-id'), (None, 'a-file'), (None, None), (None, False))
1130
b'dir-id', (None, 'a-dir'), False, (False, True),
1131
(None, root_id), (None, 'a-dir'), (None, None), (None, False)),
1133
b'file-id', (None, 'a-dir/a-file'), False, (False, True),
1134
(None, b'dir-id'), (None, 'a-file'), (None, None), (None, False))
1124
1136
# bug 367632 showed that specifying the root broke some code paths,
1125
1137
# so we check this contract with and without it.
1136
1148
tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1137
1149
self.assertEqual(sorted([self.unchanged(tree1, b'root-id'),
1138
1150
self.unchanged(tree1, b'b-id'),
1139
(b'a-id', ('a', 'd'), True, (True, True),
1140
(b'root-id', b'root-id'), ('a',
1141
'd'), ('file', 'file'),
1142
(False, False)), self.unchanged(tree1, b'c-id')]),
1152
b'a-id', ('a', 'd'), True, (True, True),
1153
(b'root-id', b'root-id'), ('a', 'd'),
1155
(False, False)), self.unchanged(tree1, b'c-id')]),
1143
1156
self.do_iter_changes(tree1, tree2, include_unchanged=True))
1145
1158
def test_compare_subtrees(self):