Check for existence of change's target SHA1 for reindexing

When the target branch of a change was advancing rapidly,
the reindexing retries applied by the ForwardedIndexingHandlerWithRetries
were continuing potentially forever as they were waiting to
see the target branch's expected SHA1 for the event.

Whilst it is vital to wait for a target branch SHA1 to appear before
reindexing a change on a remote site, it isn't essential to have
that SHA1 being *exactly* the tip of the target branch, as that
moment can be easily missed.

Example:
- Create two changes C1 and C2 in parallel and push them with
  %submit option
- The changes C1 and C2 will trigger the rapid advance of their
  target SHA1
- The other nodes may reindex C1 but not C2 because the target branch
  has advanced more than expected

Checking simply the existence of the target SHA1 in the repository
is enough to satisfy the conditions for the change being reindexed.

Bug: Issue 335353379
Change-Id: Ife361ec3378a60c0d1eb15df0f9570d569adc07a
(cherry picked from commit 89d497605c85b3422f2b6958cca1df3fc2dd532f)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
index 063d7bf..54dcca6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
@@ -26,7 +26,6 @@
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.ChangeIndexEvent;
 import java.io.IOException;
 import java.sql.Timestamp;
-import java.util.Objects;
 import java.util.Optional;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.lib.ObjectId;
@@ -102,8 +101,7 @@
         .map(
             e ->
                 (computedChangeTs.get() > e.eventCreatedOn)
-                    || ((computedChangeTs.get() == e.eventCreatedOn)
-                        && (Objects.equals(getBranchTargetSha(), e.targetSha))))
+                    || ((computedChangeTs.get() == e.eventCreatedOn) && repositoryHas(e.targetSha)))
         .orElse(true);
   }
 
@@ -142,6 +140,15 @@
     }
   }
 
+  private boolean repositoryHas(String targetSha) {
+    try (Repository repo = gitRepoMgr.openRepository(changeNotes.get().getProjectName())) {
+      return repo.parseCommit(ObjectId.fromString(targetSha)) != null;
+    } catch (IOException e) {
+      log.warn("Unable to find SHA1 {} for change {}", targetSha, changeId, e);
+      return false;
+    }
+  }
+
   @Override
   public boolean isChangeConsistent() {
     Optional<ChangeNotes> notes = getChangeNotes();