736
736
# make it raise to trap naughty direct users.
737
737
raise NotImplementedError(self._iter_inventory_xmls)
739
def _find_revision_outside_set(self, revision_ids):
740
revision_set = frozenset(revision_ids)
741
for revid in revision_ids:
742
parent_ids = self.get_parent_map([revid]).get(revid, ())
743
for parent in parent_ids:
744
if parent in revision_set:
745
# Parent is not outside the set
747
if parent not in self.get_parent_map([parent]):
751
return _mod_revision.NULL_REVISION
739
def _find_parent_ids_of_revisions(self, revision_ids):
740
# TODO: we probably want to make this a helper that other code can get
742
parent_map = self.get_parent_map(revision_ids)
744
map(parents.update, parent_map.itervalues())
745
parents.difference_update(revision_ids)
746
parents.discard(_mod_revision.NULL_REVISION)
753
def _find_file_keys_to_fetch(self, revision_ids, pb):
754
rich_root = self.supports_rich_root()
755
revision_outside_set = self._find_revision_outside_set(revision_ids)
756
if revision_outside_set == _mod_revision.NULL_REVISION:
757
uninteresting_root_keys = set()
759
uninteresting_inv = self.get_inventory(revision_outside_set)
760
uninteresting_root_keys = set([uninteresting_inv.id_to_entry.key()])
761
interesting_root_keys = set()
762
for idx, inv in enumerate(self.iter_inventories(revision_ids)):
763
interesting_root_keys.add(inv.id_to_entry.key())
764
revision_ids = frozenset(revision_ids)
765
file_id_revisions = {}
766
bytes_to_info = inventory.CHKInventory._bytes_to_utf8name_key
767
for record, items in chk_map.iter_interesting_nodes(self.chk_bytes,
768
interesting_root_keys, uninteresting_root_keys,
770
# This is cheating a bit to use the last grabbed 'inv', but it
772
for name, bytes in items:
773
(name_utf8, file_id, revision_id) = bytes_to_info(bytes)
774
if not rich_root and name_utf8 == '':
776
if revision_id in revision_ids:
777
# Would we rather build this up into file_id => revision
780
file_id_revisions[file_id].add(revision_id)
782
file_id_revisions[file_id] = set([revision_id])
783
for file_id, revisions in file_id_revisions.iteritems():
784
yield ('file', file_id, revisions)
749
def _find_present_inventory_ids(self, revision_ids):
750
keys = [(r,) for r in revision_ids]
751
parent_map = self.inventories.get_parent_map(keys)
752
present_inventory_ids = set(k[-1] for k in parent_map)
753
return present_inventory_ids
786
755
def fileids_altered_by_revision_ids(self, revision_ids, _inv_weave=None):
787
756
"""Find the file ids and versions affected by revisions.
793
762
revision_ids. Each altered file-ids has the exact revision_ids that
794
763
altered it listed explicitly.
796
rich_roots = self.supports_rich_root()
765
rich_root = self.supports_rich_root()
766
bytes_to_info = inventory.CHKInventory._bytes_to_utf8name_key
767
file_id_revisions = {}
798
768
pb = ui.ui_factory.nested_progress_bar()
800
total = len(revision_ids)
801
# TODO: This could probably be implemented in terms of
802
# 'iter_inventory_deltas'. Since we only include items where
803
# 'entry.revision == inv.revision_id', then we know that all
804
# the entries which are identical to another inventory are
805
# *not* going to match. Note that revision_ids may be a set,
806
# so doesn't have a great iteration order.
807
for pos, inv in enumerate(self.iter_inventories(revision_ids)):
808
pb.update("Finding text references", pos, total)
809
for entry in inv.iter_just_entries():
810
if entry.revision != inv.revision_id:
812
if not rich_roots and entry.file_id == inv.root_id:
814
alterations = result.setdefault(entry.file_id, set([]))
815
alterations.add(entry.revision)
770
parent_ids = self._find_parent_ids_of_revisions(revision_ids)
771
present_parent_inv_ids = self._find_present_inventory_ids(parent_ids)
772
uninteresting_root_keys = set()
773
interesting_root_keys = set()
774
inventories_to_read = set(present_parent_inv_ids)
775
inventories_to_read.update(revision_ids)
776
for inv in self.iter_inventories(inventories_to_read):
777
entry_chk_root_key = inv.id_to_entry.key()
778
if inv.revision_id in present_parent_inv_ids:
779
uninteresting_root_keys.add(entry_chk_root_key)
781
interesting_root_keys.add(entry_chk_root_key)
783
chk_bytes = self.chk_bytes
784
for record, items in chk_map.iter_interesting_nodes(chk_bytes,
785
interesting_root_keys, uninteresting_root_keys,
787
for name, bytes in items:
788
(name_utf8, file_id, revision_id) = bytes_to_info(bytes)
789
if not rich_root and name_utf8 == '':
792
file_id_revisions[file_id].add(revision_id)
794
file_id_revisions[file_id] = set([revision_id])
797
return file_id_revisions
820
799
def find_text_key_references(self):
821
800
"""Find the text key references within the repository.