Fix pull replication filtering for deleted refs

The test
shouldFilterOutRefMissingInTheLocalRepositoryAndDeletedInSharedRefDb was
introduced for fixing the Issue 40015453 where entries that were deleted
in the global-refdb were never fetched.

It was then in I368e64c47d2c because of the assumption that management
of removal of refs via fetching would have let the Git protocol to
resolve the correct alignment of deleted refs.

Bug: Issue 515801262
Change-Id: I06bea83e07295463fb19bf5c4b65f07c8a85ed23
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 6f90b6c..a620dce 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
@@ -70,7 +70,6 @@
         gitRepositoryManager.openRepository(Project.nameKey(projectName))) {
       RefDatabase refDb = repository.getRefDatabase();
       return refs.stream()
-          .filter(ref -> !hasBeenRemovedFromGlobalRefDb(projectName, ref))
           .filter(
               ref -> {
                 if (shouldNotBeTrackedAnymoreOnGlobalRefDb(ref)) {
@@ -88,6 +87,28 @@
                             ref,
                             oid.getName()));
 
+                try {
+                  Ref localRef = refDb.exactRef(ref);
+                  if (localRef == null
+                      && foundAsZeroInSharedRefDb(Project.nameKey(projectName), ref)) {
+                    repLog.info(
+                        "{}:{} was removed locally and is set to zeros in the shared-refdb and thus"
+                            + " will NOT BE fetched",
+                        projectName,
+                        ref);
+                    return false;
+                  }
+                } catch (IOException ioe) {
+                  String message =
+                      String.format(
+                          "Cannot dereference ref '%s' for project '%s' therefore will NOT BE"
+                              + " fetched",
+                          ref, projectName);
+                  repLog.error(message);
+                  logger.atSevere().withCause(ioe).log("%s", message);
+                  return false;
+                }
+
                 return !localRefOid.isPresent();
               })
           .collect(Collectors.toSet());
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 e09f6f6..2216544 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,6 +17,7 @@
 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;
@@ -147,7 +148,7 @@
     Set<String> filteredRefsToFetch = fetchFilter.filter(project, refsToFetch);
 
     assertThat(filteredRefsToFetch).hasSize(1);
-    verify(sharedRefDatabaseMock, times(3))
+    verify(sharedRefDatabaseMock, atLeastOnce())
         .get(eq(projectName), eq(temporaryOutdated), eq(String.class));
   }
 
@@ -172,12 +173,6 @@
   @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 =
@@ -188,7 +183,7 @@
   }
 
   @Test
-  public void shouldFilterOutWhenRefIsDeletedInTheSharedRefDb() throws Exception {
+  public void shouldNotFilterOutWhenRefIsDeletedInTheSharedRefDb() throws Exception {
     String temporaryOutdated = "refs/heads/temporaryOutdated";
     newRef(temporaryOutdated);
 
@@ -201,8 +196,8 @@
         new MultisiteReplicationFetchFilter(sharedRefDatabaseMock, gitRepositoryManager, config);
     Set<String> filteredRefsToFetch = fetchFilter.filter(project, refsToFetch);
 
-    assertThat(filteredRefsToFetch).hasSize(0);
-    verify(sharedRefDatabaseMock).get(eq(projectName), any(), any());
+    assertThat(filteredRefsToFetch).hasSize(1);
+    verify(sharedRefDatabaseMock, atLeastOnce()).get(eq(projectName), any(), any());
   }
 
   @Test