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