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()