161
161
return tuple(self).__getitem__(i)
162
162
return getattr(self, self.__slots__[i])
164
def is_reparented(self):
165
return self.parent_id[0] != self.parent_id[1]
164
167
def discard_new(self):
165
168
return self.__class__(
166
169
self.file_id, (self.path[0], None), self.changed_content,
344
347
if self.supports_tree_reference():
345
348
for path, entry in self.iter_entries_by_dir():
346
349
if entry.kind == 'tree-reference':
347
yield path, entry.file_id
349
352
def kind(self, path):
350
353
raise NotImplementedError("Tree subclass %s must implement kind"
925
928
from_entries_by_dir = list(self.source.iter_entries_by_dir(
926
929
specific_files=source_specific_files))
927
from_data = dict((e.file_id, (p, e)) for p, e in from_entries_by_dir)
930
from_data = dict(from_entries_by_dir)
928
931
to_entries_by_dir = list(self.target.iter_entries_by_dir(
929
932
specific_files=target_specific_files))
933
path_equivs = find_previous_paths(
934
self.target, self.source, [p for p, e in to_entries_by_dir])
930
935
num_entries = len(from_entries_by_dir) + len(to_entries_by_dir)
932
937
# the unversioned path lookup only occurs on real trees - where there
946
951
(None, unversioned_path[0][-1]),
947
952
(None, target_kind),
948
953
(None, target_executable))
949
source_path, source_entry = from_data.get(target_entry.file_id,
951
result, changes = self._changes_from_entries(source_entry,
952
target_entry, source_path=source_path, target_path=target_path)
953
to_paths[result[0]] = result[1][1]
954
source_path = path_equivs[target_path]
955
if source_path is not None:
956
source_entry = from_data.get(source_path)
959
result, changes = self._changes_from_entries(
960
source_entry, target_entry, source_path=source_path, target_path=target_path)
961
to_paths[result.file_id] = result.path[1]
963
if result.versioned[0]:
957
965
if pb is not None:
958
966
pb.update('comparing files', entry_count, num_entries)
959
967
if changes or include_unchanged:
960
968
if specific_files is not None:
961
new_parent_id = result[4][1]
962
precise_file_ids.add(new_parent_id)
963
changed_file_ids.append(result[0])
969
precise_file_ids.add(result.parent_id[1])
970
changed_file_ids.append(result.file_id)
965
972
# Ensure correct behaviour for reparented/added specific files.
966
973
if specific_files is not None:
967
974
# Record output dirs
968
if result[6][1] == 'directory':
969
seen_dirs.add(result[0])
975
if result.kind[1] == 'directory':
976
seen_dirs.add(result.file_id)
970
977
# Record parents of reparented/added entries.
971
versioned = result[3]
973
if not versioned[0] or parents[0] != parents[1]:
974
seen_parents.add(parents[1])
978
if not result.versioned[0] or result.is_reparented():
979
seen_parents.add(result.parent_id[1])
975
980
while all_unversioned:
976
981
# yield any trailing unversioned paths
977
982
unversioned_path = all_unversioned.popleft()
1103
1108
# Get this parents parent to examine.
1104
new_parent_id = result[4][1]
1109
new_parent_id = result.parent_id[1]
1105
1110
precise_file_ids.add(new_parent_id)
1107
1112
if (result.kind[0] == 'directory' and
1163
1168
:param from_tree: From tree
1164
1169
:param to_tree: To tree
1165
:param paths: Iterable over paths to search for
1170
:param paths: Iterable over paths in from_tree to search for
1166
1171
:return: Dictionary mapping from from_tree paths to paths in to_tree, or
1167
1172
None if there is no equivalent path.
1178
1183
:param from_tree: From tree
1179
1184
:param to_tree: To tree
1180
:param path: Path to search for
1185
:param path: Path to search for (exists in from_tree)
1181
1186
:return: path in to_tree, or None if there is no equivalent path.
1187
:raise NoSuchFile: If the path doesn't exist in from_tree
1183
1189
if file_id is None:
1184
1190
file_id = from_tree.path2id(path)