@ApiStatus.Internal
  public static @NotNull Map<VirtualFile, RootDirtySet> collectDirtyPathsPerRoot(
    @NotNull GitVcsDirtyScope dirtyScope,
    @NotNull Map<GitRepository, GitSubmodule> knownSubmodules
  ) {
    Project project = dirtyScope.getProject();
    Map<VirtualFile, RootDirtySet> dirtySetPerRoot = new HashMap<>(dirtyScope.getDirtySetsPerRoot());

    // Git will not detect renames unless both affected paths are passed to the 'git status' command.
    // Thus, we are forced to pass all deleted/added files in a repository to ensure all renames are detected.
    for (VirtualFile root : dirtySetPerRoot.keySet()) {
      RootDirtySet rootPaths = dirtySetPerRoot.get(root);
      if (rootPaths.isEverythingDirty()) continue;

      GitRepository gitRepository = GitRepositoryManager.getInstance(project).getRepositoryForRoot(root);
      if (gitRepository == null) continue;

      List<GitFileStatus> records = gitRepository.getStagingAreaHolder().getAllRecords();
      for (GitFileStatus record : records) {
        FilePath filePath = record.getPath();
        FilePath origPath = record.getOrigPath();
        if (origPath != null) {
          rootPaths.markDirty(origPath);
          rootPaths.markDirty(filePath);
        }
        else if (isStatusCodeForPotentialRename(record.getIndex()) ||
                 isStatusCodeForPotentialRename(record.getWorkTree())) {
          rootPaths.markDirty(filePath);
        }
      }
    }

    // Make sure submodule status in parent repository is being properly reported,
    // as 'dirtyScope.belongsTo' will return true for its Change (and it will be removed from ChangeListWorker).
    for (GitSubmodule submodule : knownSubmodules.values()) {
      VirtualFile submoduleRoot = submodule.getRepository().getRoot();
      VirtualFile parentRoot = submodule.getParent().getRoot();

      RootDirtySet dirtySet = dirtySetPerRoot.get(submoduleRoot);
      if (dirtySet != null && dirtySet.isEverythingDirty()) { // faster check for 'dirtySet.belongsTo(submoduleRoot)'
        RootDirtySet rootPaths = dirtySetPerRoot.computeIfAbsent(parentRoot,
                                                                 root -> GitVcsDirtyScope.createDirtySetForRoot(root));
        rootPaths.markDirty(VcsUtil.getFilePath(submoduleRoot));
      }
    }

    return dirtySetPerRoot;
  }
@ApiStatus.Internal
  public static @NotNull Map<VirtualFile, RootDirtySet> collectDirtyPathsPerRoot(
    @NotNull GitVcsDirtyScope dirtyScope,
    @NotNull Map<GitRepository, GitSubmodule> knownSubmodules
  )