protected boolean removeOutdatedRefs()

in git-agent/src/main/java/jetbrains/buildServer/buildTriggers/vcs/git/agent/UpdaterImpl.java [903:955]


  protected boolean removeOutdatedRefs(@NotNull File workingDir, boolean forceOutdatedRefsCheck) throws VcsException {
    if (!forceOutdatedRefsCheck && !shouldRemoveOutdatedRefs()) {
      return false;
    }
    boolean outdatedRefsRemoved = false;
    final AgentGitFacade git = myGitFactory.create(workingDir);

    final ShowRefCommand showRefCommand = git.showRef();
    showRefCommand.throwExceptionOnNonZeroExitCode(false);

    final ShowRefResult showRefResult = showRefCommand.call();
    final Set<String> invalidRefs = showRefResult.getInvalidRefs();
    if (showRefResult.isFailed() && invalidRefs.isEmpty()) {
      // show-ref command failed, but it reported no invalid refs (or we couldn't parse them),
      // we suspect, that there are invalid refs though and remove all refs, see TW-74592
      removeRefs(workingDir);
      return true;
    }
    final Refs localRefs = new Refs(showRefResult.getValidRefs());
    if (localRefs.isEmpty() && invalidRefs.isEmpty())
      return false;
    if (!invalidRefs.isEmpty()) {
      removeRefs(git, invalidRefs);
      outdatedRefsRemoved = true;
    }
    final Refs remoteRefs;
    try {
      remoteRefs = getRemoteRefs(workingDir);
    } catch (VcsException e) {
      if (CommandUtil.isCanceledError(e))
        throw e;
      String msg = "Failed to list remote repository refs, outdated local refs will not be cleaned";
      LOG.warn(msg);
      myLogger.warning(msg);
      return outdatedRefsRemoved;
    }
    //We remove both outdated local refs (e.g. refs/heads/topic) and outdated remote
    //tracking branches (refs/remote/origin/topic), while git remote origin prune
    //removes only the latter. We need that because in some cases git cannot handle
    //rename of the branch (TW-28735).
    final List<String> localRefsToDelete = new ArrayList<String>();
    for (Ref localRef : localRefs.list()) {
      Ref correspondingRemoteRef = createCorrespondingRemoteRef(localRef);
      if (remoteRefs.isOutdated(correspondingRemoteRef)) {
        localRefsToDelete.add(localRef.getName());
      }
    }
    if (!localRefsToDelete.isEmpty()) {
      removeRefs(git, localRefsToDelete);
      outdatedRefsRemoved = true;
    }
    return outdatedRefsRemoved;
  }