Add configuration for checking of Received Objects

Adds ability to configure the checking of Received Objects that is
performed by jgit on a per project basis based on the project.config

See jgit setCheckReceivedObjects() function

Currently this is set to true in all cases so that all objects are
checked for validity. Unfortunetly some pre-existing repositories
have known issues within their git history with Invalid Trees written
by other(non jgit) implementations. These issues can be seen in
repositories when git fsck --full is run.

While doing this check is correct in most cases it causes issues when
repositories are being sync'd from upstream servers or transfered from
other git servers to gerrit.

This changes adds a git-checks section to the project.config that allows
the checkReceivedObjects key to be used to control this check.

The default is always true unless overridden in the project.config file.

Test Procedure:
In order to test this you need to create a projects with the ability
to directy upload changes/branches including merge commits. You will also
need the ability to forge author/commiter identity. This project should
have no initial commit.

Locate a repository with the following formatted issue:
warning in tree <SHA SUM>: contains zero-padded file modes

Firstly attempt to push the effected tree to the created project, this
should fail.

Clone the test project and checkout refs/meta/config modify the
project.config file to include:

[receive]
	checkReceivedObjects = true

Upload this new config and attempt to push the effected tree again, this
should still fail.

Modify the config to be:

[receive]
	checkReceivedObjects = false

Upload this config and then push the effected tree again, this should succeed.

More info regarding this issues is located here:

https://groups.google.com/forum/#!topic/repo-discuss/O_TaspFfY7s
https://groups.google.com/forum/#!topic/repo-discuss/b_jX_7pal3U

---------------------

Change-Id: I9f566557dfdc0a33c7c88d76fc7c247dd838dea4
diff --git a/Documentation/config-project-config.txt b/Documentation/config-project-config.txt
index e86cdae..2fb256f 100644
--- a/Documentation/config-project-config.txt
+++ b/Documentation/config-project-config.txt
@@ -129,6 +129,21 @@
 +
 Common unit suffixes of k, m, or g are supported.
 
+[[receive.checkReceivedObjects]]receive.checkReceivedObjects::
++
+Controls whether or not the JGit functionality for checking received objects
+is enabled.
++
+By default Gerrit checks the validity of git objects. Setting this variable to
+false should not be used unless a project with history containing invalid
+objects needs to be pushed into a Gerrit repository.
++
+This functionality is provided as some other git implementations have allowed
+bad history to be written into git repositories. If these repositories need pushing
+up to Gerrit then the JGit checks need to be disabled.
++
+The default value for this is true, false disables the checks.
+
 [[submit-section]]
 === Submit section
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
index 1db7b4a..55f4ff7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
@@ -114,6 +114,7 @@
   private static final String KEY_MAX_OBJECT_SIZE_LIMIT = "maxObjectSizeLimit";
   private static final String KEY_REQUIRE_CONTRIBUTOR_AGREEMENT =
       "requireContributorAgreement";
+  private static final String KEY_CHECK_RECEIVED_OBJECTS = "checkReceivedObjects";
 
   private static final String SUBMIT = "submit";
   private static final String KEY_ACTION = "action";
@@ -157,6 +158,7 @@
   private ObjectId rulesId;
   private long maxObjectSizeLimit;
   private Map<String, Config> pluginConfigs;
+  private boolean checkReceivedObjects;
 
   public static ProjectConfig read(MetaDataUpdate update) throws IOException,
       ConfigInvalidException {
@@ -339,6 +341,13 @@
   }
 
   /**
+   * @return the checkReceivedObjects for this project, default is true.
+   */
+  public boolean getCheckReceivedObjects() {
+    return checkReceivedObjects;
+  }
+
+  /**
    * Check all GroupReferences use current group name, repairing stale ones.
    *
    * @param groupBackend cache to use when looking up group information by UUID.
@@ -408,8 +417,7 @@
     loadLabelSections(rc);
     loadCommentLinkSections(rc);
     loadPluginSections(rc);
-
-    maxObjectSizeLimit = rc.getLong(RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT, 0);
+    loadReceiveSection(rc);
   }
 
   private void loadAccountsSection(
@@ -696,6 +704,11 @@
     commentLinkSections = ImmutableList.copyOf(commentLinkSections);
   }
 
+  private void loadReceiveSection(Config rc) {
+    checkReceivedObjects = rc.getBoolean(RECEIVE, KEY_CHECK_RECEIVED_OBJECTS, true);
+    maxObjectSizeLimit = rc.getLong(RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT, 0);
+  }
+
   private void loadPluginSections(Config rc) {
     pluginConfigs = Maps.newHashMap();
     for (String plugin : rc.getSubsections(PLUGIN)) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index 29efb81..e602ccb 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -406,10 +406,12 @@
 
     this.messageSender = new ReceivePackMessageSender();
 
+    ProjectState ps = projectControl.getProjectState();
+
     rp.setAllowCreates(true);
     rp.setAllowDeletes(true);
     rp.setAllowNonFastForwards(true);
-    rp.setCheckReceivedObjects(true);
+    rp.setCheckReceivedObjects(ps.getConfig().getCheckReceivedObjects());
     rp.setRefFilter(new RefFilter() {
       @Override
       public Map<String, Ref> filter(Map<String, Ref> refs) {