def _apply_changes()

in src/buildstream/storage/_casbaseddirectory.py [0:0]


    def _apply_changes(self, dir_a: "CasBasedDirectory", dir_b: "CasBasedDirectory") -> None:
        # If the digests are the same, the directories are the same
        # (child properties affect the digest). We can skip any work
        # in such a case.
        if dir_a._get_digest() == dir_b._get_digest():
            return

        def get_subdir(entry: _IndexEntry, directory: CasBasedDirectory) -> CasBasedDirectory:
            return directory.__index[entry.name].get_directory(directory)

        def is_dir_in(entry: _IndexEntry, directory: CasBasedDirectory) -> bool:
            return directory.__index[entry.name].type == FileType.DIRECTORY

        # We first check which files were added, and add them to our
        # directory.
        for entry in dir_b.__index.values():
            if self.__contains_entry(entry):
                # We can short-circuit checking entries from b that
                # already exist in our index.
                continue

            if not dir_a.__contains_entry(entry):
                if entry.name in self.__index and is_dir_in(entry, self) and is_dir_in(entry, dir_b):
                    # If the entry changed, and is a directory in both
                    # the current and to-merge-into tree, we need to
                    # merge recursively.

                    # If the entry is not a directory in dir_a, we
                    # want to overwrite the file, but we need an empty
                    # directory for recursion.
                    if entry.name in dir_a.__index and is_dir_in(entry, dir_a):
                        sub_a = get_subdir(entry, dir_a)
                    else:
                        sub_a = CasBasedDirectory(dir_a.__cas_cache)

                    subdir = get_subdir(entry, self)
                    subdir._apply_changes(sub_a, get_subdir(entry, dir_b))
                else:
                    # In any other case, we just add/overwrite the file/directory
                    self.__add_entry(entry)

        # We can't iterate and remove entries at the same time
        to_remove = [entry for entry in dir_a.__index.values() if entry.name not in dir_b.__index]
        for entry in to_remove:
            self.remove(entry.name, recursive=True)

        self.__invalidate_digest()