in git-server/src/main/java/jetbrains/buildServer/buildTriggers/vcs/git/GitVcsSupport.java [480:536]
private Set<VcsRootEntry> findVcsRootEntriesWithPaths(@NotNull Collection<GitMapFullPath.FullPath> paths, @NotNull Collection<VcsRootEntry> rootEntries) {
Set<VcsRootEntry> res = new HashSet<>();
Set<String> mappedPaths = new HashSet<>();
paths.forEach(p -> mappedPaths.addAll(p.getMappedPaths()));
Map<Pair<File, CheckoutRules>, Boolean> cache = new HashMap<>();
for (VcsRootEntry re: rootEntries) {
VcsRoot root = re.getVcsRoot();
CheckoutRules checkoutRules = re.getCheckoutRules();
if (checkoutRules.map(mappedPaths).isEmpty()) continue;
OperationContext context = createContext(root, "repositoryContainsPath");
try {
final GitVcsRoot gitRoot = context.getGitRoot();
final File cloneDir = gitRoot.getRepositoryDir();
// group paths with the same revisions because most likely for all of them the operation can be performed only once
Map<Pair<String, String>, List<GitMapFullPath.FullPath>> pathsGroupedByRevisions = new HashMap<>();
for (GitMapFullPath.FullPath path: paths) {
pathsGroupedByRevisions.computeIfAbsent(Pair.create(path.getRevision(), path.getHintRevision()), k -> new ArrayList<>()).add(path);
}
boolean pathsApplicable = cache.computeIfAbsent(Pair.create(cloneDir, checkoutRules), key -> {
try {
for (Map.Entry<Pair<String, String>, List<GitMapFullPath.FullPath>> e: pathsGroupedByRevisions.entrySet()) {
for (GitMapFullPath.FullPath path: e.getValue()) {
if (checkoutRules.map(path.getMappedPaths()).isEmpty()) continue;
final GitMapFullPath.RevisionCheckResult result = myMapFullPath.repositoryContainsPath(context, gitRoot, path);
if (result == GitMapFullPath.RevisionCheckResult.CONTAINS_PATH) return true;
if (result == GitMapFullPath.RevisionCheckResult.DOES_NOT_CONTAIN_REVISION) {
// seems the path has revisions and revisions check returned false
// as we grouped all the paths with the same revisions together there is no need to check other paths in the same group
break;
}
}
}
} catch (VcsException e) {
LOG.warnAndDebugDetails("Error while checking suitability for root " + LogUtil.describe(root) + ", assume root is not suitable", e);
}
return false;
});
if (pathsApplicable) {
res.add(re);
}
} catch (VcsException e) {
LOG.warnAndDebugDetails("Error while checking suitability for root " + LogUtil.describe(root) + ", assume root is not suitable", e);
} finally {
context.close();
}
}
return res;
}