Merge changes Idf8d0513,I4caa8047

* changes:
  Support reindexing immediately after NoteDb upgrade
  Expand test for Reindex program
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/OfflineNoteDbMigrationIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/OfflineNoteDbMigrationIT.java
index 9b36b03..4b3e703 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/OfflineNoteDbMigrationIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/OfflineNoteDbMigrationIT.java
@@ -127,7 +127,7 @@
   }
 
   @Test
-  public void migrationDoesNotRequireIndex() throws Exception {
+  public void migrationWithReindex() throws Exception {
     assertNotesMigrationState(NotesMigrationState.REVIEW_DB);
     setUpOneChange();
 
@@ -136,15 +136,13 @@
     assertThat(status.getReady(ChangeSchemaDefinitions.NAME, version)).isTrue();
     status.setReady(ChangeSchemaDefinitions.NAME, version, false);
     status.save();
+    assertServerStartupFails();
 
     migrate("--trial", "false");
     assertNotesMigrationState(NotesMigrationState.NOTE_DB_UNFUSED);
 
     status = new GerritIndexStatus(sitePaths);
-    assertThat(status.getReady(ChangeSchemaDefinitions.NAME, version)).isFalse();
-
-    // TODO(dborowitz): Remove when offline migration includes reindex.
-    assertServerStartupFails();
+    assertThat(status.getReady(ChangeSchemaDefinitions.NAME, version)).isTrue();
   }
 
   private void setUpOneChange() throws Exception {
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ReindexIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ReindexIT.java
index 10c51df..4edc829 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ReindexIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ReindexIT.java
@@ -14,14 +14,42 @@
 
 package com.google.gerrit.acceptance.pgm;
 
+import static com.google.common.truth.Truth8.assertThat;
+
+import com.google.common.io.MoreFiles;
 import com.google.gerrit.acceptance.NoHttpd;
 import com.google.gerrit.acceptance.StandaloneSiteTest;
+import com.google.gerrit.extensions.api.GerritApi;
+import com.google.gerrit.extensions.common.ChangeInput;
+import com.google.gerrit.reviewdb.client.Project;
+import java.nio.file.Files;
 import org.junit.Test;
 
 @NoHttpd
 public class ReindexIT extends StandaloneSiteTest {
   @Test
-  public void reindexEmptySite() throws Exception {
+  public void reindexFromScratch() throws Exception {
+    Project.NameKey project = new Project.NameKey("project");
+    String changeId;
+    try (ServerContext ctx = startServer()) {
+      GerritApi gApi = ctx.getInjector().getInstance(GerritApi.class);
+      gApi.projects().create("project");
+
+      ChangeInput in = new ChangeInput(project.get(), "master", "Test change");
+      in.newBranch = true;
+      changeId = gApi.changes().create(in).info().changeId;
+    }
+
+    MoreFiles.deleteRecursively(sitePaths.index_dir);
+    Files.createDirectory(sitePaths.index_dir);
+    assertServerStartupFails();
+
     runGerrit("reindex", "-d", sitePaths.site_path.toString(), "--show-stack-trace");
+
+    try (ServerContext ctx = startServer()) {
+      GerritApi gApi = ctx.getInjector().getInstance(GerritApi.class);
+      assertThat(gApi.changes().query("message:Test").get().stream().map(c -> c.changeId))
+          .containsExactly(changeId);
+    }
   }
 }
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/MigrateToNoteDb.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/MigrateToNoteDb.java
index 3cbf71a..eeebddd 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/MigrateToNoteDb.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/MigrateToNoteDb.java
@@ -14,9 +14,12 @@
 
 package com.google.gerrit.pgm;
 
+import static com.google.common.base.MoreObjects.firstNonNull;
 import static com.google.gerrit.server.schema.DataSourceProvider.Context.MULTI_USER;
+import static java.util.stream.Collectors.joining;
 import static java.util.stream.Collectors.toList;
 
+import com.google.common.collect.ImmutableList;
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
 import com.google.gerrit.extensions.registration.DynamicSet;
@@ -85,6 +88,13 @@
   )
   private int sequenceGap;
 
+  @Option(
+    name = "--reindex",
+    usage = "Reindex all changes after migration; defaults to false in trial mode, true otherwise",
+    handler = ExplicitBooleanOptionHandler.class
+  )
+  private Boolean reindex;
+
   private Injector dbInjector;
   private Injector sysInjector;
   private LifecycleManager dbManager;
@@ -130,7 +140,20 @@
     } finally {
       stop();
     }
-    return 0;
+
+    boolean reindex = firstNonNull(this.reindex, !trial);
+    if (!reindex) {
+      return 0;
+    }
+    // Reindex all indices, to save the user from having to run yet another program by hand while
+    // their server is offline.
+    List<String> reindexArgs =
+        ImmutableList.of(
+            "--site-path", getSitePath().toString(), "--threads", Integer.toString(threads));
+    System.out.println("Migration complete, reindexing changes with:");
+    System.out.println("  reindex " + reindexArgs.stream().collect(joining(" ")));
+    Reindex reindexPgm = new Reindex();
+    return reindexPgm.main(reindexArgs.stream().toArray(String[]::new));
   }
 
   private Injector createSysInjector() {