Merge "Fix data binding in gr-file-list, introduced in 86117"
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
index 3af3bca..41c9dc2 100644
--- a/Documentation/access-control.txt
+++ b/Documentation/access-control.txt
@@ -615,11 +615,10 @@
 a new commit on their local system, so in practice they must also
 have the `Read` access granted to upload a change.
 
-For an open source, public Gerrit installation, it is common to
-grant `Read` and `Push` for `+refs/for/refs/heads/*+`
-to `Registered Users` in the `All-Projects` ACL.  For more
-private installations, its common to simply grant `Read` and
-`Push` for `+refs/for/refs/heads/*+` to all users of a project.
+For an open source, public Gerrit installation, it is common to grant
+`Push` for `+refs/for/refs/heads/*+` to `Registered Users` in the
+`All-Projects` ACL.  For more private installations, its common to
+grant `Push` for `+refs/for/refs/heads/*+` to all users of a project.
 
 * Force option
 +
diff --git a/Documentation/rest-api-access.txt b/Documentation/rest-api-access.txt
index 4531446..07a3d78 100644
--- a/Documentation/rest-api-access.txt
+++ b/Documentation/rest-api-access.txt
@@ -334,10 +334,10 @@
 |`force`        |not set if `false`|
 Whether the force flag is set.
 |`min`          |
-not set if range if empty (from `0` to `0`) or not set|
+not set if range is empty (from `0` to `0`) or not set|
 The min value of the permission range.
 |`max`          |
-not set if range if empty (from `0` to `0`) or not set|
+not set if range is empty (from `0` to `0`) or not set|
 The max value of the permission range.
 |==================================
 
diff --git a/ReleaseNotes/ReleaseNotes-2.13.2.txt b/ReleaseNotes/ReleaseNotes-2.13.2.txt
index 87e902c..c7be976 100644
--- a/ReleaseNotes/ReleaseNotes-2.13.2.txt
+++ b/ReleaseNotes/ReleaseNotes-2.13.2.txt
@@ -20,6 +20,18 @@
 Project watches were being read from the git backend by default, but the
 migration to git is not yet completed.
 
+* link:https://bugs.chromium.org/p/gerrit/issues/detail?id=4632[Issue 4632]:
+Fix server error when deleting multiple SSH keys from the Web UI.
++
+Attempting to delete multiple keys in parallel resulted in a lock failure
+when removing the keys from the git backend.
+
+* link:https://bugs.chromium.org/p/gerrit/issues/detail?id=4645[Issue 4645]:
+Fix malformed account suggestions.
++
+If the query contained several query terms and one of the query terms was
+a substring of 'strong', the suggestion was malformed.
+
 * Hooks plugin: Fix incorrect value passed to `--change-url` parameter.
 +
 The URL was being generated using the change's Change-Id rather than the
diff --git a/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/GerritServer.java b/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/GerritServer.java
index d1ec9e6..c29e8fe 100644
--- a/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/GerritServer.java
+++ b/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/GerritServer.java
@@ -47,6 +47,7 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.URI;
+import java.nio.file.Paths;
 import java.util.concurrent.BrokenBarrierException;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CyclicBarrier;
@@ -129,7 +130,7 @@
           throw new RuntimeException(e);
         }
       }
-    });
+    }, Paths.get(baseConfig.getString("gerrit", null, "tempSiteDir")));
     daemon.setEmailModuleForTesting(new FakeEmailSender.Module());
 
     final File site;
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
index 312a93c..2475efa 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -42,6 +42,7 @@
 import com.google.gerrit.acceptance.PushOneCommit;
 import com.google.gerrit.acceptance.TestProjectInput;
 import com.google.gerrit.common.FooterConstants;
+import com.google.gerrit.common.TimeUtil;
 import com.google.gerrit.common.data.LabelType;
 import com.google.gerrit.common.data.Permission;
 import com.google.gerrit.extensions.api.changes.AddReviewerInput;
@@ -71,7 +72,9 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.LabelId;
 import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.PatchSetApproval;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.CurrentUser;
@@ -99,6 +102,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.Iterator;
 import java.util.List;
@@ -839,6 +843,26 @@
   }
 
   @Test
+  public void addReviewerWithNoteDbWhenDummyApprovalInReviewDbExists()
+      throws Exception {
+    assume().that(notesMigration.enabled()).isTrue();
+
+    PushOneCommit.Result r = createChange();
+
+    // insert dummy approval in ReviewDb
+    PatchSetApproval psa =
+        new PatchSetApproval(new PatchSetApproval.Key(r.getPatchSetId(),
+            user.id, new LabelId("Code-Review")), (short) 0, TimeUtil.nowTs());
+    db.patchSetApprovals().insert(Collections.singleton(psa));
+
+    AddReviewerInput in = new AddReviewerInput();
+    in.reviewer = user.email;
+    gApi.changes()
+        .id(r.getChangeId())
+        .addReviewer(in);
+  }
+
+  @Test
   public void addSelfAsReviewer() throws Exception {
     TestTimeUtil.resetWithClockStep(1, SECONDS);
     PushOneCommit.Result r = createChange();
diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
index c55ea1c..723b5e3 100644
--- a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
+++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
@@ -219,7 +219,7 @@
     private final Search search;
     private final Set<String> fields;
 
-    public QuerySource(List<String> types, Predicate<ChangeData> p,
+    QuerySource(List<String> types, Predicate<ChangeData> p,
         QueryOptions opts) throws QueryParseException {
       List<Sort> sorts = ImmutableList.of(
           new Sort(ChangeField.UPDATED.getName(), Sorting.DESC),
diff --git a/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/HighlightSuggestOracle.java b/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/HighlightSuggestOracle.java
index f4ff9ea4..cf5a445 100644
--- a/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/HighlightSuggestOracle.java
+++ b/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/HighlightSuggestOracle.java
@@ -88,17 +88,24 @@
         ds = escape(ds);
       }
 
+      StringBuilder pattern = new StringBuilder();
       for (String qterm : splitQuery(qstr)) {
-        qterm = "(" + escape(qterm) + ")";
+        qterm = escape(qterm);
         // We now surround qstr by <strong>. But the chosen approach is not too
         // smooth, if qstr is small (e.g.: "t") and this small qstr may occur in
         // escapes (e.g.: "Tim &lt;email@example.org&gt;"). Those escapes will
         // get <strong>-ed as well (e.g.: "&lt;" -> "&<strong>l</strong>t;"). But
         // as repairing those mangled escapes is easier than not mangling them in
         // the first place, we repair them afterwards.
-        ds = sgi(ds, qterm, "<strong>$1</strong>");
+
+        if (pattern.length() > 0) {
+          pattern.append("|");
+        }
+        pattern.append(qterm);
       }
 
+      ds = sgi(ds, "(" + pattern.toString() + ")", "<strong>$1</strong>");
+
       // Repairing <strong>-ed escapes.
       ds = sgi(ds, "(&[a-z]*)<strong>([a-z]*)</strong>([a-z]*;)", "$1$2$3");
 
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java
index f5f38fb..0b8fe3e 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java
@@ -369,7 +369,7 @@
     registerNewEmail.setEnabled(false);
 
     CallbackGroup group = new CallbackGroup();
-    if (!newEmail.equals(currentEmail)) {
+    if (currentEmail != null && !newEmail.equals(currentEmail)) {
       AccountApi.setPreferredEmail("self", newEmail,
           group.add(new GerritCallback<NativeString>() {
         @Override
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Assignee.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Assignee.java
index f46a3d1..7921ebe 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Assignee.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Assignee.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.client.change;
 
-import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.FormatUtil;
 import com.google.gerrit.client.NotSignedInDialog;
 import com.google.gerrit.client.changes.ChangeApi;
 import com.google.gerrit.client.changes.Util;
@@ -23,6 +23,7 @@
 import com.google.gerrit.client.rpc.GerritCallback;
 import com.google.gerrit.client.ui.InlineHyperlink;
 import com.google.gerrit.client.ui.RemoteSuggestBox;
+import com.google.gerrit.common.PageLinks;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.dom.client.Element;
@@ -50,19 +51,18 @@
 
   private static final Binder uiBinder = GWT.create(Binder.class);
 
-  @UiField
-  InlineHyperlink assigneeLink;
-  @UiField
-  Image editAssigneeIcon;
-  @UiField
-  Element form;
-  @UiField
-  Element error;
+  @UiField Element show;
+  @UiField InlineHyperlink assigneeLink;
+  @UiField Image editAssigneeIcon;
+  @UiField Element form;
+  @UiField Element error;
   @UiField(provided = true)
   RemoteSuggestBox suggestBox;
 
   private AssigneeSuggestOracle assigneeSuggestOracle;
   private Change.Id changeId;
+  private boolean canEdit;
+  private AccountInfo currentAssignee;
 
   Assignee() {
     assigneeSuggestOracle = new AssigneeSuggestOracle();
@@ -93,21 +93,28 @@
 
   void set(ChangeInfo info) {
     this.changeId = info.legacyId();
-    assigneeLink.setText(info.assignee() != null ? info.assignee().name() : "");
+    this.canEdit = info.hasActions() && info.actions().containsKey("assignee");
+    setAssignee(info.assignee());
     assigneeSuggestOracle.setChange(changeId);
-    editAssigneeIcon.setVisible(Gerrit.isSignedIn());
+    editAssigneeIcon.setVisible(canEdit);
+    if (!canEdit) {
+      show.setTitle(null);
+    }
   }
 
   void onOpenForm() {
     UIObject.setVisible(form, true);
+    UIObject.setVisible(show, false);
     UIObject.setVisible(error, false);
     editAssigneeIcon.setVisible(false);
     suggestBox.setFocus(true);
-    suggestBox.setText("");
+    suggestBox.setText(FormatUtil.nameEmail(currentAssignee));
+    suggestBox.selectAll();
   }
 
   void onCloseForm() {
     UIObject.setVisible(form, false);
+    UIObject.setVisible(show, true);
     UIObject.setVisible(error, false);
     editAssigneeIcon.setVisible(true);
     suggestBox.setFocus(false);
@@ -115,7 +122,9 @@
 
   @UiHandler("assign")
   void onEditAssignee(@SuppressWarnings("unused") ClickEvent e) {
-    editAssignee(suggestBox.getText());
+    if (canEdit) {
+      editAssignee(suggestBox.getText());
+    }
   }
 
   @UiHandler("cancel")
@@ -130,7 +139,7 @@
             @Override
             public void onSuccess(AccountInfo result) {
               onCloseForm();
-              assigneeLink.setText("");
+              setAssignee(null);
             }
 
             @Override
@@ -151,7 +160,7 @@
             @Override
             public void onSuccess(AccountInfo result) {
               onCloseForm();
-              assigneeLink.setText(result.name());
+              setAssignee(result);
             }
 
             @Override
@@ -168,4 +177,16 @@
           });
     }
   }
+
+  private void setAssignee(AccountInfo assignee) {
+    currentAssignee = assignee;
+    assigneeLink.setText(assignee != null ? assignee.name() : null);
+    assigneeLink.setTargetHistoryToken(assignee != null
+        ? PageLinks.toAssigneeQuery(assignee.name() != null
+            ? assignee.name()
+            : assignee.email() != null
+                ? assignee.email()
+                : String.valueOf(assignee._accountId()))
+        : "");
+  }
 }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Assignee.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Assignee.ui.xml
index 965ab2c..d5a7239 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Assignee.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Assignee.ui.xml
@@ -38,8 +38,9 @@
     }
   </ui:style>
   <g:HTMLPanel>
-    <div>
-      <u:InlineHyperlink ui:field='assigneeLink'/>
+    <div ui:field='show'>
+      <u:InlineHyperlink ui:field='assigneeLink'
+          title='Search for changes assigned to this user'/>
       <g:Image ui:field='editAssigneeIcon'
           resource='{ico.editUser}'
           styleName='{style.editAssignee}'
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Topic.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Topic.java
index 025668f..a063b6c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Topic.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Topic.java
@@ -100,6 +100,7 @@
 
       input.setText(text.getText());
       input.setFocus(true);
+      input.selectAll();
     }
   }
 
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/RemoteSuggestBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/RemoteSuggestBox.java
index 62b8f2e..084cb9a 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/RemoteSuggestBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/RemoteSuggestBox.java
@@ -134,4 +134,8 @@
   public HandlerRegistration addCloseHandler(CloseHandler<RemoteSuggestBox> h) {
     return addHandler(h, CloseEvent.getType());
   }
+
+  public void selectAll() {
+    suggestBox.getValueBox().selectAll();
+  }
 }
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
index 9d4120c..ba280c3 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
@@ -175,7 +175,8 @@
   }
 
   @VisibleForTesting
-  public Daemon(Runnable serverStarted) {
+  public Daemon(Runnable serverStarted, Path sitePath) {
+    super (sitePath);
     this.serverStarted = serverStarted;
   }
 
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java
index 9e2da5c..a2e0450 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java
@@ -78,6 +78,10 @@
   protected SiteProgram() {
   }
 
+  protected SiteProgram(Path sitePath) {
+    this.sitePath = sitePath;
+  }
+
   protected SiteProgram(Path sitePath, final Provider<DataSource> dsProvider) {
     this.sitePath = sitePath;
     this.dsProvider = dsProvider;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java
index 97af09e..43f20cc 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java
@@ -225,7 +225,7 @@
           (short) 0, update.getWhen()));
       update.putReviewer(account, REVIEWER);
     }
-    db.patchSetApprovals().insert(cells);
+    db.patchSetApprovals().upsert(cells);
     return Collections.unmodifiableList(cells);
   }
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PutAssignee.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PutAssignee.java
index b048960..4298937 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PutAssignee.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PutAssignee.java
@@ -23,6 +23,7 @@
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.extensions.webui.UiAction;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.account.AccountJson;
 import com.google.gerrit.server.change.PostReviewers.Addition;
@@ -36,8 +37,8 @@
 import java.io.IOException;
 
 @Singleton
-public class PutAssignee
-    implements RestModifyView<ChangeResource, AssigneeInput> {
+public class PutAssignee implements
+    RestModifyView<ChangeResource, AssigneeInput>, UiAction<ChangeResource> {
 
   private final SetAssigneeOp.Factory assigneeFactory;
   private final BatchUpdate.Factory batchUpdateFactory;
@@ -83,4 +84,11 @@
     reviewerInput.notify = NotifyHandling.NONE;
     return postReviewers.prepareApplication(rsrc, reviewerInput);
   }
+
+  @Override
+  public UiAction.Description getDescription(ChangeResource resource) {
+    return new UiAction.Description()
+      .setLabel("Edit Assignee")
+      .setVisible(resource.getControl().canEditAssignee());
+  }
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/BatchUpdate.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/BatchUpdate.java
index 8e98562..dc1798a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/BatchUpdate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/BatchUpdate.java
@@ -682,7 +682,7 @@
   }
 
   private void executeRefUpdates(boolean dryrun)
-      throws IOException, UpdateException {
+      throws IOException, RestApiException {
     if (commands == null || commands.isEmpty()) {
       logDebug("No ref updates to execute");
       return;
@@ -706,7 +706,7 @@
       }
     }
     if (!ok) {
-      throw new UpdateException("BatchRefUpdate failed: " + batchRefUpdate);
+      throw new RestApiException("BatchRefUpdate failed: " + batchRefUpdate);
     }
   }
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeRevisionNote.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeRevisionNote.java
index b95c92a..2bd61a7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeRevisionNote.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeRevisionNote.java
@@ -44,7 +44,7 @@
   private final ChangeNoteUtil noteUtil;
   private final Change.Id changeId;
   private final PatchLineComment.Status status;
-  private String pushCert = null;
+  private String pushCert;
 
   ChangeRevisionNote(ChangeNoteUtil noteUtil, Change.Id changeId,
       ObjectReader reader, ObjectId noteId, PatchLineComment.Status status) {
@@ -92,7 +92,7 @@
       int offset) throws IOException {
     try (InputStream is = new ByteArrayInputStream(
         raw, offset, raw.length - offset);
-        Reader r = new InputStreamReader(is)) {
+        Reader r = new InputStreamReader(is, UTF_8)) {
       return noteUtil.getGson().fromJson(r, RevisionNoteData.class);
     }
   }
@@ -109,6 +109,6 @@
     }
     int start = p.value;
     p.value = end + END_SIGNATURE.length;
-    return new String(bytes, start, p.value);
+    return new String(bytes, start, p.value, UTF_8);
   }
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java
index 300f753..18cac47 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java
@@ -70,7 +70,7 @@
  * of updates, use {@link #stage()}.
  */
 public class NoteDbUpdateManager implements AutoCloseable {
-  public static String CHANGES_READ_ONLY = "NoteDb changes are read-only";
+  public static final String CHANGES_READ_ONLY = "NoteDb changes are read-only";
 
   public interface Factory {
     NoteDbUpdateManager create(Project.NameKey projectName);
@@ -78,8 +78,9 @@
 
   @AutoValue
   public abstract static class StagedResult {
-    private static StagedResult create(Change.Id id, NoteDbChangeState.Delta delta,
-        OpenRepo changeRepo, OpenRepo allUsersRepo) {
+    private static StagedResult create(Change.Id id,
+        NoteDbChangeState.Delta delta, OpenRepo changeRepo,
+        OpenRepo allUsersRepo) {
       ImmutableList<ReceiveCommand> changeCommands = ImmutableList.of();
       ImmutableList<InsertedObject> changeObjects = ImmutableList.of();
       if (changeRepo != null) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RevisionNoteBuilder.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RevisionNoteBuilder.java
index 8eacb1c..8491f57 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RevisionNoteBuilder.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RevisionNoteBuilder.java
@@ -139,7 +139,7 @@
     data.comments = COMMENT_ORDER.sortedCopy(comments.values());
     data.pushCert = pushCert;
 
-    try (OutputStreamWriter osw = new OutputStreamWriter(out)) {
+    try (OutputStreamWriter osw = new OutputStreamWriter(out, UTF_8)) {
       noteUtil.getGson().toJson(data, osw);
     }
   }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RobotCommentsRevisionNote.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RobotCommentsRevisionNote.java
index e007ff3..0dca408 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RobotCommentsRevisionNote.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RobotCommentsRevisionNote.java
@@ -14,6 +14,8 @@
 
 package com.google.gerrit.server.notedb;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 import com.google.gerrit.reviewdb.client.RobotComment;
 
 import org.eclipse.jgit.lib.ObjectId;
@@ -40,7 +42,7 @@
       throws IOException {
     try (InputStream is = new ByteArrayInputStream(
         raw, offset, raw.length - offset);
-        Reader r = new InputStreamReader(is)) {
+        Reader r = new InputStreamReader(is, UTF_8)) {
       return noteUtil.getGson().fromJson(r,
           RobotCommentsRevisionNoteData.class).comments;
     }
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
index b8c09c6..4cc4867 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
@@ -469,18 +469,19 @@
 
       });
 
-      test('document scrolling calls function to set scroll height', function(done) {
-          var scrollStub = sinon.stub(element, '_handleScroll',
-              function() {
-                assert.isTrue(scrollStub.called);
-                document.getElementsByTagName('body')[0].style.height = originalHeight+'px';
-                scrollStub.restore();
-                done();
-              });
+      test('document scrolling calls function to set scroll height',
+          function(done) {
+          var scrollStub = sinon.stub(element, '_handleScroll', function() {
+              assert.isTrue(scrollStub.called);
+              document.getElementsByTagName('body')[0].style.height =
+                  originalHeight + 'px';
+              scrollStub.restore();
+              done();
+          });
 
           var originalHeight = document.body.scrollHeight;
           document.getElementsByTagName('body')[0].style.height = '10000px';
-          window.scroll(0,100);
+          window.scroll(0, 100);
       });
     });
   });
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html
index 8fa9a48..8ccfc9a 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html
@@ -85,7 +85,7 @@
       assert.equal(element.message, expected);
     });
 
-    test('revert a revert', function () {
+    test('revert a revert', function() {
       assert.isNotOk(element.message);
       element.populateRevertMessage(
           'Revert "one line commit"\n\nChange-Id: abcdefg\n');