private @NotNull List<TimedVcsCommit> getCommitsMatchingFilter(@NotNull VirtualFile root, @NotNull VcsLogFilterCollection filterCollection,
                                                                 @Nullable VcsLogRangeFilter.RefRange range,
                                                                 @NotNull PermanentGraph.Options options,
                                                                 int maxCount) throws VcsException {

    GitRepository repository = getRepository(root);
    if (repository == null) {
      return Collections.emptyList();
    }

    List<String> configParameters = new ArrayList<>();
    List<String> filterParameters = new ArrayList<>();

    List<String> branchLikeFilterParameters = getBranchLikeFilterParameters(repository, filterCollection, range);
    if (branchLikeFilterParameters.isEmpty()) {
      return Collections.emptyList(); // no such branches in this repository => filter matches nothing
    }
    filterParameters.addAll(branchLikeFilterParameters);

    VcsLogDateFilter dateFilter = filterCollection.get(DATE_FILTER);
    if (dateFilter != null) {
      // assuming there is only one date filter, until filter expressions are defined
      if (dateFilter.getAfter() != null) {
        filterParameters.add(prepareParameter("after", dateFilter.getAfter().toString()));
      }
      if (dateFilter.getBefore() != null) {
        filterParameters.add(prepareParameter("before", dateFilter.getBefore().toString()));
      }
    }

    VcsLogTextFilter textFilter = filterCollection.get(TEXT_FILTER);
    String text = textFilter != null ? textFilter.getText() : null;
    boolean regexp = textFilter == null || textFilter.isRegex();
    boolean caseSensitive = textFilter != null && textFilter.matchesCase();
    appendTextFilterParameters(text, regexp, caseSensitive, filterParameters);

    VcsLogUserFilter userFilter = filterCollection.get(USER_FILTER);
    if (userFilter != null) {
      Collection<String> names = ContainerUtil.map(userFilter.getUsers(root), VcsUserUtil::toExactString);
      if (regexp) {
        List<String> authors = ContainerUtil.map(names, UserNameRegex.EXTENDED_INSTANCE);
        if (GitVersionSpecialty.LOG_AUTHOR_FILTER_SUPPORTS_VERTICAL_BAR.existsIn(myProject)) {
          filterParameters.add(prepareParameter("author", StringUtil.join(authors, "|")));
        }
        else {
          filterParameters.addAll(ContainerUtil.map(authors, a -> prepareParameter("author", a)));
        }
      }
      else {
        filterParameters.addAll(ContainerUtil.map(names, a -> prepareParameter("author", StringUtil.escapeBackSlashes(a))));
      }
      configParameters.add("log.mailmap=false");
    }

    if (!CommitCountStageKt.isAll(maxCount)) {
      filterParameters.add(prepareParameter("max-count", String.valueOf(maxCount)));
    }

    if (options.equals(PermanentGraph.Options.FirstParent.INSTANCE)) {
      filterParameters.add("--first-parent");
    }

    VcsLogParentFilter parentFilter = filterCollection.get(PARENT_FILTER);
    if (parentFilter != null && !VcsLogParentFilterImplKt.getMatchesAll(parentFilter)) {
      if (VcsLogParentFilterImplKt.getHasLowerBound(parentFilter)) filterParameters.add("--min-parents=" + parentFilter.getMinParents());
      if (VcsLogParentFilterImplKt.getHasUpperBound(parentFilter)) filterParameters.add("--max-parents=" + parentFilter.getMaxParents());
    }

    // note: structure filter must be the last parameter, because it uses "--" which separates parameters from paths
    VcsLogStructureFilter structureFilter = filterCollection.get(STRUCTURE_FILTER);
    if (structureFilter != null) {
      Collection<FilePath> files = structureFilter.getFiles();
      if (!files.isEmpty()) {
        filterParameters.add("--full-history");
        filterParameters.add("--simplify-merges");
        filterParameters.add("--");
        for (FilePath file : files) {
          filterParameters.add(VcsFileUtil.relativePath(root, file));
        }
      }
    }

    List<TimedVcsCommit> commits = new ArrayList<>();
    GitLogUtil.readTimedCommits(myProject, root, configParameters, filterParameters, null, null, new CollectConsumer<>(commits));
    return commits;
  }
private @NotNull List<TimedVcsCommit> getCommitsMatchingFilter(@NotNull VirtualFile root, @NotNull VcsLogFilterCollection filterCollection,
                                                                 @Nullable VcsLogRangeFilter.RefRange range,
                                                                 @NotNull PermanentGraph.Options options,
                                                                 int maxCount)