Add macro for output of 'git describe'

'@GIT_DESCRIPTION@' can now be used as a placeholder for the output of
'git describe'. If git doesn't find any names to describe this
revision '@GIT_DESCRIPTION@' is replaced by the revision ID.

Change-Id: Ic942e827af7207396f3fa8bf341b131a27df8798
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocLoader.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocLoader.java
index 13949e1..e6064c2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocLoader.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocLoader.java
@@ -16,6 +16,7 @@
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.Weigher;
@@ -35,8 +36,9 @@
 import com.googlesource.gerrit.plugins.xdocs.formatter.Formatters;
 import com.googlesource.gerrit.plugins.xdocs.formatter.Formatters.FormatterProvider;
 
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.diff.RawText;
-import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.ObjectReader;
@@ -47,6 +49,7 @@
 import org.eclipse.jgit.treewalk.TreeWalk;
 import org.eclipse.jgit.treewalk.filter.PathFilter;
 
+import java.io.IOException;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -111,7 +114,8 @@
             String html =
                 formatter.get().format(key.getProject().get(),
                     abbrRevId, formatterCfg,
-                    replaceMacros(key.getProject(), abbrRevId, bytes));
+                    replaceMacros(repo, key.getProject(), key.getRevId(),
+                        abbrRevId, bytes));
             return getAsHtmlResource(html, commit.getCommitTime());
           } finally {
             reader.release();
@@ -127,8 +131,9 @@
     }
   }
 
-  private String replaceMacros(Project.NameKey project, String abbrRevId,
-      byte[] raw) {
+  private String replaceMacros(Repository repo, Project.NameKey project,
+      ObjectId revId, String abbrRevId, byte[] raw) throws GitAPIException,
+      IOException {
     Map<String, String> macros = Maps.newHashMap();
 
     String url = webUrl.get();
@@ -140,6 +145,9 @@
     macros.put("PROJECT", project.get());
     macros.put("PROJECT_URL", url + "#/admin/projects/" + project.get());
     macros.put("REVISION", abbrRevId);
+    macros.put("GIT_DESCRIPTION", MoreObjects.firstNonNull(
+        (new Git(repo)).describe().setTarget(revId).call(), abbrRevId));
+
 
     Matcher m = Pattern.compile("(\\\\)?@([A-Z_]+)@")
         .matcher(new String(raw, UTF_8));
diff --git a/src/main/resources/Documentation/user.md b/src/main/resources/Documentation/user.md
index fc31782..9cd5c3e 100644
--- a/src/main/resources/Documentation/user.md
+++ b/src/main/resources/Documentation/user.md
@@ -78,3 +78,6 @@
 * `\@PROJECT@`: The name of the project from which the documentation is shown.
 * `\@PROJECT_URL@`: The web URL of the project from which the documentation is shown.
 * `\@REVISION@`: The abbreviated ID of the revision from which the documentation is shown.
+* `\@GIT_DESCRIPTION@`: The output of `git describe` on the revision
+  from which the documentation is shown, or the abbreviated ID of the
+  revision if no names are found.