repo.ref expects ref but gets sha1

Use repo.resolve() rather than repo.ref() which accepts hex sha1s.

Now, manifests that include copyfile directives will be copied to
the appropriate destinations even if the repositories are pinned to SHA1
revisions.

Change-Id: Iaee9db3bbe33f1a1340d94a68ffdd93bdd6489c7
diff --git a/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestRefUpdatedListener.java b/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestRefUpdatedListener.java
index c376050..2f1dfaa 100644
--- a/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestRefUpdatedListener.java
+++ b/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestRefUpdatedListener.java
@@ -403,11 +403,12 @@
         throws GitAPIException, IOException {
       Repository repo = openRepository(repoName);
       Ref r = repo.findRef(ref);
-      if (r == null || r.getObjectId() == null) {
+      ObjectId objectId = r == null ? repo.resolve(ref) : r.getObjectId();
+      if (objectId == null) {
         throw new RevisionSyntaxException(
             String.format("repo %s does not have ref %s", repo.toString(), ref), ref);
       }
-      RevCommit commit = repo.parseCommit(r.getObjectId());
+      RevCommit commit = repo.parseCommit(objectId);
       TreeWalk tw = TreeWalk.forPath(repo, path, commit.getTree());
       return new RemoteFile(
           tw.getObjectReader().open(tw.getObjectId(0)).getCachedBytes(Integer.MAX_VALUE),
diff --git a/javatests/com/googlesource/gerrit/plugins/supermanifest/RepoSuperManifestIT.java b/javatests/com/googlesource/gerrit/plugins/supermanifest/RepoSuperManifestIT.java
index 698da79..d340093 100644
--- a/javatests/com/googlesource/gerrit/plugins/supermanifest/RepoSuperManifestIT.java
+++ b/javatests/com/googlesource/gerrit/plugins/supermanifest/RepoSuperManifestIT.java
@@ -178,6 +178,57 @@
   }
 
   @Test
+  public void basicFunctionalityWorksWithCopyFileWithBareSha1() throws Exception {
+    setupTestRepos("project");
+
+    // Make sure the manifest exists so the configuration loads successfully.
+    Project.NameKey manifestKey = projectOperations.newProject().name(name("manifest")).create();
+    TestRepository<InMemoryRepository> manifestRepo = cloneProject(manifestKey, admin);
+
+    Project.NameKey superKey = projectOperations.newProject().name(name("superproject")).create();
+    cloneProject(superKey, admin);
+
+    pushConfig(
+        "[superproject \""
+            + superKey.get()
+            + ":refs/heads/destbranch\"]\n"
+            + "  srcRepo = "
+            + manifestKey.get()
+            + "\n"
+            + "  srcRef = refs/heads/srcbranch\n"
+            + "  srcPath = default.xml\n");
+
+    String remoteXml = "  <remote name=\"origin\" fetch=\"" + canonicalWebUrl.get() + "\" />\n";
+    String defaultXml = "  <default remote=\"origin\" revision=\"refs/heads/master\" />\n";
+    // XML change will trigger commit to superproject.
+    String xml =
+        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+            + "<manifest>\n"
+            + remoteXml
+            + defaultXml
+            + "  <project name=\""
+            + testRepoKeys[0].get()
+            + "\" path=\"project1\""
+            + " revision=\""
+            + testRepoCommits[0]
+            + "\""
+            + ">\n"
+            + "<copyfile src=\"file0\" dest=\"dest\" />"
+            + "</project>\n"
+            + "</manifest>\n";
+
+    pushFactory
+        .create(admin.newIdent(), manifestRepo, "Subject", "default.xml", xml)
+        .to("refs/heads/srcbranch")
+        .assertOkStatus();
+
+    BranchApi branch = gApi.projects().name(superKey.get()).branch("refs/heads/destbranch");
+    assertThat(branch.file("project1").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
+    assertThat(branch.file("dest").asString()).isEqualTo("file");
+    assertThrows(ResourceNotFoundException.class, () -> branch.file("project2"));
+  }
+
+  @Test
   public void httpEndpoint() throws Exception {
     setupTestRepos("project");