Merge "Merge branch 'stable-2.15'"
diff --git a/java/com/google/gerrit/server/account/externalids/DisabledExternalIdCache.java b/java/com/google/gerrit/server/account/externalids/DisabledExternalIdCache.java
index c1ef261..5894051 100644
--- a/java/com/google/gerrit/server/account/externalids/DisabledExternalIdCache.java
+++ b/java/com/google/gerrit/server/account/externalids/DisabledExternalIdCache.java
@@ -35,20 +35,6 @@
   }
 
   @Override
-  public void onCreate(ObjectId oldNotesRev, ObjectId newNotesRev, Collection<ExternalId> extId) {}
-
-  @Override
-  public void onUpdate(ObjectId oldNotesRev, ObjectId newNotesRev, Collection<ExternalId> extId) {}
-
-  @Override
-  public void onReplace(
-      ObjectId oldNotesRev,
-      ObjectId newNotesRev,
-      Account.Id accountId,
-      Collection<ExternalId> toRemove,
-      Collection<ExternalId> toAdd) {}
-
-  @Override
   public void onReplace(
       ObjectId oldNotesRev,
       ObjectId newNotesRev,
@@ -56,9 +42,6 @@
       Collection<ExternalId> toAdd) {}
 
   @Override
-  public void onRemove(ObjectId oldNotesRev, ObjectId newNotesRev, Collection<ExternalId> extId) {}
-
-  @Override
   public ImmutableSet<ExternalId> byAccount(Account.Id accountId) {
     throw new UnsupportedOperationException();
   }
diff --git a/java/com/google/gerrit/server/account/externalids/ExternalIdCache.java b/java/com/google/gerrit/server/account/externalids/ExternalIdCache.java
index 7878052..ffb4e76 100644
--- a/java/com/google/gerrit/server/account/externalids/ExternalIdCache.java
+++ b/java/com/google/gerrit/server/account/externalids/ExternalIdCache.java
@@ -19,7 +19,6 @@
 import com.google.gerrit.reviewdb.client.Account;
 import java.io.IOException;
 import java.util.Collection;
-import java.util.Collections;
 import org.eclipse.jgit.lib.ObjectId;
 
 /**
@@ -29,20 +28,6 @@
  * cache is up to date.
  */
 interface ExternalIdCache {
-  void onCreate(ObjectId oldNotesRev, ObjectId newNotesRev, Collection<ExternalId> extId)
-      throws IOException;
-
-  void onUpdate(ObjectId oldNotesRev, ObjectId newNotesRev, Collection<ExternalId> extId)
-      throws IOException;
-
-  void onReplace(
-      ObjectId oldNotesRev,
-      ObjectId newNotesRev,
-      Account.Id accountId,
-      Collection<ExternalId> toRemove,
-      Collection<ExternalId> toAdd)
-      throws IOException;
-
   void onReplace(
       ObjectId oldNotesRev,
       ObjectId newNotesRev,
@@ -50,9 +35,6 @@
       Collection<ExternalId> toAdd)
       throws IOException;
 
-  void onRemove(ObjectId oldNotesRev, ObjectId newNotesRev, Collection<ExternalId> extId)
-      throws IOException;
-
   ImmutableSet<ExternalId> byAccount(Account.Id accountId) throws IOException;
 
   ImmutableSet<ExternalId> byAccount(Account.Id accountId, ObjectId rev) throws IOException;
@@ -66,19 +48,4 @@
   default ImmutableSet<ExternalId> byEmail(String email) throws IOException {
     return byEmails(email).get(email);
   }
-
-  default void onCreate(ObjectId oldNotesRev, ObjectId newNotesRev, ExternalId extId)
-      throws IOException {
-    onCreate(oldNotesRev, newNotesRev, Collections.singleton(extId));
-  }
-
-  default void onRemove(ObjectId oldNotesRev, ObjectId newNotesRev, ExternalId extId)
-      throws IOException {
-    onRemove(oldNotesRev, newNotesRev, Collections.singleton(extId));
-  }
-
-  default void onUpdate(ObjectId oldNotesRev, ObjectId newNotesRev, ExternalId updatedExtId)
-      throws IOException {
-    onUpdate(oldNotesRev, newNotesRev, Collections.singleton(updatedExtId));
-  }
 }
diff --git a/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java b/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
index 814f19e..25789a1 100644
--- a/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
+++ b/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
@@ -15,17 +15,14 @@
 package com.google.gerrit.server.account.externalids;
 
 import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
-import static java.util.stream.Collectors.toSet;
 
 import com.google.auto.value.AutoValue;
 import com.google.common.base.Strings;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
-import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Iterables;
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.MultimapBuilder;
@@ -77,73 +74,6 @@
   }
 
   @Override
-  public void onCreate(ObjectId oldNotesRev, ObjectId newNotesRev, Collection<ExternalId> extIds)
-      throws IOException {
-    updateCache(
-        oldNotesRev,
-        newNotesRev,
-        m -> {
-          for (ExternalId extId : extIds) {
-            extId.checkThatBlobIdIsSet();
-            m.put(extId.accountId(), extId);
-          }
-        });
-  }
-
-  @Override
-  public void onRemove(ObjectId oldNotesRev, ObjectId newNotesRev, Collection<ExternalId> extIds)
-      throws IOException {
-    updateCache(
-        oldNotesRev,
-        newNotesRev,
-        m -> {
-          for (ExternalId extId : extIds) {
-            m.remove(extId.accountId(), extId);
-          }
-        });
-  }
-
-  @Override
-  public void onUpdate(
-      ObjectId oldNotesRev, ObjectId newNotesRev, Collection<ExternalId> updatedExtIds)
-      throws IOException {
-    updateCache(
-        oldNotesRev,
-        newNotesRev,
-        m -> {
-          removeKeys(m.values(), updatedExtIds.stream().map(e -> e.key()).collect(toSet()));
-          for (ExternalId updatedExtId : updatedExtIds) {
-            updatedExtId.checkThatBlobIdIsSet();
-            m.put(updatedExtId.accountId(), updatedExtId);
-          }
-        });
-  }
-
-  @Override
-  public void onReplace(
-      ObjectId oldNotesRev,
-      ObjectId newNotesRev,
-      Account.Id accountId,
-      Collection<ExternalId> toRemove,
-      Collection<ExternalId> toAdd)
-      throws IOException {
-    ExternalIdNotes.checkSameAccount(Iterables.concat(toRemove, toAdd), accountId);
-
-    updateCache(
-        oldNotesRev,
-        newNotesRev,
-        m -> {
-          for (ExternalId extId : toRemove) {
-            m.remove(extId.accountId(), extId);
-          }
-          for (ExternalId extId : toAdd) {
-            extId.checkThatBlobIdIsSet();
-            m.put(extId.accountId(), extId);
-          }
-        });
-  }
-
-  @Override
   public void onReplace(
       ObjectId oldNotesRev,
       ObjectId newNotesRev,
@@ -230,10 +160,6 @@
     }
   }
 
-  private static void removeKeys(Collection<ExternalId> ids, Collection<ExternalId.Key> toRemove) {
-    Collections2.transform(ids, e -> e.key()).removeAll(toRemove);
-  }
-
   private static class Loader extends CacheLoader<ObjectId, AllExternalIds> {
     private final ExternalIdReader externalIdReader;
 
diff --git a/java/com/google/gerrit/sshd/commands/UploadArchive.java b/java/com/google/gerrit/sshd/commands/UploadArchive.java
index 7518cbb..95dbb40 100644
--- a/java/com/google/gerrit/sshd/commands/UploadArchive.java
+++ b/java/com/google/gerrit/sshd/commands/UploadArchive.java
@@ -140,7 +140,7 @@
         break;
       }
       if (!s.startsWith(argCmd)) {
-        throw new Failure(1, "fatal: 'argument' token or flush expected");
+        throw new Failure(1, "fatal: 'argument' token or flush expected, got " + s);
       }
       String[] parts = s.substring(argCmd.length()).split("=", 2);
       for (String p : parts) {
@@ -173,18 +173,18 @@
 
       ArchiveFormat f = allowedFormats.getExtensions().get("." + options.format);
       if (f == null) {
-        throw new Failure(3, "fatal: upload-archive not permitted");
+        throw new Failure(3, "fatal: upload-archive not permitted for format " + options.format);
       }
 
       // Find out the object to get from the specified reference and paths
       ObjectId treeId = repo.resolve(options.treeIsh);
       if (treeId == null) {
-        throw new Failure(4, "fatal: reference not found");
+        throw new Failure(4, "fatal: reference not found: " + options.treeIsh);
       }
 
       // Verify the user has permissions to read the specified tree.
       if (!canRead(treeId)) {
-        throw new Failure(5, "fatal: cannot perform upload-archive operation");
+        throw new Failure(5, "fatal: no permission to read tree" + options.treeIsh);
       }
 
       // The archive is sent in DATA sideband channel
diff --git a/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java b/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
index a64818d..f4f81f8 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
@@ -127,7 +127,7 @@
     tmp = in.readString();
     tmp = in.readString();
     tmp = tmp.substring(1);
-    assertThat(tmp).isEqualTo("fatal: upload-archive not permitted");
+    assertThat(tmp).isEqualTo("fatal: upload-archive not permitted for format zip");
   }
 
   private InputStream argumentsToInputStream(String c) throws Exception {