163
163
def adjust_path(self, name, parent, trans_id):
164
164
"""Change the path that is assigned to a transaction id."""
166
raise ValueError("Parent trans-id may not be None")
165
167
if trans_id == self._new_root:
166
168
raise CantMoveRoot
167
169
self._new_name[trans_id] = name
168
170
self._new_parent[trans_id] = parent
169
if parent == ROOT_PARENT:
170
if self._new_root is not None:
171
raise ValueError("Cannot have multiple roots.")
172
self._new_root = trans_id
174
172
def adjust_root_path(self, name, parent):
175
173
"""Emulate moving the root by moving all children, instead.
203
201
self.version_file(old_root_file_id, old_root)
204
202
self.unversion_file(self._new_root)
204
def fixup_new_roots(self):
205
"""Reinterpret requests to change the root directory
207
Instead of creating a root directory, or moving an existing directory,
208
all the attributes and children of the new root are applied to the
209
existing root directory.
211
This means that the old root trans-id becomes obsolete, so it is
212
recommended only to invoke this after the root trans-id has become
215
new_roots = [k for k, v in self._new_parent.iteritems() if v is
217
if len(new_roots) < 1:
219
if len(new_roots) != 1:
220
raise ValueError('A tree cannot have two roots!')
221
if self._new_root is None:
222
self._new_root = new_roots[0]
224
old_new_root = new_roots[0]
225
# TODO: What to do if a old_new_root is present, but self._new_root is
226
# not listed as being removed? This code explicitly unversions
227
# the old root and versions it with the new file_id. Though that
228
# seems like an incomplete delta
230
# unversion the new root's directory.
231
file_id = self.final_file_id(old_new_root)
232
if old_new_root in self._new_id:
233
self.cancel_versioning(old_new_root)
235
self.unversion_file(old_new_root)
236
# if, at this stage, root still has an old file_id, zap it so we can
237
# stick a new one in.
238
if (self.tree_file_id(self._new_root) is not None and
239
self._new_root not in self._removed_id):
240
self.unversion_file(self._new_root)
241
self.version_file(file_id, self._new_root)
243
# Now move children of new root into old root directory.
244
# Ensure all children are registered with the transaction, but don't
245
# use directly-- some tree children have new parents
246
list(self.iter_tree_children(old_new_root))
247
# Move all children of new root into old root directory.
248
for child in self.by_parent().get(old_new_root, []):
249
self.adjust_path(self.final_name(child), self._new_root, child)
251
# Ensure old_new_root has no directory.
252
if old_new_root in self._new_contents:
253
self.cancel_creation(old_new_root)
255
self.delete_contents(old_new_root)
257
# prevent deletion of root directory.
258
if self._new_root in self._removed_contents:
259
self.cancel_deletion(self._new_root)
261
# destroy path info for old_new_root.
262
del self._new_parent[old_new_root]
263
del self._new_name[old_new_root]
206
265
def trans_id_tree_file_id(self, inventory_id):
207
266
"""Determine the transaction id of a working tree file.
1077
1138
if (trans_id in self._limbo_files and
1078
1139
trans_id not in self._needs_rename):
1079
1140
self._rename_in_limbo([trans_id])
1080
self._limbo_children[previous_parent].remove(trans_id)
1081
del self._limbo_children_names[previous_parent][previous_name]
1141
if previous_parent != parent:
1142
self._limbo_children[previous_parent].remove(trans_id)
1143
if previous_parent != parent or previous_name != name:
1144
del self._limbo_children_names[previous_parent][previous_name]
1083
1146
def _rename_in_limbo(self, trans_ids):
1084
1147
"""Fix limbo names so that the right final path is produced.
1565
1628
child_pb.update('removing file', num, len(tree_paths))
1566
1629
full_path = self._tree.abspath(path)
1567
1630
if trans_id in self._removed_contents:
1568
mover.pre_delete(full_path, os.path.join(self._deletiondir,
1570
elif trans_id in self._new_name or trans_id in \
1631
delete_path = os.path.join(self._deletiondir, trans_id)
1632
mover.pre_delete(full_path, delete_path)
1633
elif (trans_id in self._new_name
1634
or trans_id in self._new_parent):
1573
1636
mover.rename(full_path, self._limbo_name(trans_id))
1574
1637
except OSError, e:
2662
2725
parent_trans = ROOT_PARENT
2664
2727
parent_trans = tt.trans_id_file_id(parent[1])
2665
tt.adjust_path(name[1], parent_trans, trans_id)
2728
if parent[0] is None and versioned[0]:
2729
tt.adjust_root_path(name[1], parent_trans)
2731
tt.adjust_path(name[1], parent_trans, trans_id)
2666
2732
if executable[0] != executable[1] and kind[1] == "file":
2667
2733
tt.set_executability(executable[1], trans_id)
2668
2734
if working_tree.supports_content_filtering():