538
538
self.warning("ignoring delete of %s as not in parent inventories", path)
541
class InventoryCommitHandler(GenericCommitHandler):
542
"""A CommitHandler that builds and saves Inventory objects."""
544
def pre_process_files(self):
545
super(InventoryCommitHandler, self).pre_process_files()
547
# Seed the inventory from the previous one. Note that
548
# the parent class version of pre_process_files() has
549
# already set the right basis_inventory for this branch
550
# but we need to copy it in order to mutate it safely
551
# without corrupting the cached inventory value.
552
if len(self.parents) == 0:
553
self.inventory = self.basis_inventory
555
self.inventory = copy_inventory(self.basis_inventory)
556
self.inventory_root = self.inventory.root
558
# directory-path -> inventory-entry for current inventory
559
self.directory_entries = dict(self.inventory.directories())
561
# Initialise the inventory revision info as required
562
if self.rev_store.expects_rich_root():
563
self.inventory.revision_id = self.revision_id
565
# In this revision store, root entries have no knit or weave.
566
# When serializing out to disk and back in, root.revision is
567
# always the new revision_id.
568
self.inventory.root.revision = self.revision_id
570
def post_process_files(self):
571
"""Save the revision."""
572
self.cache_mgr.inventories[self.revision_id] = self.inventory
573
self.rev_store.load(self.revision, self.inventory, None,
574
lambda file_id: self._get_data(file_id),
575
lambda file_id: self._get_per_file_parents(file_id),
576
lambda revision_ids: self._get_inventories(revision_ids))
578
def record_new(self, path, ie):
580
# If this is a merge, the file was most likely added already.
581
# The per-file parent(s) must therefore be calculated and
582
# we can't assume there are none.
583
per_file_parents, ie.revision = \
584
self.rev_store.get_parents_and_revision_for_entry(ie)
585
self.per_file_parents_for_commit[ie.file_id] = per_file_parents
586
self.inventory.add(ie)
587
except errors.DuplicateFileId:
588
# Directory already exists as a file or symlink
589
del self.inventory[ie.file_id]
591
self.inventory.add(ie)
593
def record_changed(self, path, ie, parent_id):
594
# HACK: no API for this (del+add does more than it needs to)
595
per_file_parents, ie.revision = \
596
self.rev_store.get_parents_and_revision_for_entry(ie)
597
self.per_file_parents_for_commit[ie.file_id] = per_file_parents
598
self.inventory._byid[ie.file_id] = ie
599
parent_ie = self.inventory._byid[parent_id]
600
parent_ie.children[ie.name] = ie
602
def record_delete(self, path, ie):
603
self.inventory.remove_recursive_id(ie.file_id)
605
def record_rename(self, old_path, new_path, file_id, ie):
606
# For a rename, the revision-id is always the new one so
607
# no need to change/set it here
608
ie.revision = self.revision_id
609
per_file_parents, _ = \
610
self.rev_store.get_parents_and_revision_for_entry(ie)
611
self.per_file_parents_for_commit[file_id] = per_file_parents
612
new_basename, new_parent_id = self._ensure_directory(new_path,
614
self.inventory.rename(file_id, new_parent_id, new_basename)
616
def modify_handler(self, filecmd):
617
if filecmd.dataref is not None:
618
data = self.cache_mgr.fetch_blob(filecmd.dataref)
621
self.debug("modifying %s", filecmd.path)
622
(kind, is_executable) = mode_to_kind(filecmd.mode)
623
self._modify_item(self._decode_path(filecmd.path), kind,
624
is_executable, data, self.inventory)
626
def delete_handler(self, filecmd):
627
self.debug("deleting %s", filecmd.path)
628
self._delete_item(self._decode_path(filecmd.path), self.inventory)
630
def copy_handler(self, filecmd):
631
src_path = self._decode_path(filecmd.src_path)
632
dest_path = self._decode_path(filecmd.dest_path)
633
self.debug("copying %s to %s", src_path, dest_path)
634
self._copy_item(src_path, dest_path, self.inventory)
636
def rename_handler(self, filecmd):
637
old_path = self._decode_path(filecmd.old_path)
638
new_path = self._decode_path(filecmd.new_path)
639
self.debug("renaming %s to %s", old_path, new_path)
640
self._rename_item(old_path, new_path, self.inventory)
642
def deleteall_handler(self, filecmd):
643
self.debug("deleting all files (and also all directories)")
644
self._delete_all_items(self.inventory)
647
541
class InventoryDeltaCommitHandler(GenericCommitHandler):
648
542
"""A CommitHandler that builds Inventories by applying a delta."""