Revert "Do not filter out refs removals when filtering pull-replication fetches"

This reverts commit 05960652371637b0e33ddae4005b1149bed5667a.

Reason for revert: Created the regression Issue 515801262.

Bug: Issue 515801262
Change-Id: I15b8587d2cb93bd378b5b0d62fd516acb3210d52
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java
index 8423d2e..6f90b6c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java
@@ -23,6 +23,7 @@
 import com.google.common.collect.Sets;
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.entities.Project;
+import com.google.gerrit.entities.Project.NameKey;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -69,6 +70,7 @@
         gitRepositoryManager.openRepository(Project.nameKey(projectName))) {
       RefDatabase refDb = repository.getRefDatabase();
       return refs.stream()
+          .filter(ref -> !hasBeenRemovedFromGlobalRefDb(projectName, ref))
           .filter(
               ref -> {
                 if (shouldNotBeTrackedAnymoreOnGlobalRefDb(ref)) {
@@ -133,6 +135,31 @@
     return refLocks;
   }
 
+  /* If the ref to fetch has been set to all zeros on the global-refdb, it means
+   * that whatever is the situation locally, we do not need to fetch it:
+   * - If the remote still has it, fetching it will be useless because the global
+   *   state is that the ref should be removed.
+   * - If the remote doesn't have it anymore, trying to fetch the ref won't do
+   *   anything because you can't just remove local refs by fetching.
+   */
+  private boolean hasBeenRemovedFromGlobalRefDb(String projectName, String ref) {
+    if (foundAsZeroInSharedRefDb(Project.nameKey(projectName), ref)) {
+      repLog.info(
+          "{}:{} is found as zeros (removed) in shared-refdb thus will NOT BE fetched",
+          projectName,
+          ref);
+      return true;
+    }
+    return false;
+  }
+
+  private boolean foundAsZeroInSharedRefDb(NameKey projectName, String ref) {
+    return sharedRefDb
+        .get(projectName, ref, String.class)
+        .map(r -> ZERO_ID_NAME.equals(r))
+        .orElse(false);
+  }
+
   private Optional<ObjectId> getLocalSha1IfEqualsToExistingGlobalRefDb(
       Repository repository,
       String projectName,
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java
index b9ec588..e09f6f6 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java
@@ -17,7 +17,6 @@
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -148,7 +147,7 @@
     Set<String> filteredRefsToFetch = fetchFilter.filter(project, refsToFetch);
 
     assertThat(filteredRefsToFetch).hasSize(1);
-    verify(sharedRefDatabaseMock, atLeastOnce())
+    verify(sharedRefDatabaseMock, times(3))
         .get(eq(projectName), eq(temporaryOutdated), eq(String.class));
   }
 
@@ -173,6 +172,12 @@
   @Test
   public void shouldNotFilterOutWhenRefsMultisiteVersionIsPresentInSharedRefDb() throws Exception {
     String refsMultisiteVersionRef = ProjectVersionRefUpdate.MULTI_SITE_VERSIONING_REF;
+    RevCommit multiSiteVersionRef = newRef(refsMultisiteVersionRef);
+
+    doReturn(Optional.of(multiSiteVersionRef.getId().getName()))
+        .when(sharedRefDatabaseMock)
+        .get(eq(projectName), eq(refsMultisiteVersionRef), eq(String.class));
+
     Set<String> refsToFetch = Set.of(refsMultisiteVersionRef);
 
     MultisiteReplicationFetchFilter fetchFilter =
@@ -183,7 +188,7 @@
   }
 
   @Test
-  public void shouldNotFilterOutWhenRefIsDeletedInTheSharedRefDb() throws Exception {
+  public void shouldFilterOutWhenRefIsDeletedInTheSharedRefDb() throws Exception {
     String temporaryOutdated = "refs/heads/temporaryOutdated";
     newRef(temporaryOutdated);
 
@@ -196,8 +201,25 @@
         new MultisiteReplicationFetchFilter(sharedRefDatabaseMock, gitRepositoryManager, config);
     Set<String> filteredRefsToFetch = fetchFilter.filter(project, refsToFetch);
 
+    assertThat(filteredRefsToFetch).hasSize(0);
+    verify(sharedRefDatabaseMock).get(eq(projectName), any(), any());
+  }
+
+  @Test
+  public void shouldNotFilterOutWhenRefIsMissingOnlyInTheLocalRepository() throws Exception {
+    String refObjectId = "0000000000000000000000000000000000000001";
+    String nonExistingLocalRef = "refs/heads/temporaryOutdated";
+
+    Set<String> refsToFetch = Set.of(nonExistingLocalRef);
+    doReturn(Optional.of(refObjectId))
+        .when(sharedRefDatabaseMock)
+        .get(eq(projectName), any(), any());
+
+    MultisiteReplicationFetchFilter fetchFilter =
+        new MultisiteReplicationFetchFilter(sharedRefDatabaseMock, gitRepositoryManager, config);
+    Set<String> filteredRefsToFetch = fetchFilter.filter(project, refsToFetch);
+
     assertThat(filteredRefsToFetch).hasSize(1);
-    verify(sharedRefDatabaseMock, atLeastOnce()).get(eq(projectName), any(), any());
   }
 
   @Test
@@ -213,6 +235,23 @@
     assertThat(filteredRefsToFetch).hasSize(1);
   }
 
+  @Test
+  public void shouldFilterOutRefMissingInTheLocalRepositoryAndDeletedInSharedRefDb()
+      throws Exception {
+    String nonExistingLocalRef = "refs/heads/temporaryOutdated";
+
+    Set<String> refsToFetch = Set.of(nonExistingLocalRef);
+    doReturn(Optional.of(ObjectId.zeroId().getName()))
+        .when(sharedRefDatabaseMock)
+        .get(eq(projectName), any(), any());
+
+    MultisiteReplicationFetchFilter fetchFilter =
+        new MultisiteReplicationFetchFilter(sharedRefDatabaseMock, gitRepositoryManager, config);
+    Set<String> filteredRefsToFetch = fetchFilter.filter(project, refsToFetch);
+
+    assertThat(filteredRefsToFetch).hasSize(0);
+  }
+
   private RevCommit newRef(String refName) throws Exception {
     return repo.branch(refName).commit().create();
   }