Merge "Document ProjectCreator"
diff --git a/java/com/google/gerrit/common/data/GarbageCollectionResult.java b/java/com/google/gerrit/common/data/GarbageCollectionResult.java
index 5ed0158..5e3601e 100644
--- a/java/com/google/gerrit/common/data/GarbageCollectionResult.java
+++ b/java/com/google/gerrit/common/data/GarbageCollectionResult.java
@@ -18,6 +18,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+/** A list of errors occurred during GC. */
 public class GarbageCollectionResult {
   protected List<Error> errors;
 
diff --git a/java/com/google/gerrit/extensions/api/projects/BanCommitInput.java b/java/com/google/gerrit/extensions/api/projects/BanCommitInput.java
index b0f674f..b24eca0 100644
--- a/java/com/google/gerrit/extensions/api/projects/BanCommitInput.java
+++ b/java/com/google/gerrit/extensions/api/projects/BanCommitInput.java
@@ -17,6 +17,7 @@
 import com.google.common.collect.Lists;
 import java.util.List;
 
+/** Commits that will forbidden to be uploaded. */
 public class BanCommitInput {
   public List<String> commits;
   public String reason;
diff --git a/java/com/google/gerrit/server/account/SetInactiveFlag.java b/java/com/google/gerrit/server/account/SetInactiveFlag.java
index a6c5d5c..32ed694 100644
--- a/java/com/google/gerrit/server/account/SetInactiveFlag.java
+++ b/java/com/google/gerrit/server/account/SetInactiveFlag.java
@@ -32,6 +32,7 @@
 import java.util.concurrent.atomic.AtomicReference;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 
+/** Toggler for account active state. */
 @Singleton
 public class SetInactiveFlag {
   private final PluginSetContext<AccountActivationValidationListener>
diff --git a/java/com/google/gerrit/server/git/BanCommit.java b/java/com/google/gerrit/server/git/BanCommit.java
index 4473ab7..242c11b 100644
--- a/java/com/google/gerrit/server/git/BanCommit.java
+++ b/java/com/google/gerrit/server/git/BanCommit.java
@@ -20,7 +20,6 @@
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.entities.RefNames;
 import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.git.LockFailureException;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.GerritPersonIdent;
 import com.google.gerrit.server.IdentifiedUser;
@@ -47,6 +46,12 @@
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevWalk;
 
+/**
+ * Logic for banning commits from being uploaded.
+ *
+ * <p>Gerrit has a per-project list of commits that are forbidden to be pushed. This class reads and
+ * writes the banned commits list in {@code refs/meta/reject-commits}.
+ */
 @Singleton
 public class BanCommit {
   /**
@@ -91,9 +96,14 @@
     this.tz = gerritIdent.getTimeZone();
   }
 
+  /**
+   * Bans a list of commits from the given project.
+   *
+   * <p>The user must be specified, so it can be checked for the {@code BAN_COMMIT} permission.
+   */
   public BanCommitResult ban(
       Project.NameKey project, CurrentUser user, List<ObjectId> commitsToBan, String reason)
-      throws AuthException, LockFailureException, IOException, PermissionBackendException {
+      throws AuthException, IOException, PermissionBackendException {
     permissionBackend.user(user).project(project).check(ProjectPermission.BAN_COMMIT);
 
     final BanCommitResult result = new BanCommitResult();
diff --git a/java/com/google/gerrit/server/git/BanCommitResult.java b/java/com/google/gerrit/server/git/BanCommitResult.java
index 9fadae2..c78123e 100644
--- a/java/com/google/gerrit/server/git/BanCommitResult.java
+++ b/java/com/google/gerrit/server/git/BanCommitResult.java
@@ -18,6 +18,7 @@
 import java.util.List;
 import org.eclipse.jgit.lib.ObjectId;
 
+/** The outcome of the {@link com.google.gerrit.server.git.BanCommit} operation. */
 public class BanCommitResult {
   private final List<ObjectId> newlyBannedCommits = new ArrayList<>(4);
   private final List<ObjectId> alreadyBannedCommits = new ArrayList<>(4);
diff --git a/java/com/google/gerrit/server/git/ChangeReportFormatter.java b/java/com/google/gerrit/server/git/ChangeReportFormatter.java
index f897a1d..e0efaef 100644
--- a/java/com/google/gerrit/server/git/ChangeReportFormatter.java
+++ b/java/com/google/gerrit/server/git/ChangeReportFormatter.java
@@ -18,6 +18,7 @@
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.entities.Change;
 
+/** Formatter for git command-line progress messages. */
 public interface ChangeReportFormatter {
   @AutoValue
   public abstract static class Input {
diff --git a/java/com/google/gerrit/server/git/DefaultChangeReportFormatter.java b/java/com/google/gerrit/server/git/DefaultChangeReportFormatter.java
index 5866c57..4f6094e 100644
--- a/java/com/google/gerrit/server/git/DefaultChangeReportFormatter.java
+++ b/java/com/google/gerrit/server/git/DefaultChangeReportFormatter.java
@@ -22,7 +22,7 @@
 import com.google.inject.Inject;
 import java.util.Optional;
 
-/** Print a change description for use in git command-line progress. */
+/** Default formatter for change descriptions for use in git command-line progress. */
 public class DefaultChangeReportFormatter implements ChangeReportFormatter {
   private static final int SUBJECT_MAX_LENGTH = 80;
   private static final String SUBJECT_CROP_APPENDIX = "...";
diff --git a/java/com/google/gerrit/server/git/DefaultQueueOp.java b/java/com/google/gerrit/server/git/DefaultQueueOp.java
index b30acfa..9fb1a9b 100644
--- a/java/com/google/gerrit/server/git/DefaultQueueOp.java
+++ b/java/com/google/gerrit/server/git/DefaultQueueOp.java
@@ -17,6 +17,10 @@
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
+/**
+ * Wrapper class so a Runnable can schedule itself onto the Gerrit Workqueue. Subclasses must
+ * implement the {@code run} method.
+ */
 public abstract class DefaultQueueOp implements Runnable {
   private final WorkQueue workQueue;
 
diff --git a/java/com/google/gerrit/server/git/GarbageCollection.java b/java/com/google/gerrit/server/git/GarbageCollection.java
index 090d439..9b52f48 100644
--- a/java/com/google/gerrit/server/git/GarbageCollection.java
+++ b/java/com/google/gerrit/server/git/GarbageCollection.java
@@ -16,6 +16,7 @@
 
 import com.google.common.collect.Sets;
 import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.common.Nullable;
 import com.google.gerrit.common.data.GarbageCollectionResult;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.events.GarbageCollectorListener;
@@ -37,6 +38,7 @@
 import org.eclipse.jgit.lib.TextProgressMonitor;
 import org.eclipse.jgit.storage.pack.PackConfig;
 
+/** Serial execution of GC on a list of repositories. */
 public class GarbageCollection {
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
@@ -69,8 +71,9 @@
     return run(projectNames, gcConfig.isAggressive(), writer);
   }
 
+  /** Runs GC on the given projects, serially. Progress is written to writer if non-null. */
   public GarbageCollectionResult run(
-      List<Project.NameKey> projectNames, boolean aggressive, PrintWriter writer) {
+      List<Project.NameKey> projectNames, boolean aggressive, @Nullable PrintWriter writer) {
     GarbageCollectionResult result = new GarbageCollectionResult();
     Set<Project.NameKey> projectsToGc = gcQueue.addAll(projectNames);
     for (Project.NameKey projectName :
diff --git a/java/com/google/gerrit/server/git/GarbageCollectionQueue.java b/java/com/google/gerrit/server/git/GarbageCollectionQueue.java
index e3a923b..5df9ab5 100644
--- a/java/com/google/gerrit/server/git/GarbageCollectionQueue.java
+++ b/java/com/google/gerrit/server/git/GarbageCollectionQueue.java
@@ -21,6 +21,7 @@
 import java.util.HashSet;
 import java.util.Set;
 
+/** A thread-safe list of projects scheduled for GC. */
 @Singleton
 public class GarbageCollectionQueue {
   private final Set<Project.NameKey> projectsScheduledForGc = new HashSet<>();
diff --git a/java/com/google/gerrit/server/restapi/project/BanCommit.java b/java/com/google/gerrit/server/restapi/project/BanCommit.java
index a20d462..eb5473d 100644
--- a/java/com/google/gerrit/server/restapi/project/BanCommit.java
+++ b/java/com/google/gerrit/server/restapi/project/BanCommit.java
@@ -31,6 +31,7 @@
 import java.util.List;
 import org.eclipse.jgit.lib.ObjectId;
 
+/** The REST endpoint that marks commits as banned in a project. */
 @Singleton
 public class BanCommit implements RestModifyView<ProjectResource, BanCommitInput> {
   private final com.google.gerrit.server.git.BanCommit banCommit;
diff --git a/java/com/google/gerrit/server/restapi/project/GarbageCollect.java b/java/com/google/gerrit/server/restapi/project/GarbageCollect.java
index 25a2c90..c5423e6 100644
--- a/java/com/google/gerrit/server/restapi/project/GarbageCollect.java
+++ b/java/com/google/gerrit/server/restapi/project/GarbageCollect.java
@@ -43,6 +43,7 @@
 import java.util.Collections;
 import java.util.Optional;
 
+/** REST endpoint that executes GC on a project. */
 @RequiresCapability(GlobalCapability.RUN_GC)
 @Singleton
 public class GarbageCollect
diff --git a/java/com/google/gerrit/server/update/RetryableAction.java b/java/com/google/gerrit/server/update/RetryableAction.java
index 9a2807a..75ebeb37 100644
--- a/java/com/google/gerrit/server/update/RetryableAction.java
+++ b/java/com/google/gerrit/server/update/RetryableAction.java
@@ -37,6 +37,17 @@
  * retry via {@link #retryOn(Predicate)}.
  */
 public class RetryableAction<T> {
+  /**
+   * Type of an retryable action.
+   *
+   * <p>The action type is used for two purposes:
+   *
+   * <ul>
+   *   <li>to determine the default timeout for executing the action (see {@link
+   *       RetryHelper#getDefaultTimeout(String)})
+   *   <li>as bucket for all retry metrics (see {@link RetryHelper.Metrics})
+   * </ul>
+   */
   public enum ActionType {
     ACCOUNT_UPDATE,
     CHANGE_UPDATE,
diff --git a/package.json b/package.json
index 95edf0b..2656f74 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
   "scripts": {
     "start": "polygerrit-ui/run-server.sh",
     "test": "WCT_HEADLESS_MODE=1 WCT_ARGS='--verbose -l chrome' ./polygerrit-ui/app/run_test.sh",
-    "eslint": "./node_modules/eslint/bin/eslint.js --ignore-pattern 'bower_components/' --ignore-pattern 'gr-linked-text' --ignore-pattern 'scripts/vendor' --ext .html,.js polygerrit-ui/app",
+    "eslint": "./node_modules/eslint/bin/eslint.js --ext .html,.js polygerrit-ui/app",
     "eslintfix": "npm run eslint -- --fix",
     "test-template": "./polygerrit-ui/app/run_template_test.sh",
     "polylint": "bazel test polygerrit-ui/app:polylint_test"
diff --git a/polygerrit-ui/app/lint_test.sh b/polygerrit-ui/app/lint_test.sh
index 35939ba..bcd94ba 100755
--- a/polygerrit-ui/app/lint_test.sh
+++ b/polygerrit-ui/app/lint_test.sh
@@ -19,4 +19,4 @@
     exit 1
 fi
 
-${eslint_bin} --ignore-pattern 'bower_components/' --ignore-pattern 'gr-linked-text' --ignore-pattern 'scripts/vendor' --ext .html,.js .
+${eslint_bin} --ext .html,.js .
diff --git a/tools/dev-hooks/pre-commit b/tools/dev-hooks/pre-commit
new file mode 100755
index 0000000..b77f382
--- /dev/null
+++ b/tools/dev-hooks/pre-commit
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# Part of Gerrit Code Review (https://www.gerritcodereview.com/)
+#
+# Copyright (C) 2019 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.
+
+
+# To enable this hook:
+# - copy this file or content to ".git/hooks/pre-commit"
+# - (optional if you copied this file) make it executable: `chmod +x .git/hooks/pre-commit`
+
+set -ue
+
+# gitroot, default to .
+gitroot=$(git rev-parse --show-cdup)
+gitroot=${gitroot:-.};
+
+# eslint
+eslint=${gitroot}/node_modules/eslint/bin/eslint.js
+
+# Run eslint over changed frontend code
+CHANGED_UI_FILES=$(git diff --cached --name-only -- '*.js' '*.html' | grep 'polygerrit-ui') && true
+if [ "${CHANGED_UI_FILES}" ]; then
+  if $eslint --fix ${CHANGED_UI_FILES}; then
+    # Add again in case lint fix modified some files
+    git add ${CHANGED_UI_FILES}
+    exit 0
+  else
+    echo "Failed to fix all linter issues.";
+    exit 1
+  fi
+else
+  echo "No UI files changed"
+  exit 0
+fi
\ No newline at end of file