903
907
self.create_symlink(target, trans_id)
910
def _affected_ids(self):
911
"""Return the set of transform ids affected by the transform"""
912
trans_ids = set(self._removed_id)
913
trans_ids.update(self._new_id.keys())
914
trans_ids.update(self._removed_contents)
915
trans_ids.update(self._new_contents.keys())
916
trans_ids.update(self._new_executability.keys())
917
trans_ids.update(self._new_name.keys())
918
trans_ids.update(self._new_parent.keys())
921
def _get_file_id_maps(self):
922
"""Return mapping of file_ids to trans_ids in the to and from states"""
923
trans_ids = self._affected_ids()
926
# Build up two dicts: trans_ids associated with file ids in the
927
# FROM state, vs the TO state.
928
for trans_id in trans_ids:
929
from_file_id = self.tree_file_id(trans_id)
930
if from_file_id is not None:
931
from_trans_ids[from_file_id] = trans_id
932
to_file_id = self.final_file_id(trans_id)
933
if to_file_id is not None:
934
to_trans_ids[to_file_id] = trans_id
935
return from_trans_ids, to_trans_ids
937
def _from_file_data(self, from_trans_id, from_versioned, file_id):
938
"""Get data about a file in the from (tree) state
940
Return a (name, parent, kind, executable) tuple
942
from_path = self._tree_id_paths.get(from_trans_id)
944
# get data from working tree if versioned
945
from_entry = self._tree.inventory[file_id]
946
from_name = from_entry.name
947
from_parent = from_entry.parent_id
950
if from_path is None:
951
# File does not exist in FROM state
955
# File exists, but is not versioned. Have to use path-
957
from_name = os.path.basename(from_path)
958
tree_parent = self.get_tree_parent(from_trans_id)
959
from_parent = self.tree_file_id(tree_parent)
960
if from_path is not None:
961
from_kind, from_executable, from_stats = \
962
self._tree._comparison_data(from_entry, from_path)
965
from_executable = False
966
return from_name, from_parent, from_kind, from_executable
968
def _to_file_data(self, to_trans_id, from_trans_id, from_executable):
969
"""Get data about a file in the to (target) state
971
Return a (name, parent, kind, executable) tuple
973
to_name = self.final_name(to_trans_id)
975
to_kind = self.final_kind(to_trans_id)
978
to_parent = self.final_file_id(self.final_parent(to_trans_id))
979
if to_trans_id in self._new_executability:
980
to_executable = self._new_executability[to_trans_id]
981
elif to_trans_id == from_trans_id:
982
to_executable = from_executable
984
to_executable = False
985
return to_name, to_parent, to_kind, to_executable
987
def _iter_changes(self):
988
"""Produce output in the same format as Tree._iter_changes.
990
Will produce nonsensical results if invoked while inventory/filesystem
991
conflicts (as reported by TreeTransform.find_conflicts()) are present.
993
This reads the Transform, but only reproduces changes involving a
994
file_id. Files that are not versioned in either of the FROM or TO
995
states are not reflected.
997
final_paths = FinalPaths(self)
998
from_trans_ids, to_trans_ids = self._get_file_id_maps()
1000
# Now iterate through all active file_ids
1001
for file_id in set(from_trans_ids.keys() + to_trans_ids.keys()):
1003
from_trans_id = from_trans_ids.get(file_id)
1004
# find file ids, and determine versioning state
1005
if from_trans_id is None:
1006
from_versioned = False
1007
from_trans_id = to_trans_ids[file_id]
1009
from_versioned = True
1010
to_trans_id = to_trans_ids.get(file_id)
1011
if to_trans_id is None:
1012
to_versioned = False
1013
to_trans_id = from_trans_id
1017
from_name, from_parent, from_kind, from_executable = \
1018
self._from_file_data(from_trans_id, from_versioned, file_id)
1020
to_name, to_parent, to_kind, to_executable = \
1021
self._to_file_data(to_trans_id, from_trans_id, from_executable)
1023
to_path = final_paths.get_path(to_trans_id)
1024
if from_kind != to_kind:
1026
elif to_kind in ('file' or 'symlink') and (
1027
to_trans_id != from_trans_id or
1028
to_trans_id in self._new_contents):
1030
if (not modified and from_versioned == to_versioned and
1031
from_parent==to_parent and from_name == to_name and
1032
from_executable == to_executable):
1034
results.append((file_id, to_path, modified,
1035
(from_versioned, to_versioned),
1036
(from_parent, to_parent),
1037
(from_name, to_name),
1038
(from_kind, to_kind),
1039
(from_executable, to_executable)))
1040
return iter(sorted(results, key=lambda x:x[1]))
906
1043
def joinpath(parent, child):
907
1044
"""Join tree-relative paths, handling the tree root specially"""
908
1045
if parent is None or parent == "":
1231
1371
return conflicts
1234
def _alter_files(working_tree, target_tree, tt, pb, interesting_ids, backups,
1236
from bzrlib import delta
1374
def _alter_files(working_tree, target_tree, tt, pb, interesting_ids,
1237
1376
merge_modified = working_tree.merge_modified()
1238
change_list = list(target_tree._iter_changes(working_tree,
1239
specific_file_ids=interesting_ids, pb=pb))
1377
change_list = target_tree._iter_changes(working_tree,
1378
specific_file_ids=interesting_ids, pb=pb)
1240
1379
if target_tree.inventory.root is None:
1241
1380
skip_root = True
1243
1382
skip_root = False
1244
1383
basis_tree = None
1247
change_reporter = delta.ChangeReporter(working_tree.inventory)
1248
delta.report_changes(change_list, change_reporter)
1249
1385
for id_num, (file_id, path, changed_content, versioned, parent, name,
1250
1386
kind, executable) in enumerate(change_list):
1251
1387
if skip_root and file_id[0] is not None and parent[0] is None: