157
158
def apply_inventory_delta(self, changes):
158
159
"""Apply changes to the inventory as an atomic operation.
160
The argument is a set of changes to apply. It must describe a
161
valid result, but the order is not important. Specifically,
162
intermediate stages *may* be invalid, such as when two files
165
The changes should be structured as a list of tuples, of the form
166
(old_path, new_path, file_id, new_entry). For creation, old_path
167
must be None. For deletion, new_path and new_entry must be None.
168
file_id is always non-None. For renames and other mutations, all
169
values must be non-None.
171
If the new_entry is a directory, its children should be an empty
172
dict. Children are handled by apply_inventory_delta itself.
174
:param changes: A list of tuples for the change to apply:
175
[(old_path, new_path, file_id, new_inventory_entry), ...]
161
:param changes: An inventory delta to apply to the working tree's
164
:seealso Inventory.apply_delta: For details on the changes parameter.
178
167
inv = self.inventory
180
for old_path, file_id in sorted(((op, f) for op, np, f, e in changes
181
if op is not None), reverse=True):
182
if file_id not in inv:
184
children[file_id] = getattr(inv[file_id], 'children', {})
185
inv.remove_recursive_id(file_id)
186
for new_path, new_entry in sorted((np, e) for op, np, f, e in
187
changes if np is not None):
188
if getattr(new_entry, 'children', None) is not None:
189
new_entry.children = children.get(new_entry.file_id, {})
168
inv.apply_delta(changes)
191
169
self._write_inventory(inv)
193
171
@needs_write_lock
451
429
self.read_working_inventory()
452
430
return added, ignored
432
def update_to_one_parent_via_delta(self, new_revid, delta):
433
"""Update the parents of this tree after a commit.
435
This gives the tree one parent, with revision id new_revid. The
436
inventory delta is applied ot the current basis tree to generate the
437
inventory for the parent new_revid, and all other parent trees are
440
:param new_revid: The new revision id for the trees parent.
441
:param delta: An inventory delta (see apply_inventory_delta) describing
442
the changes from the current left most parent revision to new_revid.
444
# if the tree is updated by a pull to the branch, as happens in
445
# WorkingTree2, when there was no separation between branch and tree,
446
# then just clear merges, efficiency is not a concern for now as this
447
# is legacy environments only, and they are slow regardless.
448
if self.last_revision() == new_revid:
449
self.set_parent_ids([new_revid])
451
# generic implementation based on Inventory manipulation. See
452
# WorkingTree classes for optimised versions for specific format trees.
453
basis = self.basis_tree()
455
inventory = basis.inventory
457
inventory.apply_delta(delta)
458
rev_tree = RevisionTree(self.branch.repository, inventory, new_revid)
459
self.set_parent_trees([(new_revid, rev_tree)])
455
462
class _FastPath(object):
456
463
"""A path object with fast accessors for things like basename."""