in git-server/src/main/java/jetbrains/buildServer/buildTriggers/vcs/git/gitProxy/GitProxyChangesCollector.java [326:402]
private List<CommitChange> retrieveChanges(@NotNull GitApiClient<GitRepoApi> client, @NotNull LinkedHashSet<String> commitPatterns, @NotNull Map<String, CommitInfo> commitInfoMap) throws VcsException {
List<CommitChange> changes = new ArrayList<>();
int maxCommitsPerPage = TeamCityProperties.getInteger(GIT_PROXY_COMMITS_PER_PAGE, GIT_PROXY_COMMITS_PER_PAGE_DEFAULT);
long currentResultSize = 0;
long startTime = System.currentTimeMillis();
boolean shouldCollectFileChanges = true;
while (true) {
if (shouldCollectFileChanges && currentResultSize > getMaxChangesCollectionResultSizeInBytes()) {
LOG.warn(String.format("Failed to collect all the changes from git proxy. Reached the size limit of changes collection result. File changes will not be collected starting from revision %s. Operation id %s",
changes.get(changes.size() - 1).revision, client.getOperationId()));
shouldCollectFileChanges = false;
}
if (!shouldCollectFileChanges && currentResultSize > 2 * getMaxChangesCollectionResultSizeInBytes()) {
LOG.warn(String.format("Failed to collect all the changes from git proxy. Reached the maximum size of changes collection result. Returning partial result ending with %s. Operation id %s",
changes.get(changes.size() - 1).revision, client.getOperationId()));
return changes;
}
CommitList commitList;
try {
commitList = client.newRequest().listCommits(Collections.singletonList(new Pair<>("id-range", commitPatterns)), changes.size(), maxCommitsPerPage, false, true);
} catch (Exception e) {
throw new VcsException("Failed to collect commits from git proxy for collectChanges operation", e);
}
if (System.currentTimeMillis() - startTime > getTotalTimeoutSeconds() * 1000) {
throw new VcsException(String.format("Failed to collect all the changes from git proxy in specified time. Retrieved: %d, Total matched: %d", changes.size(), commitList.totalMatched));
}
if (shouldCollectFileChanges) {
List<String> commitIds = new ArrayList<>(commitList.commits.size());
for (Commit commit : commitList.commits) {
commitInfoMap.put(commit.id, commit.info);
commitIds.add(commit.id);
// size of data in commitInfoMap
currentResultSize += GIT_COMMIT_ID_SIZE_BYTES * 2; // commit.id, commit.info.id
currentResultSize += getStringSizeBytes(commit.info.fullMessage);
currentResultSize += commit.info.parents == null ? 0 : commit.info.parents.size() * GIT_COMMIT_ID_SIZE_BYTES;
}
try {
List<CommitChange> newChanges = client.newRequest().listChanges(commitIds, false, false, false, false,
TeamCityProperties.getInteger(GIT_PROXY_MAX_FILE_CHANGES_PER_COMMIT,
GIT_PROXY_MAX_FILE_CHANGES_PER_COMMIT_DEFAULT));
for (CommitChange change : newChanges) {
changes.add(change);
currentResultSize += GIT_COMMIT_ID_SIZE_BYTES; // change.revision
currentResultSize += change.compareTo == null ? 0 : GIT_COMMIT_ID_SIZE_BYTES;
for (FileChange fileChange : change.changes) {
currentResultSize += getStringSizeBytes(fileChange.oldPath);
currentResultSize += getStringSizeBytes(fileChange.newPath);
}
}
} catch (Exception e) {
throw new VcsException("Failed to collect changes from git proxy for collectChanges operation", e);
}
} else {
for (Commit commit : commitList.commits) {
String parent = commit.info.parents.isEmpty() ? null : commit.info.parents.get(0);
currentResultSize += GIT_COMMIT_ID_SIZE_BYTES;
currentResultSize += parent == null ? 0 : GIT_COMMIT_ID_SIZE_BYTES;
changes.add(new CommitChange(commit.id, parent, false, Collections.emptyList()));
}
}
if (changes.size() >= commitList.totalMatched) {
// all the result pages were retrieved, we can return result
break;
}
}
return changes;
}