Allow a Link trailer to be used as an alternative change ID trailer

In some projects it may be desirable for the trailer to contain a link to
the Gerrit review page so that it is convenient to access the review page
starting from the commit message. The Link trailer is a standard trailer
used for inserting links in the commit message, which has been adopted by
the Linux kernel among other projects. For example, the Linux kernel has a
policy about linking to the mailing list archive with Link trailers:
https://www.kernel.org/doc/html/latest/maintainer/configure-git.html#creating-commit-links-to-lore-kernel-org

This change makes Gerrit interoperate well with the Link trailer. Specifically,
it teaches the Gerrit server to recognize trailers of the form:

    Link: https://gerrit-review.googlesource.com/id/I78e884a944cedb5144f661a057e4829c8f84e933

as well as the existing Change-Id trailer, teaches the server to recognize
/id/ as a search prefix for change IDs and modifies the commit-msg hook
to optionally add a Link trailer (using a server URL provided in the
property gerrit.reviewUrl) instead of the Change-Id trailer.

Change-Id: I78e884a944cedb5144f661a057e4829c8f84e933
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
index 3ffd819..5261426 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
@@ -160,6 +160,8 @@
    */
   QUERY_LEGACY_SUFFIX: /^\/q\/.+,n,z$/,
 
+  CHANGE_ID_QUERY: /^\/id\/(I[0-9a-f]{40})$/,
+
   // Matches /c/<changeNum>/[<basePatchNum>..][<patchNum>][/].
   CHANGE_LEGACY: /^\/c\/(\d+)\/?(((-?\d+|edit)(\.\.(\d+|edit))?))?\/?$/,
   CHANGE_NUMBER_LEGACY: /^\/(\d+)\/?/,
@@ -1018,6 +1020,8 @@
 
     this._mapRoute(RoutePattern.QUERY, '_handleQueryRoute');
 
+    this._mapRoute(RoutePattern.CHANGE_ID_QUERY, '_handleChangeIdQueryRoute');
+
     this._mapRoute(RoutePattern.DIFF_LEGACY_LINENUM, '_handleLegacyLinenum');
 
     this._mapRoute(
@@ -1510,6 +1514,16 @@
     });
   }
 
+  _handleChangeIdQueryRoute(data: PageContextWithQueryMap) {
+    // TODO(pcc): This will need to indicate that this was a change ID query if
+    // standard queries gain the ability to search places like commit messages
+    // for change IDs.
+    this._setParams({
+      view: GerritNav.View.SEARCH,
+      query: data.params[0],
+    });
+  }
+
   _handleQueryLegacySuffixRoute(ctx: PageContextWithQueryMap) {
     this._redirect(ctx.path.replace(LEGACY_QUERY_SUFFIX_PATTERN, ''));
   }