Merge branch 'stable-3.10' into stable-3.11

* stable-3.10:
  Handle annotated tag updates in shared ref logging

Change-Id: Ib59e1658582ab668caab135514657c34b2735a5b
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLogger.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLogger.java
index 691d8b1..f4acb91 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLogger.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLogger.java
@@ -16,6 +16,7 @@
 
 import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
 import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
+import static org.eclipse.jgit.lib.Constants.OBJ_TAG;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.flogger.FluentLogger;
@@ -38,6 +39,7 @@
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevTag;
 import org.eclipse.jgit.revwalk.RevWalk;
 
 /**
@@ -72,9 +74,9 @@
   /**
    * {@inheritDoc}.
    *
-   * <p>Only logs commits and blob refs (throws {@link IncorrectObjectTypeException} for any other
-   * unexpected type). Additionally, it hydrates commits with information about the committer and
-   * commit message.
+   * <p>Only logs commits, annotated tags and blob refs (throws {@link IncorrectObjectTypeException}
+   * for any other unexpected type). Additionally, it hydrates commits and annotated tags with
+   * information about the committer and commit message.
    *
    * <p>Logs Json serialization of {@link SharedRefLogEntry.UpdateRef}
    */
@@ -88,6 +90,11 @@
         if (newRefValue != null) {
           int objectType = walk.parseAny(newRefValue).getType();
           switch (objectType) {
+            case OBJ_TAG:
+              RevTag revTag = walk.parseTag(newRefValue);
+              committer = CommonConverters.toGitPerson(revTag.getTaggerIdent());
+              commitMessage = revTag.getShortMessage();
+              break;
             case OBJ_COMMIT:
               RevCommit commit = walk.parseCommit(newRefValue);
               committer = CommonConverters.toGitPerson(commit.getCommitterIdent());
diff --git a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLoggerTest.java b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLoggerTest.java
index 5b9a9dd..3a7cba9 100644
--- a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLoggerTest.java
+++ b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLoggerTest.java
@@ -15,6 +15,7 @@
 package com.gerritforge.gerrit.globalrefdb.validation;
 
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.TAG_MODIFICATION;
 
 import com.google.gerrit.acceptance.AbstractDaemonTest;
 import com.google.gerrit.acceptance.PushOneCommit;
@@ -22,6 +23,7 @@
 import com.google.gerrit.json.OutputFormat;
 import com.google.gerrit.server.Sequence;
 import com.google.gerrit.server.config.SitePaths;
+import com.google.gerrit.server.update.context.RefUpdateContext;
 import com.google.gerrit.server.util.SystemLog;
 import com.google.gson.Gson;
 import java.io.IOException;
@@ -32,9 +34,14 @@
 import org.apache.log4j.Logger;
 import org.apache.log4j.PatternLayout;
 import org.apache.log4j.WriterAppender;
+import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefUpdate;
 import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.TagBuilder;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -143,6 +150,45 @@
     assertThat(gotLogEntry.refName).isEqualTo(refName);
   }
 
+  @Test
+  public void shouldLogAnnotatedTagRef() throws Exception {
+    final String tagRefName = "refs/tags/v1.0";
+    final String refName = "refs/remotes/origin/master";
+    PushOneCommit.Result result = pushTo(refName);
+    ObjectId commitId = result.getCommit().toObjectId();
+    PersonIdent taggerIdent = new PersonIdent("Tagger123", "tagger@test.com");
+    String message = "Release v1.0";
+    ObjectId tagId;
+    try (Repository repository = repoManager.openRepository(project);
+        ObjectInserter inserter = repository.newObjectInserter();
+        RefUpdateContext ctx = RefUpdateContext.open(TAG_MODIFICATION)) {
+      TagBuilder tag = new TagBuilder();
+      tag.setTag("v1.0");
+      tag.setMessage(message);
+      tag.setTagger(taggerIdent);
+      tag.setObjectId(commitId, Constants.OBJ_COMMIT);
+      tagId = inserter.insert(tag);
+      inserter.flush();
+
+      RefUpdate ru = repository.updateRef(tagRefName);
+      ru.setNewObjectId(tagId);
+      ru.update();
+
+      Ref tagRef = repository.exactRef(tagRefName);
+      log4jSharedRefLogger.logRefUpdate(project.get(), tagRef, tagId);
+    }
+
+    SharedRefLogEntry.UpdateRef gotLogEntry =
+        gson.fromJson(logWriter.toString(), SharedRefLogEntry.UpdateRef.class);
+
+    assertThat(gotLogEntry.type).isEqualTo(SharedRefLogEntry.Type.UPDATE_REF);
+    assertThat(gotLogEntry.projectName).isEqualTo(project.get());
+    assertThat(gotLogEntry.refName).isEqualTo(tagRefName);
+    assertThat(gotLogEntry.newId).isEqualTo(tagId.getName());
+    assertThat(gotLogEntry.comment).isEqualTo(message);
+    assertThat(gotLogEntry.committer.name).isEqualTo(taggerIdent.getName());
+  }
+
   private Log4jSharedRefLogger newLog4jSharedRefLogger() throws IOException {
     final Log4jSharedRefLogger log4jSharedRefLogger =
         new Log4jSharedRefLogger(new SystemLog(new SitePaths(newPath()), baseConfig), repoManager);