Avoid costly findMergedInto during push to refs/for/*

It is uncommon to automatically close a change by first getting the
commit into a branch or tag, and then later pushing that commit to
refs/for/* and expecting Gerrit will close the change by matching
the Change-Id in the commit message footer.  Most of the time a
change is automatically closed by a direct branch push, and doesn't
need this fallback driven by Change-Id in the message.

However, leave in the fix for GERRIT-54 e6b34af43cae ("Close change
if a replacement patch set is already submitted") to permit users
to close a change by pushing the exact commit to refs/changes/NNNN.
This format is deprecated and will be removed in the future anyway.

Change-Id: Ie5d2af4c1aa2a1bb301b29332e856babf6288b17
(cherry picked from commit 718fd9bcccc290bdbca8e7c67aa28eee901221d3)
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index b0a1e76..9ba95ee 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -861,10 +861,11 @@
       return;
     }
 
-    requestReplace(cmd, changeEnt, newCommit);
+    requestReplace(cmd, true, changeEnt, newCommit);
   }
 
-  private boolean requestReplace(final ReceiveCommand cmd, final Change change,
+  private boolean requestReplace(final ReceiveCommand cmd,
+      final boolean checkMergedInto, final Change change,
       final RevCommit newCommit) {
     if (change.getStatus().isClosed()) {
       reject(cmd, "change " + change.getId() + " closed");
@@ -872,7 +873,7 @@
     }
 
     final ReplaceRequest req =
-        new ReplaceRequest(change.getId(), newCommit, cmd);
+        new ReplaceRequest(change.getId(), newCommit, cmd, checkMergedInto);
     if (replaceByChange.containsKey(req.ontoChange)) {
       reject(cmd, "duplicate request");
       return false;
@@ -951,7 +952,7 @@
           if (changes.size() == 1) {
             // Schedule as a replacement to this one matching change.
             //
-            if (requestReplace(newChange, changes.get(0), c)) {
+            if (requestReplace(newChange, false, changes.get(0), c)) {
               continue;
             } else {
               return;
@@ -1284,8 +1285,10 @@
     insertAncestors(ps.getId(), c);
     db.patchSets().insert(Collections.singleton(ps));
 
-    final Ref mergedInto = findMergedInto(change.getDest().get(), c);
-    result.mergedIntoRef = mergedInto != null ? mergedInto.getName() : null;
+    if (request.checkMergedInto) {
+      final Ref mergedInto = findMergedInto(change.getDest().get(), c);
+      result.mergedIntoRef = mergedInto != null ? mergedInto.getName() : null;
+    }
     result.change = change;
     result.patchSet = ps;
     result.info = patchSetInfoFactory.get(c, ps.getId());
@@ -1504,12 +1507,14 @@
     final Change.Id ontoChange;
     final RevCommit newCommit;
     final ReceiveCommand cmd;
+    final boolean checkMergedInto;
 
     ReplaceRequest(final Change.Id toChange, final RevCommit newCommit,
-        final ReceiveCommand cmd) {
+        final ReceiveCommand cmd, final boolean checkMergedInto) {
       this.ontoChange = toChange;
       this.newCommit = newCommit;
       this.cmd = cmd;
+      this.checkMergedInto = checkMergedInto;
     }
   }
 
@@ -1775,7 +1780,7 @@
         for (final String changeId : c.getFooterLines(CHANGE_ID)) {
           final Change.Id onto = byKey.get(new Change.Key(changeId.trim()));
           if (onto != null) {
-            toClose.add(new ReplaceRequest(onto, c, cmd));
+            toClose.add(new ReplaceRequest(onto, c, cmd, false));
             break;
           }
         }