Merge branch 'stable-3.0' into stable-3.1

* stable-3.0:
  IntBlob: Add debug log when storing value on ref
  RepoSequence: Add debug log when acquiring new sequence batch
  Bazel: Remove version suffix from servlet-api-3_1 rule
  Update no-new-changes error doc
  Ignore WIP changes in "CCed on" dashboard section
  Sequences: Introduce constants for configuration keys/values
  RepoSequence: Add debug log of batch size
  Move Flogger to nongoogle.bzl
  DefaultRefFilter#canSeeSingleChangeRef: Do not fail for invalid change refs
  Upgrade testcontainers to 1.14.3
  Add missing documentation of notedb.changes.sequenceBatchSize

Change-Id: I9e135202b7f520a6267b9ad94c97ed58c8f67233
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 177862a..4aa8269 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -3612,6 +3612,18 @@
 +
 By default, 1.
 
+[[notedb.changes.sequenceBatchSize]]notedb.changes.sequenceBatchSize::
++
+The next available change sequence number is stored as UTF-8 text in a
+blob pointed to by the `refs/sequences/changes` ref in the `All-Projects`
+repository. Multiple processes share the same sequence by incrementing
+the counter using normal git ref updates. To amortize the cost of these
+ref updates, processes increment the counter by a larger number and
+hand out numbers from that range in memory until they run out. This
+configuration parameter controls the size of the change ID batch that
+each process retrieves at once.
++
+By default, 20.
 
 [[oauth]]
 === Section oauth
diff --git a/Documentation/error-no-new-changes.txt b/Documentation/error-no-new-changes.txt
index 17422ad..45586c3 100644
--- a/Documentation/error-no-new-changes.txt
+++ b/Documentation/error-no-new-changes.txt
@@ -22,8 +22,8 @@
 this simply paste the commit ID in the Gerrit Web UI into the search
 field. Details about how to search in Gerrit are explained link:user-search.html[here].
 
-Please note that each commit can really be pushed only once. This
-means:
+Please note that generally it only makes sense for each commit to
+be pushed only once. This means:
 
 . you cannot push a commit again even if the change for which the
   commit was pushed before was abandoned (but you may restore the
@@ -31,14 +31,18 @@
 . you cannot reset a change to an old patch set by pushing the old
   commit for this change again
 . if a commit was pushed to one branch you cannot push this commit
-  to another branch in project scope.
+  to another branch in project scope (see link:user-upload.html#base[exception]).
 . if a commit was pushed directly to a branch (without going through
   code review) you cannot push this commit once again for code
   review (please note that in this case searching by the commit ID
-  in the Gerrit Web UI will not find any change)
+  in the Gerrit Web UI will not find any change), see
+  link:user-upload.html#base[exception].
 
 If you need to re-push a commit you may rewrite this commit by
-link:http://www.kernel.org/pub/software/scm/git/docs/git-commit.html[amending] it or doing an interactive link:http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html[git rebase]. By rewriting the
+link:http://www.kernel.org/pub/software/scm/git/docs/git-commit.html[amending]
+it or doing an interactive
+link:http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html[git
+rebase], or see link:user-upload.html#base[exception]. By rewriting the
 commit you actually create a new commit (with a new commit ID in
 project scope) which can then be pushed to Gerrit.
 
@@ -46,6 +50,13 @@
 the old commit (case 1 above), you also need to replace it with a new
 Change-Id, otherwise the push will fail with another error message.
 
+Sometimes a change no longer makes sense to be destined for a specific
+branch, and instead of trying to re-push the commit for a different
+branch, it makes more sense to move the change to the preferred branch
+(where it will now likely need a rebase). Moving the change instead of
+pushing a rebased commit to the preferred branch helps to retain code
+review comments and any previous patchsets on the original change.
+
 == Fast-forward merges
 
 You will also encounter this error if you did a Fast-forward merge
diff --git a/WORKSPACE b/WORKSPACE
index ef43fc7..6c2e5cd 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -193,26 +193,6 @@
     sha1 = "42aa5155a54a87d70af32d4b0d06bf43779de0e2",
 )
 
-FLOGGER_VERS = "0.4"
-
-maven_jar(
-    name = "flogger",
-    artifact = "com.google.flogger:flogger:" + FLOGGER_VERS,
-    sha1 = "9c8863dcc913b56291c0c88e6d4ca9715b43df98",
-)
-
-maven_jar(
-    name = "flogger-log4j-backend",
-    artifact = "com.google.flogger:flogger-log4j-backend:" + FLOGGER_VERS,
-    sha1 = "17aa5e31daa1354187e14b6978597d630391c028",
-)
-
-maven_jar(
-    name = "flogger-system-backend",
-    artifact = "com.google.flogger:flogger-system-backend:" + FLOGGER_VERS,
-    sha1 = "287b569d76abcd82f9de87fe41829fbc7ebd8ac9",
-)
-
 maven_jar(
     name = "gson",
     artifact = "com.google.code.gson:gson:2.8.5",
diff --git a/java/com/google/gerrit/server/notedb/IntBlob.java b/java/com/google/gerrit/server/notedb/IntBlob.java
index c0af37f..5efc2b0 100644
--- a/java/com/google/gerrit/server/notedb/IntBlob.java
+++ b/java/com/google/gerrit/server/notedb/IntBlob.java
@@ -20,6 +20,7 @@
 import com.google.auto.value.AutoValue;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.CharMatcher;
+import com.google.common.flogger.FluentLogger;
 import com.google.common.primitives.Ints;
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.entities.Project;
@@ -41,6 +42,8 @@
 
 @AutoValue
 public abstract class IntBlob {
+  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
   public static Optional<IntBlob> parse(Repository repo, String refName) throws IOException {
     try (ObjectReader or = repo.newObjectReader()) {
       return parse(repo, refName, or);
@@ -84,8 +87,13 @@
       throws IOException {
     ObjectId newId;
     try (ObjectInserter ins = repo.newObjectInserter()) {
+      logger.atFine().log(
+          "storing value %d on %s in %s (oldId: %s)",
+          val, refName, projectName, oldId == null ? "null" : oldId.name());
       newId = ins.insert(OBJ_BLOB, Integer.toString(val).getBytes(UTF_8));
       ins.flush();
+      logger.atFine().log(
+          "successfully stored %d on %s as %s in %s", val, refName, newId.name(), projectName);
     }
     RefUpdate ru = repo.updateRef(refName);
     if (oldId != null) {
diff --git a/java/com/google/gerrit/server/notedb/RepoSequence.java b/java/com/google/gerrit/server/notedb/RepoSequence.java
index 8096f89..e52b84c 100644
--- a/java/com/google/gerrit/server/notedb/RepoSequence.java
+++ b/java/com/google/gerrit/server/notedb/RepoSequence.java
@@ -30,6 +30,7 @@
 import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import com.google.common.flogger.FluentLogger;
 import com.google.common.util.concurrent.Runnables;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.entities.RefNames;
@@ -64,6 +65,8 @@
  * numbers.
  */
 public class RepoSequence {
+  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
   @FunctionalInterface
   public interface Seed {
     int get();
@@ -185,6 +188,7 @@
     this.afterReadRef = requireNonNull(afterReadRef, "afterReadRef");
     this.retryer = requireNonNull(retryer, "retryer");
 
+    logger.atFine().log("sequence batch size for %s is %s", name, batchSize);
     counterLock = new ReentrantLock(true);
   }
 
@@ -263,6 +267,7 @@
   private void acquire(int count) {
     try (Repository repo = repoManager.openRepository(projectName);
         RevWalk rw = new RevWalk(repo)) {
+      logger.atFine().log("acquire %d ids on %s in %s", count, refName, projectName);
       Optional<IntBlob> blob = IntBlob.parse(repo, refName, rw);
       afterReadRef.run();
       ObjectId oldId;
diff --git a/java/com/google/gerrit/server/notedb/Sequences.java b/java/com/google/gerrit/server/notedb/Sequences.java
index 73cc600..9f19725 100644
--- a/java/com/google/gerrit/server/notedb/Sequences.java
+++ b/java/com/google/gerrit/server/notedb/Sequences.java
@@ -32,6 +32,11 @@
 
 @Singleton
 public class Sequences {
+  private static final String SECTION_NOTEDB = "noteDb";
+  private static final String KEY_SEQUENCE_BATCH_SIZE = "sequenceBatchSize";
+  private static final int DEFAULT_ACCOUNTS_SEQUENCE_BATCH_SIZE = 1;
+  private static final int DEFAULT_CHANGES_SEQUENCE_BATCH_SIZE = 20;
+
   public static final String NAME_ACCOUNTS = "accounts";
   public static final String NAME_GROUPS = "groups";
   public static final String NAME_CHANGES = "changes";
@@ -60,7 +65,12 @@
       AllUsersName allUsers,
       MetricMaker metrics) {
 
-    int accountBatchSize = cfg.getInt("noteDb", "accounts", "sequenceBatchSize", 1);
+    int accountBatchSize =
+        cfg.getInt(
+            SECTION_NOTEDB,
+            NAME_ACCOUNTS,
+            KEY_SEQUENCE_BATCH_SIZE,
+            DEFAULT_ACCOUNTS_SEQUENCE_BATCH_SIZE);
     accountSeq =
         new RepoSequence(
             repoManager,
@@ -70,7 +80,12 @@
             () -> FIRST_ACCOUNT_ID,
             accountBatchSize);
 
-    int changeBatchSize = cfg.getInt("noteDb", "changes", "sequenceBatchSize", 20);
+    int changeBatchSize =
+        cfg.getInt(
+            SECTION_NOTEDB,
+            NAME_CHANGES,
+            KEY_SEQUENCE_BATCH_SIZE,
+            DEFAULT_CHANGES_SEQUENCE_BATCH_SIZE);
     changeSeq =
         new RepoSequence(
             repoManager,
diff --git a/java/com/google/gerrit/server/permissions/DefaultRefFilter.java b/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
index f6a5335..67bfcb9 100644
--- a/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
+++ b/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
@@ -565,7 +565,12 @@
     // even if the change is not part of the set of most recent changes that
     // SearchingChangeCacheImpl returns.
     Change.Id cId = Change.Id.fromRef(refName);
-    requireNonNull(cId, () -> String.format("invalid change id for ref %s", refName));
+    if (cId == null) {
+      // The ref is not a valid change ref. Treat it as non-visible since it's not representing a
+      // change.
+      logger.atWarning().log("invalid change ref %s is not visible", refName);
+      return false;
+    }
     ChangeNotes notes;
     try {
       notes = changeNotesFactory.create(projectState.getNameKey(), cId);
diff --git a/lib/nongoogle_test.sh b/lib/nongoogle_test.sh
index 336fcbf..80195c8 100755
--- a/lib/nongoogle_test.sh
+++ b/lib/nongoogle_test.sh
@@ -16,6 +16,9 @@
 duct-tape
 eddsa
 elasticsearch-rest-client
+flogger
+flogger-log4j-backend
+flogger-system-backend
 httpasyncclient
 httpcore-nio
 j2objc
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
index e79277a..c8bf6c1 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
@@ -144,10 +144,10 @@
         suffixForDashboard: 'limit:25',
       },
       {
-        // Open changes the viewed user is CCed on. Changes ignored by the viewing
-        // user are filtered out.
+        // Non-WIP open changes the viewed user is CCed on. Changes ignored by the
+        // viewing user are filtered out.
         name: 'CCed on',
-        query: 'is:open -is:ignored cc:${user}',
+        query: 'is:open -is:wip -is:ignored cc:${user}',
         suffixForDashboard: 'limit:10',
       },
       {
diff --git a/tools/nongoogle.bzl b/tools/nongoogle.bzl
index 5e2e4e1..19c2eaa 100644
--- a/tools/nongoogle.bzl
+++ b/tools/nongoogle.bzl
@@ -112,6 +112,29 @@
         sha1 = "f84302e14648f9f63c0c73951054aeb2ff0b810a",
     )
 
+    # Google internal dependencies: these are developed at Google, so there is
+    # no concern about version skew.
+
+    FLOGGER_VERS = "0.4"
+
+    maven_jar(
+        name = "flogger",
+        artifact = "com.google.flogger:flogger:" + FLOGGER_VERS,
+        sha1 = "9c8863dcc913b56291c0c88e6d4ca9715b43df98",
+    )
+
+    maven_jar(
+        name = "flogger-log4j-backend",
+        artifact = "com.google.flogger:flogger-log4j-backend:" + FLOGGER_VERS,
+        sha1 = "17aa5e31daa1354187e14b6978597d630391c028",
+    )
+
+    maven_jar(
+        name = "flogger-system-backend",
+        artifact = "com.google.flogger:flogger-system-backend:" + FLOGGER_VERS,
+        sha1 = "287b569d76abcd82f9de87fe41829fbc7ebd8ac9",
+    )
+
     # Test-only dependencies below.
 
     maven_jar(
@@ -126,18 +149,18 @@
         sha1 = "dc13ae4faca6df981fc7aeb5a522d9db446d5d50",
     )
 
-    TESTCONTAINERS_VERSION = "1.14.2"
+    TESTCONTAINERS_VERSION = "1.14.3"
 
     maven_jar(
         name = "testcontainers",
         artifact = "org.testcontainers:testcontainers:" + TESTCONTAINERS_VERSION,
-        sha1 = "d74bc045fb5f30988b0adff20244412972a9f564",
+        sha1 = "071fc82ba663f469447a19434e7db90f3a872753",
     )
 
     maven_jar(
         name = "testcontainers-elasticsearch",
         artifact = "org.testcontainers:elasticsearch:" + TESTCONTAINERS_VERSION,
-        sha1 = "66e1a6da0362beee83673b877c9c2e0536d6912c",
+        sha1 = "3709e2ebb0b6aa4e2ba2b6ca92ffdd3bf637a86c",
     )
 
     maven_jar(