Use InMemoryRepository in acceptance tests

We can no longer use CloneCommand, which always produces an on-disk
repository. Instead "clone" by setting up a remote and checking out a
detached head.

Change-Id: I94bc3d9b231526bb5740c530702f5c918c61cc03
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
index 3e31aa6..d88a206 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
@@ -211,7 +211,7 @@
     project = new Project.NameKey(projectInput.name);
     createProject(projectInput);
 
-    setRepo(cloneProject(sshSession.getUrl() + "/" + project.get()));
+    setRepo(cloneProject(project, sshSession));
   }
 
   private ProjectInput projectInput(Description description) {
@@ -237,9 +237,9 @@
     return in;
   }
 
-  protected void setRepo(Git git) throws Exception {
-    this.git = git;
-    testRepo = new TestRepository<>(git.getRepository());
+  protected void setRepo(TestRepository<?> testRepo) throws Exception {
+    this.git = Git.wrap(testRepo.getRepository());
+    this.testRepo = new TestRepository<>(git.getRepository());
   }
 
   protected void createProject(String name) throws RestApiException {
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/GitUtil.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/GitUtil.java
index e68279d..b0fae3c 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/GitUtil.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/GitUtil.java
@@ -17,20 +17,23 @@
 import com.google.common.base.Optional;
 import com.google.common.collect.Iterables;
 import com.google.gerrit.common.FooterConstants;
-import com.google.gerrit.testutil.TempFileUtil;
+import com.google.gerrit.reviewdb.client.Project;
 
 import com.jcraft.jsch.JSch;
 import com.jcraft.jsch.JSchException;
 import com.jcraft.jsch.Session;
 
-import org.eclipse.jgit.api.CloneCommand;
 import org.eclipse.jgit.api.FetchCommand;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.api.PushCommand;
 import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
 import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.transport.FetchResult;
 import org.eclipse.jgit.transport.JschConfigSessionFactory;
 import org.eclipse.jgit.transport.OpenSshConfig.Host;
 import org.eclipse.jgit.transport.PushResult;
@@ -38,7 +41,6 @@
 import org.eclipse.jgit.transport.SshSessionFactory;
 import org.eclipse.jgit.util.FS;
 
-import java.io.File;
 import java.io.IOException;
 import java.util.List;
 import java.util.Properties;
@@ -67,17 +69,31 @@
     });
   }
 
-  public static Git cloneProject(String url) throws GitAPIException, IOException {
-    return cloneProject(url, true);
+  public static TestRepository<InMemoryRepository> cloneProject(
+      Project.NameKey project, String uri) throws Exception {
+    InMemoryRepository dest = new InMemoryRepository.Builder()
+        .setRepositoryDescription(new DfsRepositoryDescription(project.get()))
+        // SshTransport depends on a real FS to read ~/.ssh/config, but
+        // InMemoryRepository by default uses a null FS.
+        // TODO(dborowitz): Remove when we no longer depend on SSH.
+        .setFS(FS.detect())
+        .build();
+    Config cfg = dest.getConfig();
+    cfg.setString("remote", "origin", "url", uri);
+    cfg.setString("remote", "origin", "fetch",
+        "+refs/heads/*:refs/remotes/origin/*");
+    TestRepository<InMemoryRepository> testRepo = new TestRepository<>(dest);
+    FetchResult result = testRepo.git().fetch().setRemote("origin").call();
+    String originMaster = "refs/remotes/origin/master";
+    if (result.getTrackingRefUpdate(originMaster) != null) {
+      testRepo.reset(originMaster);
+    }
+    return new TestRepository<>(dest);
   }
 
-  public static Git cloneProject(String url, boolean checkout) throws GitAPIException, IOException {
-    final File gitDir = TempFileUtil.createTempDirectory();
-    final CloneCommand cloneCmd = Git.cloneRepository();
-    cloneCmd.setURI(url);
-    cloneCmd.setDirectory(gitDir);
-    cloneCmd.setNoCheckout(!checkout);
-    return cloneCmd.call();
+  public static TestRepository<InMemoryRepository> cloneProject(
+      Project.NameKey project, SshSession sshSession) throws Exception {
+    return cloneProject(project, sshSession.getUrl() + "/" + project.get());
   }
 
   public static void fetch(Git git, String spec) throws GitAPIException {
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
index b74bf34..ad3c180 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
@@ -311,7 +311,7 @@
     assertThat(canRebase).isFalse();
     merge(r2);
 
-    git.checkout().setName(r1.getCommit().name()).call();
+    testRepo.reset(r1.getCommit());
     push = pushFactory.create(db, admin.getIdent(), testRepo);
     PushOneCommit.Result r3 = push.to("refs/for/master");
 
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java
index 126e2ff..eeba450 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java
@@ -267,7 +267,8 @@
   @Test
   @TestProjectInput(createEmptyCommit = false)
   public void updateRootCommitMessage() throws Exception {
-    setRepo(cloneProject(sshSession.getUrl() + "/" + project));
+    // Re-clone empty repo; TestRepository doesn't let us reset to unborn head.
+    testRepo = cloneProject(project, sshSession);
     changeId = newChange(admin.getIdent());
     change = getChange(changeId);
 
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index 482a494..4522c13 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -68,7 +68,7 @@
       default:
         throw new IllegalArgumentException("unexpected protocol: " + p);
     }
-    setRepo(cloneProject(url + "/" + project.get()));
+    setRepo(cloneProject(project, url + "/" + project.get()));
   }
 
   @Test
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmitOnPushIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
index ed6e6e7..073f37e 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
@@ -105,7 +105,7 @@
 
     git.fetch().setRefSpecs(new RefSpec("refs/meta/config:refs/meta/config")).call();
     ObjectId objectId = git.getRepository().getRef("refs/meta/config").getObjectId();
-    git.checkout().setName(objectId.getName()).call();
+    testRepo.reset(objectId);
 
     PushOneCommit.Result r = pushTo("refs/for/refs/meta/config%submit");
     r.assertOkStatus();
@@ -116,10 +116,9 @@
 
   @Test
   public void submitOnPushMergeConflict() throws Exception {
-    String master = "refs/heads/master";
-    ObjectId objectId = git.getRepository().getRef(master).getObjectId();
-    push(master, "one change", "a.txt", "some content");
-    git.checkout().setName(objectId.getName()).call();
+    ObjectId objectId = git.getRepository().getRef("HEAD").getObjectId();
+    push("refs/heads/master", "one change", "a.txt", "some content");
+    testRepo.reset(objectId);
 
     grant(Permission.SUBMIT, project, "refs/for/refs/heads/master");
     PushOneCommit.Result r =
@@ -132,9 +131,9 @@
   @Test
   public void submitOnPushSuccessfulMerge() throws Exception {
     String master = "refs/heads/master";
-    ObjectId objectId = git.getRepository().getRef(master).getObjectId();
+    ObjectId objectId = git.getRepository().getRef("HEAD").getObjectId();
     push(master, "one change", "a.txt", "some content");
-    git.checkout().setName(objectId.getName()).call();
+    testRepo.reset(objectId);
 
     grant(Permission.SUBMIT, project, "refs/for/refs/heads/master");
     PushOneCommit.Result r =
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java
index 65fdd0f..b2c0adb 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java
@@ -53,7 +53,7 @@
     SshSession sshSession = new SshSession(server, user);
     initSsh(user);
     sshSession.open();
-    setRepo(cloneProject(sshSession.getUrl() + "/" + project.get()));
+    setRepo(cloneProject(project, sshSession));
     sshSession.close();
     user2 = accounts.user2();
     sessionDev = new RestSession(server, user2);
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java
index 0153666..674b21a 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java
@@ -61,15 +61,15 @@
   @Test
   public void listBranches() throws Exception {
     pushTo("refs/heads/master");
-    String masterCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
+    String headCommit = git.getRepository().getRef("HEAD").getTarget().getObjectId().getName();
     pushTo("refs/heads/dev");
-    String devCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
+    String devCommit = git.getRepository().getRef("HEAD").getTarget().getObjectId().getName();
     RestResponse r = adminSession.get("/projects/" + project.get() + "/branches");
     List<BranchInfo> expected = Lists.asList(
         new BranchInfo("refs/meta/config",  null, false),
         new BranchInfo[] {
           new BranchInfo("HEAD", "master", false),
-          new BranchInfo("refs/heads/master", masterCommit, false),
+          new BranchInfo("refs/heads/master", headCommit, false),
           new BranchInfo("refs/heads/dev", devCommit, true)
         });
     List<BranchInfo> result = toBranchInfoList(r);
@@ -86,14 +86,14 @@
   public void listBranchesSomeHidden() throws Exception {
     blockRead(project, "refs/heads/dev");
     pushTo("refs/heads/master");
-    String masterCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
+    String headCommit = git.getRepository().getRef("HEAD").getTarget().getObjectId().getName();
     pushTo("refs/heads/dev");
     RestResponse r = userSession.get("/projects/" + project.get() + "/branches");
     // refs/meta/config is hidden since user is no project owner
     List<BranchInfo> expected = Lists.asList(
         new BranchInfo("HEAD", "master", false),
         new BranchInfo[] {
-          new BranchInfo("refs/heads/master", masterCommit, false),
+          new BranchInfo("refs/heads/master", headCommit, false),
         });
     assertBranches(expected, toBranchInfoList(r));
   }
@@ -103,7 +103,7 @@
     blockRead(project, "refs/heads/master");
     pushTo("refs/heads/master");
     pushTo("refs/heads/dev");
-    String devCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
+    String devCommit = git.getRepository().getRef("HEAD").getTarget().getObjectId().getName();
     RestResponse r = userSession.get("/projects/" + project.get() + "/branches");
     // refs/meta/config is hidden since user is no project owner
     assertBranches(Collections.singletonList(new BranchInfo("refs/heads/dev",
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ProjectLevelConfigIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ProjectLevelConfigIT.java
index ceca9d9..4aa0ba0 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ProjectLevelConfigIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ProjectLevelConfigIT.java
@@ -68,10 +68,8 @@
     parentCfg.setString("s2", "ss", "k3", "parentValue3");
     parentCfg.setString("s2", "ss", "k4", "parentValue4");
 
-    Git parentGit =
-        cloneProject(sshSession.getUrl() + "/" + allProjects.get(), false);
-    TestRepository<?> parentTestRepo =
-        new TestRepository<>(parentGit.getRepository());
+    TestRepository<?> parentTestRepo = cloneProject(allProjects, sshSession);
+    Git parentGit = Git.wrap(parentTestRepo.getRepository());
     fetch(parentGit, RefNames.REFS_CONFIG + ":refs/heads/config");
     parentTestRepo.reset("refs/heads/config");
     PushOneCommit push =
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/GetRelatedIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
index 4b05d79..34d468f 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
@@ -99,7 +99,8 @@
 
     // Swap the order of commits and push again.
     testRepo.reset("HEAD~2");
-    git.cherryPick().include(c2).include(c1).call();
+    testRepo.cherryPick(c2);
+    testRepo.cherryPick(c1);
     pushHead(git, "refs/for/master", false);
     PatchSet.Id c1ps2 = getPatchSetId(c1);
     PatchSet.Id c2ps2 = getPatchSetId(c2);
@@ -143,7 +144,8 @@
 
     // Swap the order of commits, create a new commit on top, and push again.
     testRepo.reset(initial);
-    git.cherryPick().include(c2).include(c1).call();
+    testRepo.cherryPick(c2);
+    testRepo.cherryPick(c1);
     RevCommit c3 = commitBuilder()
         .add("c.txt", "3")
         .message("subject: 3")
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/PatchListCacheIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/PatchListCacheIT.java
index cb0818f..ea2cd75 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/PatchListCacheIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/PatchListCacheIT.java
@@ -120,7 +120,7 @@
     pushHead(git, "refs/for/master", false);
 
     // Change 1,2 (+FILE_A, -FILE_D))
-    git.cherryPick().include(c).call();
+    testRepo.cherryPick(c);
     pushHead(git, "refs/for/master", false);
 
     // Compare Change 1,2 with Base (+FILE_A, -FILE_D))
@@ -187,7 +187,7 @@
     pushHead(git, "refs/for/master", false);
 
     // Change 1,2 (+FILE_A, +FILE_C, -FILE_D)
-    git.cherryPick().include(a).call();
+    testRepo.cherryPick(a);
     RevCommit b = amendBuilder()
         .add(FILE_C, "2")
         .create();
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java
index 0458f06..73d9c89 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java
@@ -189,7 +189,7 @@
     PushOneCommit.Result r2 = push.to("refs/for/master");
     merge(r2);
 
-    git.checkout().setName(r1.getCommit().name()).call();
+    testRepo.reset(r1.getCommit());
     push = pushFactory.create(db, admin.getIdent(), testRepo, subject, file, contents);
     PushOneCommit.Result r3 = push.to("refs/for/master");
     revision(r3).review(ReviewInput.recommend());
@@ -216,7 +216,7 @@
     PushOneCommit.Result r2 = push.to("refs/for/master");
     merge(r2);
 
-    git.checkout().setName(r1.getCommit().name()).call();
+    testRepo.reset(r1.getCommit());
     push = pushFactory.create(db, admin.getIdent(), testRepo, subject, file, contents);
     PushOneCommit.Result r3 = push.to("refs/for/master");
     revision(r3).review(ReviewInput.recommend());
@@ -232,7 +232,7 @@
     saveLabelConfig();
 
     PushOneCommit.Result r1 = createChange();
-    git.checkout().setName(r1.getCommit().name()).call();
+    testRepo.reset(r1.getCommit());
 
     PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
         PushOneCommit.SUBJECT, "b.txt", "other contents");
@@ -262,7 +262,7 @@
 
     PushOneCommit.Result r1 = createChange();
 
-    git.checkout().setName(r1.getCommit().name()).call();
+    testRepo.reset(r1.getCommit());
 
     PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
         PushOneCommit.SUBJECT, "b.txt", "other contents");
@@ -303,7 +303,7 @@
     PushOneCommit.Result basePlusMMinusM = push.to("refs/for/master");
     merge(basePlusMMinusM);
 
-    git.checkout().setName(base.getCommit().name()).call();
+    testRepo.reset(base.getCommit());
     push = pushFactory.create(db, admin.getIdent(), testRepo,
         PushOneCommit.SUBJECT, file, contents + "MM");
     PushOneCommit.Result patchSet = push.to("refs/for/master");
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/ssh/JschVerifyFalseBugIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/ssh/JschVerifyFalseBugIT.java
index 27a70b0..4f8a334 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/ssh/JschVerifyFalseBugIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/ssh/JschVerifyFalseBugIT.java
@@ -19,6 +19,7 @@
 
 import com.google.gerrit.acceptance.AbstractDaemonTest;
 import com.google.gerrit.acceptance.NoHttpd;
+import com.google.gerrit.reviewdb.client.Project;
 
 import org.junit.Ignore;
 import org.junit.Test;
@@ -50,7 +51,7 @@
         for (int i = 1; i < 100; i++) {
           String p = "p" + i;
           createProject(p);
-          cloneProject(sshSession.getUrl() + "/" + p);
+          cloneProject(new Project.NameKey(p), sshSession);
         }
         return null;
       }