private List retrieveChanges()

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;
  }