Merge "RFC: Enable Eclipse warning about fall-through cases in switch statements"
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
index 1a0c0db..cd9bb4d 100644
--- a/Documentation/access-control.txt
+++ b/Documentation/access-control.txt
@@ -768,8 +768,7 @@
 [[category_submit]]
 === Submit
 
-This category permits users to push the `Submit Patch Set n` button
-on the web UI.
+This category permits users to submit changes.
 
 Submitting a change causes it to be merged into the destination
 branch as soon as possible, making it a permanent part of the
diff --git a/Documentation/rest-api-accounts.txt b/Documentation/rest-api-accounts.txt
index 9966c8e..b5c1557 100644
--- a/Documentation/rest-api-accounts.txt
+++ b/Documentation/rest-api-accounts.txt
@@ -1550,6 +1550,8 @@
 Whether to show the change sizes as colored bars in the change table.
 |`legacycid_in_change_table`      |not set if `false`|
 Whether to show change number in the change table.
+|`mute_common_path_prefixes` |not set if `false`|
+Whether to mute common path prefixes in file names in the file table.
 |`review_category_strategy`   ||
 The strategy used to displayed info in the review category column.
 Allowed values are `NONE`, `NAME`, `EMAIL`, `USERNAME`, `ABBREV`.
@@ -1591,6 +1593,8 @@
 Whether to show the change sizes as colored bars in the change table.
 |`legacycid_in_change_table`      |optional|
 Whether to show change number in the change table.
+|`mute_common_path_prefixes` |optional|
+Whether to mute common path prefixes in file names in the file table.
 |`review_category_strategy`   |optional|
 The strategy used to displayed info in the review category column.
 Allowed values are `NONE`, `NAME`, `EMAIL`, `USERNAME`, `ABBREV`.
diff --git a/Documentation/rest-api-projects.txt b/Documentation/rest-api-projects.txt
index c6215c9..40873fe 100644
--- a/Documentation/rest-api-projects.txt
+++ b/Documentation/rest-api-projects.txt
@@ -2172,7 +2172,8 @@
 |Field Name                  ||Description
 |`name`                      |optional|
 The name of the project (not encoded). +
-If set, must match the project name in the URL.
+If set, must match the project name in the URL. +
+If name ends with `.git` the suffix will be automatically removed.
 |`parent`                    |optional|
 The name of the parent project. +
 If not set, the `All-Projects` project will be the parent project.
diff --git a/Documentation/user-review-ui.txt b/Documentation/user-review-ui.txt
index 42c3e0d..ab1070a 100644
--- a/Documentation/user-review-ui.txt
+++ b/Documentation/user-review-ui.txt
@@ -599,10 +599,6 @@
 each label on which the user is allowed to vote. Voting on non-current
 patch sets is not possible.
 
-Typing "LGTM" (acronym for 'Looks Good To Me') in the summary comment
-text box automatically selects the highest possible score for the
-'Code-Review' label.
-
 The inline draft comments that will be published are displayed in a
 separate section so that they can be reviewed before publishing. There
 are links to navigate to the inline comments which can be used if a
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java
index d2e70c3..7de4712 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java
@@ -44,6 +44,17 @@
             .name);
   }
 
+  @Test
+  public void createProjectFooWithGitSuffix() throws Exception {
+    String name = "foo";
+    assertThat(name).isEqualTo(
+        gApi.projects()
+            .name(name + ".git")
+            .create()
+            .get()
+            .name);
+  }
+
   @Test(expected = RestApiException.class)
   public void createProjectFooBar() throws Exception {
     ProjectInput in = new ProjectInput();
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
index a87e972..998c5ea 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
@@ -58,6 +58,17 @@
   }
 
   @Test
+  public void testCreateProjectApiWithGitSuffix() throws Exception {
+    final String newProjectName = "newProject";
+    ProjectInfo p = gApi.projects().name(newProjectName + ".git").create().get();
+    assertThat(p.name).isEqualTo(newProjectName);
+    ProjectState projectState = projectCache.get(new Project.NameKey(newProjectName));
+    assertThat(projectState).isNotNull();
+    assertProjectInfo(projectState.getProject(), p);
+    assertHead(newProjectName, "refs/heads/master");
+  }
+
+  @Test
   public void testCreateProject() throws Exception {
     final String newProjectName = "newProject";
     RestResponse r = adminSession.put("/projects/" + newProjectName);
@@ -71,6 +82,19 @@
   }
 
   @Test
+  public void testCreateProjectWithGitSuffix() throws Exception {
+    final String newProjectName = "newProject";
+    RestResponse r = adminSession.put("/projects/" + newProjectName + ".git");
+    assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_CREATED);
+    ProjectInfo p = newGson().fromJson(r.getReader(), ProjectInfo.class);
+    assertThat(p.name).isEqualTo(newProjectName);
+    ProjectState projectState = projectCache.get(new Project.NameKey(newProjectName));
+    assertThat(projectState).isNotNull();
+    assertProjectInfo(projectState.getProject(), p);
+    assertHead(newProjectName, "refs/heads/master");
+  }
+
+  @Test
   public void testCreateProjectWithNameMismatch_BadRequest() throws Exception {
     ProjectInput in = new ProjectInput();
     in.name = "otherName";
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/GetProjectIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/GetProjectIT.java
new file mode 100644
index 0000000..761e282
--- /dev/null
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/GetProjectIT.java
@@ -0,0 +1,51 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.acceptance.rest.project;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.extensions.common.ProjectInfo;
+
+import org.apache.http.HttpStatus;
+import org.junit.Test;
+
+public class GetProjectIT extends AbstractDaemonTest {
+
+  @Test
+  public void getProject() throws Exception {
+    String name = project.get();
+    RestResponse r = adminSession.get("/projects/" + name);
+    assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_OK);
+    ProjectInfo p = newGson().fromJson(r.getReader(), ProjectInfo.class);
+    assertThat(p.name).isEqualTo(name);
+  }
+
+  @Test
+  public void getProjectWithGitSuffix() throws Exception {
+    String name = project.get();
+    RestResponse r = adminSession.get("/projects/" + name + ".git");
+    assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_OK);
+    ProjectInfo p = newGson().fromJson(r.getReader(), ProjectInfo.class);
+    assertThat(p.name).isEqualTo(name);
+  }
+
+  @Test
+  public void getProjectNotExisting() throws Exception {
+    RestResponse r = adminSession.get("/projects/does-not-exist");
+    assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_NOT_FOUND);
+  }
+}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/CommentsIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/CommentsIT.java
index dfce940..fbd3c29 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/CommentsIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/CommentsIT.java
@@ -22,6 +22,7 @@
 import com.google.gerrit.acceptance.PushOneCommit;
 import com.google.gerrit.acceptance.RestResponse;
 import com.google.gerrit.extensions.api.changes.ReviewInput;
+import com.google.gerrit.extensions.client.Comment;
 import com.google.gerrit.extensions.client.Side;
 import com.google.gerrit.extensions.common.CommentInfo;
 import com.google.gerrit.server.notedb.NotesMigration;
@@ -44,83 +45,95 @@
     return NotesMigration.allEnabledConfig();
   }
 
+  private final Integer lines[] = {0, 1};
+
   @Test
   public void createDraft() throws Exception {
-    PushOneCommit.Result r = createChange();
-    String changeId = r.getChangeId();
-    String revId = r.getCommit().getName();
-    ReviewInput.CommentInput comment = newCommentInfo(
-        "file1", Side.REVISION, 1, "comment 1");
-    addDraft(changeId, revId, comment);
-    Map<String, List<CommentInfo>> result = getDraftComments(changeId, revId);
-    assertThat(result).hasSize(1);
-    CommentInfo actual = Iterables.getOnlyElement(result.get(comment.path));
-    assertCommentInfo(comment, actual);
+    for (Integer line : lines) {
+      PushOneCommit.Result r = createChange();
+      String changeId = r.getChangeId();
+      String revId = r.getCommit().getName();
+      ReviewInput.CommentInput comment = newCommentInfo(
+          "file1", Side.REVISION, line, "comment 1");
+      addDraft(changeId, revId, comment);
+      Map<String, List<CommentInfo>> result = getDraftComments(changeId, revId);
+      assertThat(result).hasSize(1);
+      CommentInfo actual = Iterables.getOnlyElement(result.get(comment.path));
+      assertCommentInfo(comment, actual);
+    }
   }
 
   @Test
   public void postComment() throws Exception {
-    String file = "file";
-    String contents = "contents";
-    PushOneCommit push = pushFactory.create(db, admin.getIdent(),
-        "first subject", file, contents);
-    PushOneCommit.Result r = push.to(git, "refs/for/master");
-    String changeId = r.getChangeId();
-    String revId = r.getCommit().getName();
-    ReviewInput input = new ReviewInput();
-    ReviewInput.CommentInput comment = newCommentInfo(
-        file, Side.REVISION, 1, "comment 1");
-    input.comments = new HashMap<>();
-    input.comments.put(comment.path, Lists.newArrayList(comment));
-    revision(r).review(input);
-    Map<String, List<CommentInfo>> result = getPublishedComments(changeId, revId);
-    assertThat(result).isNotEmpty();
-    CommentInfo actual = Iterables.getOnlyElement(result.get(comment.path));
-    assertCommentInfo(comment, actual);
+    for (Integer line : lines) {
+      String file = "file";
+      String contents = "contents " + line;
+      PushOneCommit push = pushFactory.create(db, admin.getIdent(),
+          "first subject", file, contents);
+      PushOneCommit.Result r = push.to(git, "refs/for/master");
+      String changeId = r.getChangeId();
+      String revId = r.getCommit().getName();
+      ReviewInput input = new ReviewInput();
+      ReviewInput.CommentInput comment = newCommentInfo(
+          file, Side.REVISION, line, "comment 1");
+      input.comments = new HashMap<>();
+      input.comments.put(comment.path, Lists.newArrayList(comment));
+      revision(r).review(input);
+      Map<String, List<CommentInfo>> result = getPublishedComments(changeId, revId);
+      assertThat(result).isNotEmpty();
+      CommentInfo actual = Iterables.getOnlyElement(result.get(comment.path));
+      assertCommentInfo(comment, actual);
+    }
   }
 
   @Test
   public void putDraft() throws Exception {
-    PushOneCommit.Result r = createChange();
-    String changeId = r.getChangeId();
-    String revId = r.getCommit().getName();
-    ReviewInput.CommentInput comment = newCommentInfo(
-        "file1", Side.REVISION, 1, "comment 1");
-    addDraft(changeId, revId, comment);
-    Map<String, List<CommentInfo>> result = getDraftComments(changeId, revId);
-    CommentInfo actual = Iterables.getOnlyElement(result.get(comment.path));
-    assertCommentInfo(comment, actual);
-    String uuid = actual.id;
-    comment.message = "updated comment 1";
-    updateDraft(changeId, revId, comment, uuid);
-    result = getDraftComments(changeId, revId);
-    actual = Iterables.getOnlyElement(result.get(comment.path));
-    assertCommentInfo(comment, actual);
+    for (Integer line : lines) {
+      PushOneCommit.Result r = createChange();
+      String changeId = r.getChangeId();
+      String revId = r.getCommit().getName();
+      ReviewInput.CommentInput comment = newCommentInfo(
+          "file1", Side.REVISION, line, "comment 1");
+      addDraft(changeId, revId, comment);
+      Map<String, List<CommentInfo>> result = getDraftComments(changeId, revId);
+      CommentInfo actual = Iterables.getOnlyElement(result.get(comment.path));
+      assertCommentInfo(comment, actual);
+      String uuid = actual.id;
+      comment.message = "updated comment 1";
+      updateDraft(changeId, revId, comment, uuid);
+      result = getDraftComments(changeId, revId);
+      actual = Iterables.getOnlyElement(result.get(comment.path));
+      assertCommentInfo(comment, actual);
+    }
   }
 
   @Test
   public void getDraft() throws Exception {
-    PushOneCommit.Result r = createChange();
-    String changeId = r.getChangeId();
-    String revId = r.getCommit().getName();
-    ReviewInput.CommentInput comment = newCommentInfo(
-        "file1", Side.REVISION, 1, "comment 1");
-    CommentInfo returned = addDraft(changeId, revId, comment);
-    CommentInfo actual = getDraftComment(changeId, revId, returned.id);
-    assertCommentInfo(comment, actual);
+    for (Integer line : lines) {
+      PushOneCommit.Result r = createChange();
+      String changeId = r.getChangeId();
+      String revId = r.getCommit().getName();
+      ReviewInput.CommentInput comment = newCommentInfo(
+          "file1", Side.REVISION, line, "comment 1");
+      CommentInfo returned = addDraft(changeId, revId, comment);
+      CommentInfo actual = getDraftComment(changeId, revId, returned.id);
+      assertCommentInfo(comment, actual);
+    }
   }
 
   @Test
   public void deleteDraft() throws Exception {
-    PushOneCommit.Result r = createChange();
-    String changeId = r.getChangeId();
-    String revId = r.getCommit().getName();
-    ReviewInput.CommentInput comment = newCommentInfo(
-        "file1", Side.REVISION, 1, "comment 1");
-    CommentInfo returned = addDraft(changeId, revId, comment);
-    deleteDraft(changeId, revId, returned.id);
-    Map<String, List<CommentInfo>> drafts = getDraftComments(changeId, revId);
-    assertThat(drafts).isEmpty();
+    for (Integer line : lines) {
+      PushOneCommit.Result r = createChange();
+      String changeId = r.getChangeId();
+      String revId = r.getCommit().getName();
+      ReviewInput.CommentInput comment = newCommentInfo(
+          "file1", Side.REVISION, line, "comment 1");
+      CommentInfo returned = addDraft(changeId, revId, comment);
+      deleteDraft(changeId, revId, returned.id);
+      Map<String, List<CommentInfo>> drafts = getDraftComments(changeId, revId);
+      assertThat(drafts).isEmpty();
+    }
   }
 
   private CommentInfo addDraft(String changeId, String revId,
@@ -176,18 +189,40 @@
     assertThat(actual.line).isEqualTo(expected.line);
     assertThat(actual.message).isEqualTo(expected.message);
     assertThat(actual.inReplyTo).isEqualTo(expected.inReplyTo);
+    assertCommentRange(expected.range, actual.range);
     if (actual.side == null) {
       assertThat(Side.REVISION).isEqualTo(expected.side);
     }
   }
 
+  private static void assertCommentRange(Comment.Range expected,
+      Comment.Range actual) {
+    if (expected == null) {
+      assertThat(actual).isNull();
+    } else {
+      assertThat(actual).isNotNull();
+      assertThat(actual.startLine).isEqualTo(expected.startLine);
+      assertThat(actual.startCharacter).isEqualTo(expected.startCharacter);
+      assertThat(actual.endLine).isEqualTo(expected.endLine);
+      assertThat(actual.endCharacter).isEqualTo(expected.endCharacter);
+    }
+  }
+
   private ReviewInput.CommentInput newCommentInfo(String path,
       Side side, int line, String message) {
     ReviewInput.CommentInput input = new ReviewInput.CommentInput();
     input.path = path;
     input.side = side;
-    input.line = line;
+    input.line = line != 0 ? line : null;
     input.message = message;
+    if (line != 0) {
+      Comment.Range range = new Comment.Range();
+      range.startLine = 1;
+      range.startCharacter = 1;
+      range.endLine = 1;
+      range.endCharacter = 5;
+      input.range = range;
+    }
     return input;
   }
 }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java
index abcfa0c..4c3cc29 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java
@@ -42,6 +42,7 @@
   String showRelativeDateInChangeTable();
   String showSizeBarInChangeTable();
   String showLegacycidInChangeTable();
+  String muteCommonPathPrefixes();
   String myMenu();
   String myMenuInfo();
   String myMenuName();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties
index 8f151a9..5596ace 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties
@@ -23,6 +23,7 @@
 showRelativeDateInChangeTable = Show Relative Dates In Changes Table
 showSizeBarInChangeTable = Show Change Sizes As Colored Bars In Changes Table
 showLegacycidInChangeTable = Show Change Number In Changes Table
+muteCommonPathPrefixes = Mute Common Path Prefixes In File List
 myMenu = My Menu
 myMenuInfo = \
   Menu items for the 'My' top level menu. \
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java
index 25c21bf..5cee767 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java
@@ -50,6 +50,7 @@
   private CheckBox relativeDateInChangeTable;
   private CheckBox sizeBarInChangeTable;
   private CheckBox legacycidInChangeTable;
+  private CheckBox muteCommonPathPrefixes;
   private ListBox maximumPageSize;
   private ListBox dateFormat;
   private ListBox timeFormat;
@@ -132,8 +133,9 @@
     relativeDateInChangeTable = new CheckBox(Util.C.showRelativeDateInChangeTable());
     sizeBarInChangeTable = new CheckBox(Util.C.showSizeBarInChangeTable());
     legacycidInChangeTable = new CheckBox(Util.C.showLegacycidInChangeTable());
+    muteCommonPathPrefixes = new CheckBox(Util.C.muteCommonPathPrefixes());
 
-    final Grid formGrid = new Grid(10, 2);
+    final Grid formGrid = new Grid(11, 2);
 
     int row = 0;
     formGrid.setText(row, labelIdx, "");
@@ -172,6 +174,10 @@
     formGrid.setWidget(row, fieldIdx, legacycidInChangeTable);
     row++;
 
+    formGrid.setText(row, labelIdx, "");
+    formGrid.setWidget(row, fieldIdx, muteCommonPathPrefixes);
+    row++;
+
     formGrid.setText(row, labelIdx, Util.C.diffViewLabel());
     formGrid.setWidget(row, fieldIdx, diffView);
 
@@ -201,6 +207,7 @@
     e.listenTo(relativeDateInChangeTable);
     e.listenTo(sizeBarInChangeTable);
     e.listenTo(legacycidInChangeTable);
+    e.listenTo(muteCommonPathPrefixes);
     e.listenTo(diffView);
   }
 
@@ -226,6 +233,7 @@
     relativeDateInChangeTable.setEnabled(on);
     sizeBarInChangeTable.setEnabled(on);
     legacycidInChangeTable.setEnabled(on);
+    muteCommonPathPrefixes.setEnabled(on);
     reviewCategoryStrategy.setEnabled(on);
     diffView.setEnabled(on);
   }
@@ -242,6 +250,7 @@
     relativeDateInChangeTable.setValue(p.relativeDateInChangeTable());
     sizeBarInChangeTable.setValue(p.sizeBarInChangeTable());
     legacycidInChangeTable.setValue(p.legacycidInChangeTable());
+    muteCommonPathPrefixes.setValue(p.muteCommonPathPrefixes());
     setListBox(reviewCategoryStrategy,
         AccountGeneralPreferences.ReviewCategoryStrategy.NONE,
         p.reviewCategoryStrategy());
@@ -325,6 +334,7 @@
     p.setRelativeDateInChangeTable(relativeDateInChangeTable.getValue());
     p.setSizeBarInChangeTable(sizeBarInChangeTable.getValue());
     p.setLegacycidInChangeTable(legacycidInChangeTable.getValue());
+    p.setMuteCommonPathPrefixes(muteCommonPathPrefixes.getValue());
     p.setReviewCategoryStrategy(getListBox(reviewCategoryStrategy,
         ReviewCategoryStrategy.NONE,
         ReviewCategoryStrategy.values()));
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/Preferences.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/Preferences.java
index aec679c..e9bd5f1 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/Preferences.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/Preferences.java
@@ -44,6 +44,7 @@
     p.relativeDateInChangeTable(in.isRelativeDateInChangeTable());
     p.sizeBarInChangeTable(in.isSizeBarInChangeTable());
     p.legacycidInChangeTable(in.isLegacycidInChangeTable());
+    p.muteCommonPathPrefixes(in.isMuteCommonPathPrefixes());
     p.reviewCategoryStrategy(in.getReviewCategoryStrategy());
     p.diffView(in.getDiffView());
     p.setMyMenus(myMenus);
@@ -102,6 +103,9 @@
   public final native boolean legacycidInChangeTable()
   /*-{ return this.legacycid_in_change_table || false }-*/;
 
+  public final native boolean muteCommonPathPrefixes()
+  /*-{ return this.mute_common_path_prefixes || false }-*/;
+
   public final ReviewCategoryStrategy reviewCategoryStrategy() {
     String s = reviewCategeoryStrategyRaw();
     return s != null ? ReviewCategoryStrategy.valueOf(s) : ReviewCategoryStrategy.NONE;
@@ -164,6 +168,9 @@
   public final native void legacycidInChangeTable(boolean s)
   /*-{ this.legacycid_in_change_table = s }-*/;
 
+  public final native void muteCommonPathPrefixes(boolean s)
+  /*-{ this.mute_common_path_prefixes = s }-*/;
+
   public final void reviewCategoryStrategy(ReviewCategoryStrategy s) {
     reviewCategoryStrategyRaw(s != null ? s.toString() : null);
   }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
index aa50f02..5dab3ac 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
@@ -630,7 +630,8 @@
 
       if (Patch.COMMIT_MSG.equals(path)) {
         sb.append(Util.C.commitMessage());
-      } else {
+      } else if (!hasUser || Gerrit.getUserAccount().getGeneralPreferences()
+          .isMuteCommonPathPrefixes()) {
         int commonPrefixLen = commonPrefix(path);
         if (commonPrefixLen > 0) {
           sb.openSpan().setStyleName(R.css().commonPrefix())
@@ -639,6 +640,8 @@
         }
         sb.append(path.substring(commonPrefixLen));
         lastPath = path;
+      } else {
+        sb.append(path);
       }
 
       sb.closeAnchor();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
index 5eb936c..fd9f4bc 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
@@ -76,8 +76,6 @@
 import java.util.TreeSet;
 
 class ReplyBox extends Composite {
-  private static final String CODE_REVIEW = "Code-Review";
-
   interface Binder extends UiBinder<HTMLPanel, ReplyBox> {}
   private static final Binder uiBinder = GWT.create(Binder.class);
 
@@ -92,7 +90,6 @@
   private final String revision;
   private ReviewInput in = ReviewInput.create();
   private int labelHelpColumn;
-  private Runnable lgtm;
 
   @UiField Styles style;
   @UiField TextArea message;
@@ -173,20 +170,6 @@
       }}, 0);
   }
 
-  @UiHandler("message")
-  void onMessageKey(KeyPressEvent event) {
-    if (lgtm != null
-        && event.getCharCode() == 'M'
-        && message.getValue().equals("LGT")) {
-      Scheduler.get().scheduleDeferred(new ScheduledCommand() {
-        @Override
-        public void execute() {
-          lgtm.run();
-        }
-      });
-    }
-  }
-
   @UiHandler("post")
   void onPost(@SuppressWarnings("unused") ClickEvent e) {
     postReview();
@@ -358,15 +341,6 @@
         labelsTable.setWidget(row, 1 + i, b);
       }
     }
-
-    if (CODE_REVIEW.equalsIgnoreCase(id) && !group.buttons.isEmpty()) {
-      lgtm = new Runnable() {
-        @Override
-        public void run() {
-          group.selectMax();
-        }
-      };
-    }
   }
 
   private void renderCheckBox(int row, LabelAndValues lv) {
@@ -390,15 +364,6 @@
     });
     b.setStyleName(style.label_name());
     labelsTable.setWidget(row, 0, b);
-
-    if (CODE_REVIEW.equalsIgnoreCase(id)) {
-      lgtm = new Runnable() {
-        @Override
-        public void run() {
-          b.setValue(true, true);
-        }
-      };
-    }
   }
 
   private static boolean isCheckBox(Set<Short> values) {
@@ -467,16 +432,6 @@
       selected = b;
       labelsTable.setText(row, labelHelpColumn, b.text);
     }
-
-    void selectMax() {
-      for (int i = 0; i < buttons.size() - 1; i++) {
-        buttons.get(i).setValue(false, false);
-      }
-
-      LabelRadioButton max = buttons.get(buttons.size() - 1);
-      max.setValue(true, true);
-      max.select();
-    }
   }
 
   private class LabelRadioButton extends RadioButton implements
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/mode/ModeInfo.java b/gerrit-gwtui/src/main/java/net/codemirror/mode/ModeInfo.java
index 2dc034b..d6b194b 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/mode/ModeInfo.java
+++ b/gerrit-gwtui/src/main/java/net/codemirror/mode/ModeInfo.java
@@ -51,6 +51,7 @@
       Modes.I.gas(),
       Modes.I.gerrit_commit(),
       Modes.I.gfm(),
+      Modes.I.go(),
       Modes.I.groovy(),
       Modes.I.haskell(),
       Modes.I.htmlmixed(),
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/mode/Modes.java b/gerrit-gwtui/src/main/java/net/codemirror/mode/Modes.java
index 2bd5b00..e511be5 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/mode/Modes.java
+++ b/gerrit-gwtui/src/main/java/net/codemirror/mode/Modes.java
@@ -36,6 +36,7 @@
   @Source("gas.js") @DoNotEmbed DataResource gas();
   @Source("gerrit/commit.js") @DoNotEmbed DataResource gerrit_commit();
   @Source("gfm.js") @DoNotEmbed DataResource gfm();
+  @Source("go.js") @DoNotEmbed DataResource go();
   @Source("groovy.js") @DoNotEmbed DataResource groovy();
   @Source("haskell.js") @DoNotEmbed DataResource haskell();
   @Source("htmlmixed.js") @DoNotEmbed DataResource htmlmixed();
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
index 5055d47..a7b53cf 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
@@ -105,6 +105,7 @@
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.EOFException;
+import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -767,10 +768,16 @@
       b64 = new BinaryResult() {
         @Override
         public void writeTo(OutputStream out) throws IOException {
-          OutputStream e = BaseEncoding.base64().encodingStream(
-              new OutputStreamWriter(out, ISO_8859_1));
-          src.writeTo(e);
-          e.flush();
+          try (OutputStreamWriter w = new OutputStreamWriter(
+                new FilterOutputStream(out) {
+                  @Override
+                  public void close() {
+                    // Do not close out, but only w and e.
+                  }
+                }, ISO_8859_1);
+              OutputStream e = BaseEncoding.base64().encodingStream(w)) {
+            src.writeTo(e);
+          }
         }
       };
     }
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/WarDistribution.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/WarDistribution.java
index 2c34711..3328a54 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/WarDistribution.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/WarDistribution.java
@@ -49,8 +49,9 @@
             String pluginJarName = new File(ze.getName()).getName();
             String pluginName = pluginJarName.substring(0,
                 pluginJarName.length() - JAR.length());
-            final InputStream in = zf.getInputStream(ze);
-            processor.process(pluginName, in);
+            try (InputStream in = zf.getInputStream(ze)) {
+              processor.process(pluginName, in);
+            }
           }
         }
       }
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AccountGeneralPreferences.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AccountGeneralPreferences.java
index a0cc2bf..31494ba 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AccountGeneralPreferences.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AccountGeneralPreferences.java
@@ -157,6 +157,9 @@
   @Column(id = 18, length = 20, notNull = false)
   protected String reviewCategoryStrategy;
 
+  @Column(id = 19)
+  protected boolean muteCommonPathPrefixes;
+
   public AccountGeneralPreferences() {
   }
 
@@ -295,6 +298,15 @@
     this.legacycidInChangeTable = legacycidInChangeTable;
   }
 
+  public boolean isMuteCommonPathPrefixes() {
+    return muteCommonPathPrefixes;
+  }
+
+  public void setMuteCommonPathPrefixes(
+      boolean muteCommonPathPrefixes) {
+    this.muteCommonPathPrefixes = muteCommonPathPrefixes;
+  }
+
   public void resetToDefaults() {
     maximumPageSize = DEFAULT_PAGESIZE;
     showSiteHeader = true;
@@ -309,5 +321,6 @@
     diffView = null;
     sizeBarInChangeTable = true;
     legacycidInChangeTable = false;
+    muteCommonPathPrefixes = true;
   }
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/GetPreferences.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetPreferences.java
index 8983013..e45e7cc 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/GetPreferences.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetPreferences.java
@@ -109,6 +109,7 @@
     Boolean relativeDateInChangeTable;
     Boolean sizeBarInChangeTable;
     Boolean legacycidInChangeTable;
+    Boolean muteCommonPathPrefixes;
     ReviewCategoryStrategy reviewCategoryStrategy;
     DiffView diffView;
     List<TopMenu.MenuItem> my;
@@ -127,6 +128,7 @@
         relativeDateInChangeTable = p.isRelativeDateInChangeTable() ? true : null;
         sizeBarInChangeTable = p.isSizeBarInChangeTable() ? true : null;
         legacycidInChangeTable = p.isLegacycidInChangeTable() ? true : null;
+        muteCommonPathPrefixes = p.isMuteCommonPathPrefixes() ? true : null;
         reviewCategoryStrategy = p.getReviewCategoryStrategy();
         diffView = p.getDiffView();
       }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
index 08450f3..d75c5a2 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
@@ -63,6 +63,7 @@
     public Boolean relativeDateInChangeTable;
     public Boolean sizeBarInChangeTable;
     public Boolean legacycidInChangeTable;
+    public Boolean muteCommonPathPrefixes;
     public ReviewCategoryStrategy reviewCategoryStrategy;
     public DiffView diffView;
     public List<TopMenu.MenuItem> my;
@@ -150,6 +151,9 @@
       if (i.legacycidInChangeTable != null) {
         p.setLegacycidInChangeTable(i.legacycidInChangeTable);
       }
+      if (i.muteCommonPathPrefixes != null) {
+        p.setMuteCommonPathPrefixes(i.muteCommonPathPrefixes);
+      }
       if (i.reviewCategoryStrategy != null) {
         p.setReviewCategoryStrategy(i.reviewCategoryStrategy);
       }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java
index 98d99a3..baddd40 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java
@@ -43,6 +43,7 @@
 import com.google.gerrit.server.notedb.ReviewerState;
 import com.google.gerrit.server.patch.PatchSetInfoFactory;
 import com.google.gerrit.server.project.ChangeControl;
+import com.google.gerrit.server.project.ChangeModifiedException;
 import com.google.gerrit.server.project.InvalidChangeOperationException;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.ssh.NoSshInfo;
@@ -380,12 +381,4 @@
     return changeMessage != null && changeMessage.getKey().getParentKey()
         .equals(patchSet.getId().getParentKey());
   }
-
-  public class ChangeModifiedException extends InvalidChangeOperationException {
-    private static final long serialVersionUID = 1L;
-
-    public ChangeModifiedException(String msg) {
-      super(msg);
-    }
-  }
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
index 47e7b65..cd54b78 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
@@ -358,7 +358,7 @@
               new PatchLineComment.Key(
                   new Patch.Key(rsrc.getPatchSet().getId(), path),
                   ChangeUtil.messageUUID(db.get())),
-              c.line,
+              c.line != null ? c.line : 0,
               rsrc.getAccountId(),
               parent, timestamp);
         } else if (parent != null) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/SetPreferences.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/SetPreferences.java
index 0044ebd..d97499c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/SetPreferences.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/SetPreferences.java
@@ -52,6 +52,7 @@
         || i.relativeDateInChangeTable != null
         || i.sizeBarInChangeTable != null
         || i.legacycidInChangeTable != null
+        || i.muteCommonPathPrefixes != null
         || i.reviewCategoryStrategy != null) {
       throw new BadRequestException("unsupported option");
     }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReviewNoteMerger.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReviewNoteMerger.java
index 0c384b7..8b6da7b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReviewNoteMerger.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReviewNoteMerger.java
@@ -43,6 +43,7 @@
 import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.ObjectStream;
 import org.eclipse.jgit.notes.Note;
 import org.eclipse.jgit.notes.NoteMerger;
 import org.eclipse.jgit.util.io.UnionInputStream;
@@ -67,12 +68,13 @@
     ObjectLoader lo = reader.open(ours.getData());
     byte[] sep = new byte[] {'\n'};
     ObjectLoader lt = reader.open(theirs.getData());
-    UnionInputStream union = new UnionInputStream(
-        lo.openStream(),
-        new ByteArrayInputStream(sep),
-        lt.openStream());
-    ObjectId noteData = inserter.insert(Constants.OBJ_BLOB,
-        lo.getSize() + sep.length + lt.getSize(), union);
-    return new Note(ours, noteData);
+    try (ObjectStream os = lo.openStream();
+        ByteArrayInputStream b = new ByteArrayInputStream(sep);
+        ObjectStream ts = lt.openStream();
+        UnionInputStream union = new UnionInputStream(os, b, ts)) {
+      ObjectId noteData = inserter.insert(Constants.OBJ_BLOB,
+          lo.getSize() + sep.length + lt.getSize(), union);
+      return new Note(ours, noteData);
+    }
   }
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
index 2b73ff9..3d65fa7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
@@ -207,11 +207,11 @@
           schema.submoduleSubscriptions().bySubmodule(updatedBranch).toList();
 
       if (!subscribers.isEmpty()) {
-        String msgbuf = msg;
-        if (msgbuf == null) {
-          // Initialize the message buffer
-          msgbuf = "";
-
+        // Initialize the message buffer
+        StringBuilder sb = new StringBuilder();
+        if (msg != null) {
+          sb.append(msg);
+        } else {
           // The first updatedBranch on a cascade event of automatic
           // updates of repos is added to updatedSubscribers set so
           // if we face a situation having
@@ -227,8 +227,8 @@
                 && (c.getStatusCode() == CommitMergeStatus.CLEAN_MERGE
                     || c.getStatusCode() == CommitMergeStatus.CLEAN_PICK
                     || c.getStatusCode() == CommitMergeStatus.CLEAN_REBASE)) {
-              msgbuf += "\n";
-              msgbuf += c.getFullMessage();
+              sb.append("\n")
+                .append(c.getFullMessage());
             }
           }
         }
@@ -246,7 +246,7 @@
 
             Map<Branch.NameKey, String> paths = new HashMap<>(1);
               paths.put(updatedBranch, s.getPath());
-              updateGitlinks(s.getSuperProject(), myRw, modules, paths, msgbuf);
+              updateGitlinks(s.getSuperProject(), myRw, modules, paths, sb.toString());
             }
           } catch (SubmoduleException e) {
               log.warn("Cannot update gitlinks for " + s + " due to " + e.getMessage());
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/CommentsInNotesUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/CommentsInNotesUtil.java
index 652f37e..34ecbc0 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/CommentsInNotesUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/CommentsInNotesUtil.java
@@ -232,7 +232,9 @@
 
     int startLine = RawParseUtils.parseBase10(note, ptr.value, ptr);
     if (startLine == 0) {
-      return null;
+      range.setEndLine(0);
+      ptr.value += 1;
+      return range;
     }
 
     if (note[ptr.value] == '\n') {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/ServerPlugin.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/ServerPlugin.java
index a1d8ea5..0b037fb 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/ServerPlugin.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/ServerPlugin.java
@@ -253,12 +253,14 @@
             public File get() {
               if (!ready) {
                 synchronized (dataDir) {
-                  if (!dataDir.exists() && !dataDir.mkdirs()) {
-                    throw new ProvisionException(String.format(
-                        "Cannot create %s for plugin %s",
-                        dataDir.getAbsolutePath(), getName()));
+                  if (!ready) {
+                    if (!dataDir.exists() && !dataDir.mkdirs()) {
+                      throw new ProvisionException(String.format(
+                          "Cannot create %s for plugin %s",
+                          dataDir.getAbsolutePath(), getName()));
+                    }
+                    ready = true;
                   }
-                  ready = true;
                 }
               }
               return dataDir;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeModifiedException.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeModifiedException.java
new file mode 100644
index 0000000..f3ca8b6
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeModifiedException.java
@@ -0,0 +1,23 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.project;
+
+public class ChangeModifiedException extends InvalidChangeOperationException {
+  private static final long serialVersionUID = 1L;
+
+  public ChangeModifiedException(String msg) {
+    super(msg);
+  }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectsCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectsCollection.java
index 519f4f2..2f0386f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectsCollection.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectsCollection.java
@@ -31,6 +31,8 @@
 
 import java.io.IOException;
 
+import org.eclipse.jgit.lib.Constants;
+
 @Singleton
 public class ProjectsCollection implements
     RestCollection<TopLevelResource, ProjectResource>,
@@ -88,6 +90,9 @@
   }
 
   private ProjectResource _parse(String id) throws IOException {
+    if (id.endsWith(Constants.DOT_GIT_EXT)) {
+      id = id.substring(0, id.length() - Constants.DOT_GIT_EXT.length());
+    }
     ProjectControl ctl;
     try {
       ctl = controlFactory.controlFor(
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AndSource.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AndSource.java
index 82260b4..f48cfd8 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AndSource.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AndSource.java
@@ -130,7 +130,6 @@
       Paginated p = (Paginated) source;
       while (skipped && r.size() < p.limit() + start) {
         skipped = false;
-        last = null;
         ResultSet<ChangeData> next = p.restart(nextStart);
 
         for (ChangeData data : buffer(source, next)) {
@@ -139,7 +138,6 @@
           } else {
             skipped = true;
           }
-          last = data;
           nextStart++;
         }
       }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java
index 50b3d88..4e9e096 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java
@@ -32,7 +32,7 @@
 /** A version of the database schema. */
 public abstract class SchemaVersion {
   /** The current schema version. */
-  public static final Class<Schema_106> C = Schema_106.class;
+  public static final Class<Schema_107> C = Schema_107.class;
 
   public static int getBinaryVersion() {
     return guessVersion(C);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_107.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_107.java
new file mode 100644
index 0000000..13ab09a
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_107.java
@@ -0,0 +1,41 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.schema;
+
+import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gwtorm.jdbc.JdbcSchema;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class Schema_107 extends SchemaVersion {
+
+  @Inject
+  Schema_107(Provider<Schema_106> prior) {
+    super(prior);
+  }
+
+  @Override
+  protected void migrateData(ReviewDb db, UpdateUI ui) throws SQLException {
+    Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
+    try {
+      stmt.executeUpdate("UPDATE accounts set mute_common_path_prefixes = 'Y'");
+    } finally {
+      stmt.close();
+    }
+  }
+}
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java
index c356a19..db17f80 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java
@@ -812,7 +812,6 @@
         noteString);
   }
 
-
   @Test
   public void patchLineCommentMultipleOnePatchsetOneFileBothSides()
       throws Exception {
@@ -1154,6 +1153,34 @@
   }
 
   @Test
+  public void fileComment() throws Exception {
+    Change c = newChange();
+    ChangeUpdate update = newUpdate(c, otherUser);
+    String uuid = "uuid";
+    String messageForBase = "comment for base";
+    Timestamp now = TimeUtil.nowTs();
+    PatchSet.Id psId = c.currentPatchSetId();
+
+    PatchLineComment commentForBase =
+        newPublishedPatchLineComment(psId, "filename", uuid,
+        null, 0, otherUser, null, now, messageForBase,
+        (short) 0, "abcd1234abcd1234abcd1234abcd1234abcd1234");
+    update.setPatchSetId(psId);
+    update.upsertComment(commentForBase);
+    update.commit();
+
+    ChangeNotes notes = newNotes(c);
+    Multimap<PatchSet.Id, PatchLineComment> commentsForBase =
+        notes.getBaseComments();
+    Multimap<PatchSet.Id, PatchLineComment> commentsForPs =
+        notes.getPatchSetComments();
+
+    assertTrue(commentsForPs.isEmpty());
+    assertEquals(commentForBase,
+        Iterables.getOnlyElement(commentsForBase.get(psId)));
+  }
+
+  @Test
   public void patchLineCommentNoRange() throws Exception {
     Change c = newChange();
     ChangeUpdate update = newUpdate(c, otherUser);
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLog.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLog.java
index e093cfb..439b8c8 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLog.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLog.java
@@ -268,11 +268,11 @@
   }
 
   private String extractWhat(DispatchCommand dcmd) {
-    String commandName = dcmd.getCommandName();
+    StringBuilder commandName = new StringBuilder(dcmd.getCommandName());
     String[] args = dcmd.getArguments();
     for (int i = 1; i < args.length; i++) {
-      commandName = commandName + "." + args[i];
+      commandName.append(".").append(args[i]);
     }
-    return commandName;
+    return commandName.toString();
   }
 }
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
index 5e33c8f..3ac72a7 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
@@ -340,15 +340,16 @@
     }
 
     for (LabelType type : allProjectsControl.getLabelTypes().getLabelTypes()) {
-      String usage;
-      usage = "score for " + type.getName() + "\n";
+      StringBuilder usage = new StringBuilder("score for ")
+        .append(type.getName())
+        .append("\n");
 
       for (LabelValue v : type.getValues()) {
-        usage += v.format() + "\n";
+        usage.append(v.format()).append("\n");
       }
 
       final String name = "--" + type.getName().toLowerCase();
-      optionList.add(new ApproveOption(name, usage, type));
+      optionList.add(new ApproveOption(name, usage.toString(), type));
     }
 
     super.parseCommandLine();
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
index b484a3f..1cb442d 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
@@ -307,17 +307,17 @@
   private List<String> readSshKey(final List<String> sshKeys)
       throws UnsupportedEncodingException, IOException {
     if (!sshKeys.isEmpty()) {
-      String sshKey;
       int idx = sshKeys.indexOf("-");
       if (idx >= 0) {
-        sshKey = "";
+        StringBuilder sshKey = new StringBuilder();
         BufferedReader br =
             new BufferedReader(new InputStreamReader(in, "UTF-8"));
         String line;
         while ((line = br.readLine()) != null) {
-          sshKey += line + "\n";
+          sshKey.append(line)
+            .append("\n");
         }
-        sshKeys.set(idx, sshKey);
+        sshKeys.set(idx, sshKey.toString());
       }
     }
     return sshKeys;
diff --git a/lib/codemirror/cm.defs b/lib/codemirror/cm.defs
index cc0880e..db87b25 100644
--- a/lib/codemirror/cm.defs
+++ b/lib/codemirror/cm.defs
@@ -53,6 +53,7 @@
   'erlang',
   'gas',
   'gfm',
+  'go',
   'groovy',
   'haskell',
   'htmlmixed',