162
162
def adjust_path(self, name, parent, trans_id):
163
163
"""Change the path that is assigned to a transaction id."""
165
raise ValueError("Parent trans-id may not be None")
164
166
if trans_id == self._new_root:
165
167
raise CantMoveRoot
166
168
self._new_name[trans_id] = name
167
169
self._new_parent[trans_id] = parent
168
if parent == ROOT_PARENT:
169
if self._new_root is not None:
170
raise ValueError("Cannot have multiple roots.")
171
self._new_root = trans_id
173
171
def adjust_root_path(self, name, parent):
174
172
"""Emulate moving the root by moving all children, instead.
202
200
self.version_file(old_root_file_id, old_root)
203
201
self.unversion_file(self._new_root)
203
def fixup_new_roots(self):
204
"""Reinterpret requests to change the root directory
206
Instead of creating a root directory, or moving an existing directory,
207
all the attributes and children of the new root are applied to the
208
existing root directory.
210
This means that the old root trans-id becomes obsolete, so it is
211
recommended only to invoke this after the root trans-id has become
214
new_roots = [k for k, v in self._new_parent.iteritems() if v is
216
if len(new_roots) < 1:
218
if len(new_roots) != 1:
219
raise ValueError('A tree cannot have two roots!')
220
if self._new_root is None:
221
self._new_root = new_roots[0]
223
old_new_root = new_roots[0]
224
# TODO: What to do if a old_new_root is present, but self._new_root is
225
# not listed as being removed? This code explicitly unversions
226
# the old root and versions it with the new file_id. Though that
227
# seems like an incomplete delta
229
# unversion the new root's directory.
230
file_id = self.final_file_id(old_new_root)
231
if old_new_root in self._new_id:
232
self.cancel_versioning(old_new_root)
234
self.unversion_file(old_new_root)
235
# if, at this stage, root still has an old file_id, zap it so we can
236
# stick a new one in.
237
if (self.tree_file_id(self._new_root) is not None and
238
self._new_root not in self._removed_id):
239
self.unversion_file(self._new_root)
240
self.version_file(file_id, self._new_root)
242
# Now move children of new root into old root directory.
243
# Ensure all children are registered with the transaction, but don't
244
# use directly-- some tree children have new parents
245
list(self.iter_tree_children(old_new_root))
246
# Move all children of new root into old root directory.
247
for child in self.by_parent().get(old_new_root, []):
248
self.adjust_path(self.final_name(child), self._new_root, child)
250
# Ensure old_new_root has no directory.
251
if old_new_root in self._new_contents:
252
self.cancel_creation(old_new_root)
254
self.delete_contents(old_new_root)
256
# prevent deletion of root directory.
257
if self._new_root in self._removed_contents:
258
self.cancel_deletion(self._new_root)
260
# destroy path info for old_new_root.
261
del self._new_parent[old_new_root]
262
del self._new_name[old_new_root]
205
264
def trans_id_tree_file_id(self, inventory_id):
206
265
"""Determine the transaction id of a working tree file.
1075
1136
if (trans_id in self._limbo_files and
1076
1137
trans_id not in self._needs_rename):
1077
1138
self._rename_in_limbo([trans_id])
1078
self._limbo_children[previous_parent].remove(trans_id)
1079
del self._limbo_children_names[previous_parent][previous_name]
1139
if previous_parent != parent:
1140
self._limbo_children[previous_parent].remove(trans_id)
1141
if previous_parent != parent or previous_name != name:
1142
del self._limbo_children_names[previous_parent][previous_name]
1081
1144
def _rename_in_limbo(self, trans_ids):
1082
1145
"""Fix limbo names so that the right final path is produced.
1542
1605
child_pb.update('removing file', num, len(tree_paths))
1543
1606
full_path = self._tree.abspath(path)
1544
1607
if trans_id in self._removed_contents:
1545
mover.pre_delete(full_path, os.path.join(self._deletiondir,
1547
elif trans_id in self._new_name or trans_id in \
1608
delete_path = os.path.join(self._deletiondir, trans_id)
1609
mover.pre_delete(full_path, delete_path)
1610
elif (trans_id in self._new_name
1611
or trans_id in self._new_parent):
1550
1613
mover.rename(full_path, self._limbo_name(trans_id))
1551
1614
except OSError, e:
2636
2699
parent_trans = ROOT_PARENT
2638
2701
parent_trans = tt.trans_id_file_id(parent[1])
2639
tt.adjust_path(name[1], parent_trans, trans_id)
2702
if parent[0] is None and versioned[0]:
2703
tt.adjust_root_path(name[1], parent_trans)
2705
tt.adjust_path(name[1], parent_trans, trans_id)
2640
2706
if executable[0] != executable[1] and kind[1] == "file":
2641
2707
tt.set_executability(executable[1], trans_id)
2642
2708
if working_tree.supports_content_filtering():