Merge "Limit the length of abbreviated label names"
diff --git a/0001-Replace-native-http-git-_archive-with-Skylark-rules.patch b/0001-Replace-native-http-git-_archive-with-Skylark-rules.patch
deleted file mode 100644
index 3ccf5cd..0000000
--- a/0001-Replace-native-http-git-_archive-with-Skylark-rules.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-Date: Wed, 30 May 2018 21:22:18 +0200
-Subject: [PATCH] Replace native {http,git}_archive with Skylark rules
-
-See [1] for more details.
-
-Test Plan:
-
-* Apply this CL on Bazel master: [2] and build bazel
-* Run with this custom built bazel version:
-
-  $ bazel test //javatests/...
-  $ bazel test //closure/...
-
-[1] https://groups.google.com/d/topic/bazel-discuss/dO2MHQLwJF0/discussion
-[2] https://bazel-review.googlesource.com/#/c/bazel/+/55932/
----
- closure/repositories.bzl | 23 ++++++++++++-----------
- 1 file changed, 12 insertions(+), 11 deletions(-)
-
-diff --git a/closure/repositories.bzl b/closure/repositories.bzl
-index 9b84a72..2816fb6 100644
---- closure/repositories.bzl
-+++ closure/repositories.bzl
-@@ -14,6 +14,7 @@
- 
- """External dependencies for Closure Rules."""
- 
-+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file")
- load("//closure/private:java_import_external.bzl", "java_import_external")
- load("//closure/private:platform_http_file.bzl", "platform_http_file")
- load("//closure:filegroup_external.bzl", "filegroup_external")
-@@ -405,7 +406,7 @@ def com_google_common_html_types():
-   )
- 
- def com_google_common_html_types_html_proto():
--  native.http_file(
-+  http_file(
-       name = "com_google_common_html_types_html_proto",
-       sha256 = "6ece202f11574e37d0c31d9cf2e9e11a0dbc9218766d50d211059ebd495b49c3",
-       urls = [
-@@ -633,7 +634,7 @@ def com_google_javascript_closure_compiler():
- 
- def com_google_javascript_closure_library():
-   # After updating: bazel run //closure/library:regenerate -- "$PWD"
--  native.new_http_archive(
-+  http_archive(
-       name = "com_google_javascript_closure_library",
-       urls = [
-           "https://mirror.bazel.build/github.com/google/closure-library/archive/v20180405.tar.gz",
-@@ -658,7 +659,7 @@ def com_google_jsinterop_annotations():
- 
- def com_google_protobuf():
-   # Note: Protobuf 3.6.0+ is going to use C++11
--  native.http_archive(
-+  http_archive(
-       name = "com_google_protobuf",
-       strip_prefix = "protobuf-3.5.1",
-       sha256 = "826425182ee43990731217b917c5c3ea7190cfda141af4869e6d4ad9085a740f",
-@@ -669,7 +670,7 @@ def com_google_protobuf():
-   )
- 
- def com_google_protobuf_js():
--  native.new_http_archive(
-+  http_archive(
-       name = "com_google_protobuf_js",
-       urls = [
-           "https://mirror.bazel.build/github.com/google/protobuf/archive/v3.5.1.tar.gz",
-@@ -722,7 +723,7 @@ def com_google_template_soy():
-   )
- 
- def com_google_template_soy_jssrc():
--  native.new_http_archive(
-+  http_archive(
-       name = "com_google_template_soy_jssrc",
-       sha256 = "c76ab4cb6e46a7c76336640b3c40d6897b420209a6c0905cdcd32533dda8126a",
-       urls = [
-@@ -757,7 +758,7 @@ def com_squareup_javapoet():
-   )
- 
- def fonts_noto_hinted_deb():
--  native.http_file(
-+  http_file(
-       name = "fonts_noto_hinted_deb",
-       urls = [
-           "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/f/fonts-noto/fonts-noto-hinted_20161116-1_all.deb",
-@@ -767,7 +768,7 @@ def fonts_noto_hinted_deb():
-   )
- 
- def fonts_noto_mono_deb():
--  native.http_file(
-+  http_file(
-       name = "fonts_noto_mono_deb",
-       urls = [
-           "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/f/fonts-noto/fonts-noto-mono_20161116-1_all.deb",
-@@ -801,7 +802,7 @@ def javax_inject():
-   )
- 
- def libexpat_amd64_deb():
--  native.http_file(
-+  http_file(
-       name = "libexpat_amd64_deb",
-       urls = [
-           "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/e/expat/libexpat1_2.1.0-6+deb8u3_amd64.deb",
-@@ -811,7 +812,7 @@ def libexpat_amd64_deb():
-   )
- 
- def libfontconfig_amd64_deb():
--  native.http_file(
-+  http_file(
-       name = "libfontconfig_amd64_deb",
-       urls = [
-           "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/f/fontconfig/libfontconfig1_2.11.0-6.3+deb8u1_amd64.deb",
-@@ -821,7 +822,7 @@ def libfontconfig_amd64_deb():
-   )
- 
- def libfreetype_amd64_deb():
--  native.http_file(
-+  http_file(
-       name = "libfreetype_amd64_deb",
-       urls = [
-           "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/f/freetype/libfreetype6_2.5.2-3+deb8u1_amd64.deb",
-@@ -831,7 +832,7 @@ def libfreetype_amd64_deb():
-   )
- 
- def libpng_amd64_deb():
--  native.http_file(
-+  http_file(
-       name = "libpng_amd64_deb",
-       urls = [
-           "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/libp/libpng/libpng12-0_1.2.50-2+deb8u2_amd64.deb",
--- 
-2.16.3
-
diff --git a/0002-Bump-Dagger-to-2.14.1-to-support-Java-9.patch b/0002-Bump-Dagger-to-2.14.1-to-support-Java-9.patch
deleted file mode 100644
index df6780d..0000000
--- a/0002-Bump-Dagger-to-2.14.1-to-support-Java-9.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-Date: Thu, 21 Jun 2018 19:29:13 +0200
-Subject: [PATCH 2/2] Bump Dagger to 2.14.1 to support Java 9
-
-Closes #275
----
- closure/repositories.bzl | 41 +++++++++++++++++++++++++++++------------
- 1 file changed, 29 insertions(+), 12 deletions(-)
-
-diff --git a/closure/repositories.bzl b/closure/repositories.bzl
-index 2816fb6..fe63b6f 100644
---- closure/repositories.bzl
-+++ closure/repositories.bzl
-@@ -35,6 +35,7 @@ def closure_repositories(
-     omit_com_google_dagger=False,
-     omit_com_google_dagger_compiler=False,
-     omit_com_google_dagger_producers=False,
-+    omit_com_google_dagger_spi=False,
-     omit_com_google_errorprone_error_prone_annotations=False,
-     omit_com_google_errorprone_javac_shaded=False,
-     omit_com_google_guava=False,
-@@ -101,6 +102,8 @@ def closure_repositories(
-     com_google_dagger_compiler()
-   if not omit_com_google_dagger_producers:
-     com_google_dagger_producers()
-+  if not omit_com_google_dagger_spi:
-+    com_google_dagger_spi()
-   if not omit_com_google_errorprone_error_prone_annotations:
-     com_google_errorprone_error_prone_annotations()
-   if not omit_com_google_errorprone_javac_shaded:
-@@ -418,10 +421,10 @@ def com_google_common_html_types_html_proto():
- def com_google_dagger():
-   java_import_external(
-       name = "com_google_dagger",
--      jar_sha256 = "8b7806518bed270950002158934fbd8281725ee09909442f2f22b58520b667a7",
-+      jar_sha256 = "374cfee26c9c93f44caa1946583c9edc135bb9a42838476522551ec46aa55c7c",
-       jar_urls = [
--          "https://mirror.bazel.build/repo1.maven.org/maven2/com/google/dagger/dagger/2.9/dagger-2.9.jar",
--          "https://repo1.maven.org/maven2/com/google/dagger/dagger/2.9/dagger-2.9.jar",
-+          "https://mirror.bazel.build/repo1.maven.org/maven2/com/google/dagger/dagger/2.14.1/dagger-2.14.1.jar",
-+          "https://repo1.maven.org/maven2/com/google/dagger/dagger/2.14.1/dagger-2.14.1.jar",
-       ],
-       licenses = ["notice"],  # Apache 2.0
-       deps = ["@javax_inject"],
-@@ -441,17 +444,20 @@ def com_google_dagger():
- def com_google_dagger_compiler():
-   java_import_external(
-       name = "com_google_dagger_compiler",
--      jar_sha256 = "afe356def27710db5b60cad8e7a6c06510dc3d3b854f30397749cbf0d0e71315",
-+      jar_sha256 = "ff16d55273e375349537fc82292b00de04d8a2caca2d4aa6c642692b1a68194d",
-       jar_urls = [
--          "https://mirror.bazel.build/repo1.maven.org/maven2/com/google/dagger/dagger-compiler/2.9/dagger-compiler-2.9.jar",
--          "https://repo1.maven.org/maven2/com/google/dagger/dagger-compiler/2.9/dagger-compiler-2.9.jar",
-+          "https://mirror.bazel.build/repo1.maven.org/maven2/com/google/dagger/dagger-compiler/2.14.1/dagger-compiler-2.14.1.jar",
-+          "https://repo1.maven.org/maven2/com/google/dagger/dagger-compiler/2.14.1/dagger-compiler-2.14.1.jar",
-       ],
-       licenses = ["notice"],  # Apache 2.0
-       deps = [
-           "@com_google_code_findbugs_jsr305",
-           "@com_google_dagger//:runtime",
-           "@com_google_dagger_producers//:runtime",
-+          "@com_google_dagger_spi",
-           "@com_google_guava",
-+          "@com_google_java_format",
-+          "@com_squareup_javapoet",
-       ],
-       extra_build_file_content = "\n".join([
-           "java_plugin(",
-@@ -471,10 +477,10 @@ def com_google_dagger_compiler():
- def com_google_dagger_producers():
-   java_import_external(
-       name = "com_google_dagger_producers",
--      jar_sha256 = "b452dc1b95dd02f6272e97b15d1bd35d92b5f484a7d69bb73887b6c6699d8843",
-+      jar_sha256 = "96f950bc4b94d013b0c538632a4bc630f33eda8b01f63ae752b76c5e48783859",
-       jar_urls = [
--          "https://mirror.bazel.build/repo1.maven.org/maven2/com/google/dagger/dagger-producers/2.9/dagger-producers-2.9.jar",
--          "https://repo1.maven.org/maven2/com/google/dagger/dagger-producers/2.9/dagger-producers-2.9.jar",
-+          "https://mirror.bazel.build/repo1.maven.org/maven2/com/google/dagger/dagger-producers/2.14.1/dagger-producers-2.14.1.jar",
-+          "https://repo1.maven.org/maven2/com/google/dagger/dagger-producers/2.14.1/dagger-producers-2.14.1.jar",
-       ],
-       licenses = ["notice"],  # Apache 2.0
-       deps = [
-@@ -495,6 +501,17 @@ def com_google_dagger_producers():
-       ]),
-   )
- 
-+def com_google_dagger_spi():
-+  java_import_external(
-+      name = "com_google_dagger_spi",
-+      jar_sha256 = "6a20d6c6620fefe50747e9e910e0d0c178cf39d76b67ccffb505ac9a167302cb",
-+      jar_urls = [
-+          "https://mirror.bazel.build/repo1.maven.org/maven2/com/google/dagger/dagger-spi/2.14.1/dagger-spi-2.14.1.jar",
-+          "https://repo1.maven.org/maven2/com/google/dagger/dagger-spi/2.14.1/dagger-spi-2.14.1.jar",
-+      ],
-+      licenses = ["notice"],  # Apache 2.0
-+  )
-+
- def com_google_errorprone_error_prone_annotations():
-   java_import_external(
-       name = "com_google_errorprone_error_prone_annotations",
-@@ -749,10 +766,10 @@ def com_ibm_icu_icu4j():
- def com_squareup_javapoet():
-   java_import_external(
-       name = "com_squareup_javapoet",
--      jar_sha256 = "2f671d5f056f04922feff78dd60c34979fc9863b16ad706551a9b68842c1a3d0",
-+      jar_sha256 = "5bb5abdfe4366c15c0da3332c57d484e238bd48260d6f9d6acf2b08fdde1efea",
-       jar_urls = [
--          "https://mirror.bazel.build/repo1.maven.org/maven2/com/squareup/javapoet/1.7.0/javapoet-1.7.0.jar",
--          "https://repo1.maven.org/maven2/com/squareup/javapoet/1.7.0/javapoet-1.7.0.jar",
-+          "https://mirror.bazel.build/repo1.maven.org/maven2/com/squareup/javapoet/1.9.0/javapoet-1.9.0.jar",
-+          "https://repo1.maven.org/maven2/com/squareup/javapoet/1.9.0/javapoet-1.9.0.jar",
-       ],
-       licenses = ["notice"],  # Apache 2.0
-   )
--- 
-2.16.3
-
diff --git a/WORKSPACE b/WORKSPACE
index 70200d1..dfe2a45 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -14,19 +14,9 @@
 
 http_archive(
     name = "io_bazel_rules_closure",
-    build_file_content = "\n".join([
-        "exports_files([",
-        "    \"0001-Replace-native-http-git-_archive-with-Skylark-rules.patch\",",
-        "    \"0002-Bump-Dagger-to-2.14.1-to-support-Java-9.patch\",",
-        "])",
-    ]),
-    patches = [
-        "//:0001-Replace-native-http-git-_archive-with-Skylark-rules.patch",
-        "//:0002-Bump-Dagger-to-2.14.1-to-support-Java-9.patch",
-    ],
-    sha256 = "a80acb69c63d5f6437b099c111480a4493bad4592015af2127a2f49fb7512d8d",
-    strip_prefix = "rules_closure-0.7.0",
-    url = "https://github.com/bazelbuild/rules_closure/archive/0.7.0.tar.gz",
+    sha256 = "4dd84dd2bdd6c9f56cb5a475d504ea31d199c34309e202e9379501d01c3067e5",
+    strip_prefix = "rules_closure-3103a773820b59b76345f94c231cb213e0d404e2",
+    url = "https://github.com/bazelbuild/rules_closure/archive/3103a773820b59b76345f94c231cb213e0d404e2.tar.gz",
 )
 
 # File is specific to Polymer and copied from the Closure Github -- should be
diff --git a/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java b/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java
index bf68026..136b4ae 100644
--- a/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java
+++ b/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java
@@ -33,7 +33,6 @@
 import com.google.gerrit.server.PeerDaemonUser;
 import com.google.gerrit.server.account.CapabilityCollection;
 import com.google.gerrit.server.cache.PerThreadCache;
-import com.google.gerrit.server.permissions.PermissionBackendCondition.WithUser;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/restapi/account/GetDiffPreferences.java b/java/com/google/gerrit/server/restapi/account/GetDiffPreferences.java
index a8d14f6..40201a8 100644
--- a/java/com/google/gerrit/server/restapi/account/GetDiffPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/GetDiffPreferences.java
@@ -50,7 +50,7 @@
   @Override
   public DiffPreferencesInfo apply(AccountResource rsrc)
       throws RestApiException, ConfigInvalidException, IOException, PermissionBackendException {
-    if (self.get() != rsrc.getUser()) {
+    if (!self.get().hasSameAccountId(rsrc.getUser())) {
       permissionBackend.currentUser().check(GlobalPermission.ADMINISTRATE_SERVER);
     }
 
diff --git a/java/com/google/gerrit/server/restapi/account/GetEmails.java b/java/com/google/gerrit/server/restapi/account/GetEmails.java
index 63d042c..85262ee 100644
--- a/java/com/google/gerrit/server/restapi/account/GetEmails.java
+++ b/java/com/google/gerrit/server/restapi/account/GetEmails.java
@@ -44,7 +44,7 @@
   @Override
   public List<EmailInfo> apply(AccountResource rsrc)
       throws AuthException, PermissionBackendException {
-    if (self.get() != rsrc.getUser()) {
+    if (!self.get().hasSameAccountId(rsrc.getUser())) {
       permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT);
     }
 
diff --git a/java/com/google/gerrit/server/restapi/account/PutPreferred.java b/java/com/google/gerrit/server/restapi/account/PutPreferred.java
index 51d28ed..a828987 100644
--- a/java/com/google/gerrit/server/restapi/account/PutPreferred.java
+++ b/java/com/google/gerrit/server/restapi/account/PutPreferred.java
@@ -71,7 +71,7 @@
   public Response<String> apply(AccountResource.Email rsrc, Input input)
       throws RestApiException, OrmException, IOException, PermissionBackendException,
           ConfigInvalidException {
-    if (self.get() != rsrc.getUser()) {
+    if (!self.get().hasSameAccountId(rsrc.getUser())) {
       permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT);
     }
     return apply(rsrc.getUser(), rsrc.getEmail());
diff --git a/java/com/google/gerrit/server/restapi/account/SetDiffPreferences.java b/java/com/google/gerrit/server/restapi/account/SetDiffPreferences.java
index 6aa88de..f4fa354 100644
--- a/java/com/google/gerrit/server/restapi/account/SetDiffPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/SetDiffPreferences.java
@@ -57,7 +57,7 @@
   public DiffPreferencesInfo apply(AccountResource rsrc, DiffPreferencesInfo input)
       throws RestApiException, ConfigInvalidException, RepositoryNotFoundException, IOException,
           PermissionBackendException, OrmException {
-    if (self.get() != rsrc.getUser()) {
+    if (!self.get().hasSameAccountId(rsrc.getUser())) {
       permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT);
     }
 
diff --git a/java/com/google/gerrit/server/restapi/account/SetEditPreferences.java b/java/com/google/gerrit/server/restapi/account/SetEditPreferences.java
index dad6e0f..4e3f1d5 100644
--- a/java/com/google/gerrit/server/restapi/account/SetEditPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/SetEditPreferences.java
@@ -58,7 +58,7 @@
   public EditPreferencesInfo apply(AccountResource rsrc, EditPreferencesInfo input)
       throws RestApiException, RepositoryNotFoundException, IOException, ConfigInvalidException,
           PermissionBackendException, OrmException {
-    if (self.get() != rsrc.getUser()) {
+    if (!self.get().hasSameAccountId(rsrc.getUser())) {
       permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT);
     }
 
diff --git a/java/com/google/gerrit/server/restapi/account/SetPreferences.java b/java/com/google/gerrit/server/restapi/account/SetPreferences.java
index 11ecfdb..fccdabe 100644
--- a/java/com/google/gerrit/server/restapi/account/SetPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/SetPreferences.java
@@ -63,7 +63,7 @@
   public GeneralPreferencesInfo apply(AccountResource rsrc, GeneralPreferencesInfo input)
       throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException,
           OrmException {
-    if (self.get() != rsrc.getUser()) {
+    if (!self.get().hasSameAccountId(rsrc.getUser())) {
       permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT);
     }
 
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
index 7b49e1d..98e466e 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
@@ -67,7 +67,7 @@
     Config elasticsearchConfig = new Config(config);
     InMemoryModule.setDefaults(elasticsearchConfig);
     String indicesPrefix = testName();
-    ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
+    ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix, "changeme");
     return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
   }
 }
diff --git a/lib/jgit/jgit.bzl b/lib/jgit/jgit.bzl
index be90acb..384469c 100644
--- a/lib/jgit/jgit.bzl
+++ b/lib/jgit/jgit.bzl
@@ -2,7 +2,7 @@
 
 _JGIT_VERS = "5.0.1.201806211838-r"
 
-_DOC_VERS = "5.0.0.201806131550-r"  # Set to _JGIT_VERS unless using a snapshot
+_DOC_VERS = _JGIT_VERS  # Set to _JGIT_VERS unless using a snapshot
 
 JGIT_DOC_URL = "http://download.eclipse.org/jgit/site/" + _DOC_VERS + "/apidocs"
 
diff --git a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html
index 61df877..45bc5f6 100644
--- a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html
+++ b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html
@@ -45,7 +45,7 @@
       .header,
       #deletedContainer {
         align-items: center;
-        background: #f6f6f6;
+        background: var(--table-header-background-color);
         border-bottom: 1px dotted var(--border-color);
         display: flex;
         justify-content: space-between;
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.html b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.html
index 332121f..7eb2b6c 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.html
@@ -172,10 +172,13 @@
     <td class="cell project"
         hidden$="[[isColumnHidden('Project', visibleChangeTableColumns)]]">
       <a class="fullProject" href$="[[_computeProjectURL(change)]]">
-        [[change.project]]
+        [[_computeProjectDisplay(change)]]
       </a>
-      <a class="truncatedProject" href$="[[_computeProjectURL(change)]]">
-        [[_computeTruncatedProject(change.project)]]
+      <a
+          class="truncatedProject"
+          href$="[[_computeProjectURL(change)]]"
+          title$="[[_computeProjectDisplay(change)]]">
+        [[_computeProjectDisplay(change, 'true')]]
       </a>
     </td>
     <td class="cell branch"
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
index 53cc990..b73a237 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
@@ -137,9 +137,21 @@
       return Gerrit.Nav.getUrlForTopic(change.topic, change.internalHost);
     },
 
-    _computeTruncatedProject(project) {
-      if (!project) { return ''; }
-      return this.truncatePath(project, 2);
+    /**
+     * Computes the display string for the project column. If there is a host
+     * specified in the change detail, the string will be prefixed with it.
+     *
+     * @param {!Object} change
+     * @param {string=} truncate whether or not the project name should be
+     *     truncated. If this value is truthy, the name will be truncated.
+     * @return {string}
+     */
+    _computeProjectDisplay(change, truncate) {
+      if (!change || !change.project) { return ''; }
+      let str = '';
+      if (change.internalHost) { str += change.internalHost + '/'; }
+      str += truncate ? this.truncatePath(change.project, 2) : change.project;
+      return str;
     },
 
     _computeAccountStatusString(account) {
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
index 4fa6ff5..f4c66c7 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
@@ -273,5 +273,19 @@
       assert.deepEqual(Gerrit.Nav.getUrlForTopic.lastCall.args,
           [change.topic, change.internalHost]);
     });
+
+    test('_computeProjectDisplay', () => {
+      const change = {
+        project: 'a/test/repo',
+        internalHost: 'host',
+      };
+      assert.equal(element._computeProjectDisplay(change), 'host/a/test/repo');
+      assert.equal(element._computeProjectDisplay(change, true),
+          'host/…/test/repo');
+      delete change.internalHost;
+      assert.equal(element._computeProjectDisplay(change), 'a/test/repo');
+      assert.equal(element._computeProjectDisplay(change, true),
+          '…/test/repo');
+    });
   });
 </script>