Merge changes I264c7525,I0c2fe374

* changes:
  Allow to trace REST requests that match a URI regex by config
  Allow to configure automatic tracing by project or calling user
diff --git a/Documentation/config-labels.txt b/Documentation/config-labels.txt
index ff43520..9c90ba7 100644
--- a/Documentation/config-labels.txt
+++ b/Documentation/config-labels.txt
@@ -297,12 +297,13 @@
 [[label_copyAllScoresOnTrivialRebase]]
 === `label.Label-Name.copyAllScoresOnTrivialRebase`
 
-If true, all scores for the label are copied forward when a new patch
-set is uploaded that is a trivial rebase. A new patch set is considered
-as trivial rebase if the commit message is the same as in the previous
-patch set and if it has the same code delta as the previous patch set.
-This is the case if the change was rebased onto a different parent, or
-if the parent did not change at all.
+If true, all scores for the label are copied forward when a new patch set is
+uploaded that is a trivial rebase. A new patch set is considered to be trivial
+rebase if the commit message is the same as in the previous patch set and if it
+has the same diff (including context lines) as the previous patch set. This is
+the case if the change was rebased onto a different parent and that rebase did
+not require git to perform any conflict resolution, or if the parent did not
+change at all.
 
 This can be used to enable sticky approvals, reducing turn-around for
 trivial rebases prior to submitting a change.
@@ -313,13 +314,13 @@
 [[label_copyAllScoresIfNoCodeChange]]
 === `label.Label-Name.copyAllScoresIfNoCodeChange`
 
-If true, all scores for the label are copied forward when a new patch
-set is uploaded that has the same parent tree as the previous patch
-set and the same code delta as the previous patch set. This means only
-the commit message is different. This can be used to enable sticky
-approvals on labels that only depend on the code, reducing turn-around
-if only the commit message is changed prior to submitting a change.
-For the Verified label that is optionally installed by the
+If true, all scores for the label are copied forward when a new patch set is
+uploaded that has the same parent tree as the previous patch set and the same
+code diff (including context lines) as the previous patch set. This means only
+the commit message is different; the change hasn't even been rebased. This can
+be used to enable sticky approvals on labels that only depend on the code,
+reducing turn-around if only the commit message is changed prior to submitting a
+change. For the Verified label that is optionally installed by the
 link:pgm-init.html[init] site program this is enabled by default.
 
 Defaults to false.
diff --git a/java/com/google/gerrit/server/git/validators/CommitValidators.java b/java/com/google/gerrit/server/git/validators/CommitValidators.java
index da051dd..02a24f7 100644
--- a/java/com/google/gerrit/server/git/validators/CommitValidators.java
+++ b/java/com/google/gerrit/server/git/validators/CommitValidators.java
@@ -146,12 +146,7 @@
               new CommitterUploaderValidator(user, perm, urlFormatter.get()),
               new SignedOffByValidator(user, perm, projectState),
               new ChangeIdValidator(
-                  projectState,
-                  user,
-                  urlFormatter.get(),
-                  installCommitMsgHookCommand,
-                  sshInfo,
-                  change),
+                  user, urlFormatter.get(), installCommitMsgHookCommand, sshInfo, change),
               new ConfigValidator(projectConfigFactory, branch, user, rw, allUsers, allProjects),
               new BannedCommitsValidator(rejectCommits),
               new PluginCommitValidationListener(pluginValidators, skipValidation),
@@ -178,12 +173,7 @@
               new AuthorUploaderValidator(user, perm, urlFormatter.get()),
               new SignedOffByValidator(user, perm, projectCache.checkedGet(branch.project())),
               new ChangeIdValidator(
-                  projectState,
-                  user,
-                  urlFormatter.get(),
-                  installCommitMsgHookCommand,
-                  sshInfo,
-                  change),
+                  user, urlFormatter.get(), installCommitMsgHookCommand, sshInfo, change),
               new ConfigValidator(projectConfigFactory, branch, user, rw, allUsers, allProjects),
               new PluginCommitValidationListener(pluginValidators),
               new ExternalIdUpdateListener(allUsers, externalIdsConsistencyChecker),
@@ -257,7 +247,6 @@
 
     private static final Pattern CHANGE_ID = Pattern.compile(CHANGE_ID_PATTERN);
 
-    private final ProjectState projectState;
     private final UrlFormatter urlFormatter;
     private final String installCommitMsgHookCommand;
     private final SshInfo sshInfo;
@@ -265,13 +254,11 @@
     private final Change change;
 
     public ChangeIdValidator(
-        ProjectState projectState,
         IdentifiedUser user,
         UrlFormatter urlFormatter,
         String installCommitMsgHookCommand,
         SshInfo sshInfo,
         Change change) {
-      this.projectState = projectState;
       this.urlFormatter = urlFormatter;
       this.installCommitMsgHookCommand = installCommitMsgHookCommand;
       this.sshInfo = sshInfo;
diff --git a/java/com/google/gerrit/server/mail/send/ProjectWatch.java b/java/com/google/gerrit/server/mail/send/ProjectWatch.java
index 06a2e0d..eb3b831 100644
--- a/java/com/google/gerrit/server/mail/send/ProjectWatch.java
+++ b/java/com/google/gerrit/server/mail/send/ProjectWatch.java
@@ -99,9 +99,9 @@
           try {
             add(matching, state.getNameKey(), nc);
           } catch (QueryParseException e) {
-            logger.atWarning().withCause(e).log(
-                "Project %s has invalid notify %s filter \"%s\"",
-                state.getName(), nc.getName(), nc.getFilter());
+            logger.atInfo().log(
+                "Project %s has invalid notify %s filter \"%s\": %s",
+                state.getName(), nc.getName(), nc.getFilter(), e.getMessage());
           }
         }
       }
@@ -232,8 +232,8 @@
       logger.atFine().log("The filter did not match for account %s; skip notification", accountId);
     } catch (QueryParseException e) {
       // Ignore broken filter expressions.
-      logger.atWarning().withCause(e).log(
-          "Account %s has invalid filter in project watch %s", accountId, key);
+      logger.atInfo().log(
+          "Account %s has invalid filter in project watch %s: %s", accountId, key, e.getMessage());
     }
     return false;
   }
diff --git a/java/com/google/gerrit/server/restapi/account/PutUsername.java b/java/com/google/gerrit/server/restapi/account/PutUsername.java
index bc1ffc8..76a641d 100644
--- a/java/com/google/gerrit/server/restapi/account/PutUsername.java
+++ b/java/com/google/gerrit/server/restapi/account/PutUsername.java
@@ -20,9 +20,10 @@
 import com.google.gerrit.exceptions.DuplicateKeyException;
 import com.google.gerrit.extensions.api.accounts.UsernameInput;
 import com.google.gerrit.extensions.client.AccountFieldName;
-import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.reviewdb.client.Account;
@@ -71,9 +72,7 @@
 
   @Override
   public String apply(AccountResource rsrc, UsernameInput input)
-      throws AuthException, MethodNotAllowedException, UnprocessableEntityException,
-          ResourceConflictException, IOException, ConfigInvalidException,
-          PermissionBackendException {
+      throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException {
     if (!self.get().hasSameAccountId(rsrc.getUser())) {
       permissionBackend.currentUser().check(GlobalPermission.ADMINISTRATE_SERVER);
     }
@@ -82,17 +81,13 @@
       throw new MethodNotAllowedException("realm does not allow editing username");
     }
 
-    if (input == null) {
-      input = new UsernameInput();
-    }
-
     Account.Id accountId = rsrc.getUser().getAccountId();
     if (!externalIds.byAccount(accountId, SCHEME_USERNAME).isEmpty()) {
       throw new MethodNotAllowedException("Username cannot be changed.");
     }
 
-    if (Strings.isNullOrEmpty(input.username)) {
-      return input.username;
+    if (input == null || Strings.isNullOrEmpty(input.username)) {
+      throw new BadRequestException("input required");
     }
 
     if (!ExternalId.isValidUsername(input.username)) {
diff --git a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index cc99a90..3d9b88d 100644
--- a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -2663,10 +2663,6 @@
     return cds.get(0);
   }
 
-  private static void pushForReviewOk(TestRepository<?> testRepo) throws GitAPIException {
-    pushForReview(testRepo, RemoteRefUpdate.Status.OK, null);
-  }
-
   private static void pushForReviewRejected(TestRepository<?> testRepo, String expectedMessage)
       throws GitAPIException {
     pushForReview(testRepo, RemoteRefUpdate.Status.REJECTED_OTHER_REASON, expectedMessage);