~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/inventory.py

  • Committer: Robert Collins
  • Date: 2007-10-03 06:37:01 UTC
  • mfrom: (2871.1.4 commit-builder)
  • mto: This revision was merged to the branch mainline in revision 2933.
  • Revision ID: robertc@robertcollins.net-20071003063701-goxzcxccmwdukl6w
Merge bzr.dev (untested).

Show diffs side-by-side

added added

removed removed

Lines of Context:
876
876
            self._byid = {}
877
877
        self.revision_id = revision_id
878
878
 
 
879
    def __repr__(self):
 
880
        return "<Inventory object at %x, contents=%r>" % (id(self), self._byid)
 
881
 
 
882
    def apply_delta(self, delta):
 
883
        """Apply a delta to this inventory.
 
884
 
 
885
        :param delta: A list of changes to apply. After all the changes are
 
886
            applied the final inventory must be internally consistent, but it
 
887
            is ok to supply changes which, if only half-applied would have an
 
888
            invalid result - such as supplying two changes which rename two
 
889
            files, 'A' and 'B' with each other : [('A', 'B', 'A-id', a_entry),
 
890
            ('B', 'A', 'B-id', b_entry)].
 
891
 
 
892
            Each change is a tuple, of the form (old_path, new_path, file_id,
 
893
            new_entry).
 
894
            
 
895
            When new_path is None, the change indicates the removal of an entry
 
896
            from the inventory and new_entry will be ignored (using None is
 
897
            appropriate). If new_path is not None, then new_entry must be an
 
898
            InventoryEntry instance, which will be incorporated into the
 
899
            inventory (and replace any existing entry with the same file id).
 
900
            
 
901
            When old_path is None, the change indicates the addition of
 
902
            a new entry to the inventory.
 
903
            
 
904
            When neither new_path nor old_path are None, the change is a
 
905
            modification to an entry, such as a rename, reparent, kind change
 
906
            etc. 
 
907
 
 
908
            The children attribute of new_entry is ignored. This is because
 
909
            this method preserves children automatically across alterations to
 
910
            the parent of the children, and cases where the parent id of a
 
911
            child is changing require the child to be passed in as a separate
 
912
            change regardless. E.g. in the recursive deletion of a directory -
 
913
            the directory's children must be included in the delta, or the
 
914
            final inventory will be invalid.
 
915
        """
 
916
        children = {}
 
917
        # Remove all affected items which were in the original inventory,
 
918
        # starting with the longest paths, thus ensuring parents are examined
 
919
        # after their children, which means that everything we examine has no
 
920
        # modified children remaining by the time we examine it.
 
921
        for old_path, file_id in sorted(((op, f) for op, np, f, e in delta
 
922
                                        if op is not None), reverse=True):
 
923
            if file_id not in self:
 
924
                # adds come later
 
925
                continue
 
926
            # Preserve unaltered children of file_id for later reinsertion.
 
927
            children[file_id] = getattr(self[file_id], 'children', {})
 
928
            # Remove file_id and the unaltered children. If file_id is not
 
929
            # being deleted it will be reinserted back later.
 
930
            self.remove_recursive_id(file_id)
 
931
        # Insert all affected which should be in the new inventory, reattaching
 
932
        # their children if they had any. This is done from shortest path to
 
933
        # longest, ensuring that items which were modified and whose parents in
 
934
        # the resulting inventory were also modified, are inserted after their
 
935
        # parents.
 
936
        for new_path, new_entry in sorted((np, e) for op, np, f, e in
 
937
                                          delta if np is not None):
 
938
            if new_entry.kind == 'directory':
 
939
                new_entry.children = children.get(new_entry.file_id, {})
 
940
            self.add(new_entry)
 
941
 
879
942
    def _set_root(self, ie):
880
943
        self.root = ie
881
944
        self._byid = {self.root.file_id: self.root}