919
923
self.create_symlink(target, trans_id)
926
def _affected_ids(self):
927
"""Return the set of transform ids affected by the transform"""
928
trans_ids = set(self._removed_id)
929
trans_ids.update(self._new_id.keys())
930
trans_ids.update(self._removed_contents)
931
trans_ids.update(self._new_contents.keys())
932
trans_ids.update(self._new_executability.keys())
933
trans_ids.update(self._new_name.keys())
934
trans_ids.update(self._new_parent.keys())
937
def _get_file_id_maps(self):
938
"""Return mapping of file_ids to trans_ids in the to and from states"""
939
trans_ids = self._affected_ids()
942
# Build up two dicts: trans_ids associated with file ids in the
943
# FROM state, vs the TO state.
944
for trans_id in trans_ids:
945
from_file_id = self.tree_file_id(trans_id)
946
if from_file_id is not None:
947
from_trans_ids[from_file_id] = trans_id
948
to_file_id = self.final_file_id(trans_id)
949
if to_file_id is not None:
950
to_trans_ids[to_file_id] = trans_id
951
return from_trans_ids, to_trans_ids
953
def _from_file_data(self, from_trans_id, from_versioned, file_id):
954
"""Get data about a file in the from (tree) state
956
Return a (name, parent, kind, executable) tuple
958
from_path = self._tree_id_paths.get(from_trans_id)
960
# get data from working tree if versioned
961
from_entry = self._tree.inventory[file_id]
962
from_name = from_entry.name
963
from_parent = from_entry.parent_id
966
if from_path is None:
967
# File does not exist in FROM state
971
# File exists, but is not versioned. Have to use path-
973
from_name = os.path.basename(from_path)
974
tree_parent = self.get_tree_parent(from_trans_id)
975
from_parent = self.tree_file_id(tree_parent)
976
if from_path is not None:
977
from_kind, from_executable, from_stats = \
978
self._tree._comparison_data(from_entry, from_path)
981
from_executable = False
982
return from_name, from_parent, from_kind, from_executable
984
def _to_file_data(self, to_trans_id, from_trans_id, from_executable):
985
"""Get data about a file in the to (target) state
987
Return a (name, parent, kind, executable) tuple
989
to_name = self.final_name(to_trans_id)
991
to_kind = self.final_kind(to_trans_id)
994
to_parent = self.final_file_id(self.final_parent(to_trans_id))
995
if to_trans_id in self._new_executability:
996
to_executable = self._new_executability[to_trans_id]
997
elif to_trans_id == from_trans_id:
998
to_executable = from_executable
1000
to_executable = False
1001
return to_name, to_parent, to_kind, to_executable
1003
def _iter_changes(self):
1004
"""Produce output in the same format as Tree._iter_changes.
1006
Will produce nonsensical results if invoked while inventory/filesystem
1007
conflicts (as reported by TreeTransform.find_conflicts()) are present.
1009
This reads the Transform, but only reproduces changes involving a
1010
file_id. Files that are not versioned in either of the FROM or TO
1011
states are not reflected.
1013
final_paths = FinalPaths(self)
1014
from_trans_ids, to_trans_ids = self._get_file_id_maps()
1016
# Now iterate through all active file_ids
1017
for file_id in set(from_trans_ids.keys() + to_trans_ids.keys()):
1019
from_trans_id = from_trans_ids.get(file_id)
1020
# find file ids, and determine versioning state
1021
if from_trans_id is None:
1022
from_versioned = False
1023
from_trans_id = to_trans_ids[file_id]
1025
from_versioned = True
1026
to_trans_id = to_trans_ids.get(file_id)
1027
if to_trans_id is None:
1028
to_versioned = False
1029
to_trans_id = from_trans_id
1033
from_name, from_parent, from_kind, from_executable = \
1034
self._from_file_data(from_trans_id, from_versioned, file_id)
1036
to_name, to_parent, to_kind, to_executable = \
1037
self._to_file_data(to_trans_id, from_trans_id, from_executable)
1039
to_path = final_paths.get_path(to_trans_id)
1040
if from_kind != to_kind:
1042
elif to_kind in ('file' or 'symlink') and (
1043
to_trans_id != from_trans_id or
1044
to_trans_id in self._new_contents):
1046
if (not modified and from_versioned == to_versioned and
1047
from_parent==to_parent and from_name == to_name and
1048
from_executable == to_executable):
1050
results.append((file_id, to_path, modified,
1051
(from_versioned, to_versioned),
1052
(from_parent, to_parent),
1053
(from_name, to_name),
1054
(from_kind, to_kind),
1055
(from_executable, to_executable)))
1056
return iter(sorted(results, key=lambda x:x[1]))
922
1059
def joinpath(parent, child):
923
1060
"""Join tree-relative paths, handling the tree root specially"""
924
1061
if parent is None or parent == "":
1250
1390
return conflicts
1253
def _alter_files(working_tree, target_tree, tt, pb, interesting_ids, backups,
1255
from bzrlib import delta
1393
def _alter_files(working_tree, target_tree, tt, pb, interesting_ids,
1256
1395
merge_modified = working_tree.merge_modified()
1257
change_list = list(target_tree._iter_changes(working_tree,
1258
specific_file_ids=interesting_ids, pb=pb))
1396
change_list = target_tree._iter_changes(working_tree,
1397
specific_file_ids=interesting_ids, pb=pb)
1259
1398
if target_tree.inventory.root is None:
1260
1399
skip_root = True
1262
1401
skip_root = False
1263
1402
basis_tree = None
1265
change_reporter = delta.ChangeReporter(working_tree.inventory)
1266
delta.report_changes(change_list, change_reporter)
1267
for id_num, (file_id, path, changed_content, versioned, parent, name, kind,
1268
executable) in enumerate(change_list):
1403
for id_num, (file_id, path, changed_content, versioned, parent, name,
1404
kind, executable) in enumerate(change_list):
1269
1405
if skip_root and file_id[0] is not None and parent[0] is None:
1271
1407
trans_id = tt.trans_id_file_id(file_id)