]> source.dussan.org Git - gitblit.git/commitdiff
Merge receive processing into one class
authorJames Moger <james.moger@gitblit.com>
Fri, 27 Sep 2013 13:21:23 +0000 (09:21 -0400)
committerJames Moger <james.moger@gitblit.com>
Sat, 28 Sep 2013 01:31:17 +0000 (21:31 -0400)
Change-Id: I603d4524914e94ec8e02c3689b65465b42c23dd7

src/main/java/com/gitblit/git/GitblitReceivePack.java [new file with mode: 0644]
src/main/java/com/gitblit/git/GitblitReceivePackFactory.java
src/main/java/com/gitblit/git/GitblitUploadPackFactory.java
src/main/java/com/gitblit/git/ReceiveHook.java [deleted file]
src/main/java/com/gitblit/git/SideBandProgressMonitor.java [new file with mode: 0644]
src/test/config/test-gitblit.properties

diff --git a/src/main/java/com/gitblit/git/GitblitReceivePack.java b/src/main/java/com/gitblit/git/GitblitReceivePack.java
new file mode 100644 (file)
index 0000000..2d648bd
--- /dev/null
@@ -0,0 +1,467 @@
+/*\r
+ * Copyright 2013 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.git;\r
+\r
+import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_SIDE_BAND_64K;\r
+import groovy.lang.Binding;\r
+import groovy.util.GroovyScriptEngine;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.text.MessageFormat;\r
+import java.util.Collection;\r
+import java.util.LinkedHashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.concurrent.TimeUnit;\r
+\r
+import org.eclipse.jgit.lib.BatchRefUpdate;\r
+import org.eclipse.jgit.lib.NullProgressMonitor;\r
+import org.eclipse.jgit.lib.PersonIdent;\r
+import org.eclipse.jgit.lib.ProgressMonitor;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.jgit.revwalk.RevCommit;\r
+import org.eclipse.jgit.transport.PostReceiveHook;\r
+import org.eclipse.jgit.transport.PreReceiveHook;\r
+import org.eclipse.jgit.transport.ReceiveCommand;\r
+import org.eclipse.jgit.transport.ReceiveCommand.Result;\r
+import org.eclipse.jgit.transport.ReceivePack;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.gitblit.Constants;\r
+import com.gitblit.Constants.AccessRestrictionType;\r
+import com.gitblit.GitBlit;\r
+import com.gitblit.Keys;\r
+import com.gitblit.client.Translation;\r
+import com.gitblit.models.RepositoryModel;\r
+import com.gitblit.models.UserModel;\r
+import com.gitblit.utils.ArrayUtils;\r
+import com.gitblit.utils.ClientLogger;\r
+import com.gitblit.utils.CommitCache;\r
+import com.gitblit.utils.JGitUtils;\r
+import com.gitblit.utils.RefLogUtils;\r
+import com.gitblit.utils.StringUtils;\r
+\r
+\r
+/**\r
+ * GitblitReceivePack processes receive commands.  It also executes Groovy pre-\r
+ * and post- receive hooks.\r
+ *\r
+ * The general execution flow is:\r
+ * <ol>\r
+ *    <li>onPreReceive()</li>\r
+ *    <li>executeCommands()</li>\r
+ *    <li>onPostReceive()</li>\r
+ * </ol>\r
+ *\r
+ * @author Android Open Source Project\r
+ * @author James Moger\r
+ *\r
+ */\r
+public class GitblitReceivePack extends ReceivePack implements PreReceiveHook, PostReceiveHook {\r
+\r
+       private static final Logger LOGGER = LoggerFactory.getLogger(GitblitReceivePack.class);\r
+\r
+       protected final RepositoryModel repository;\r
+\r
+       protected final UserModel user;\r
+\r
+       protected final File groovyDir;\r
+\r
+       protected String gitblitUrl;\r
+\r
+       protected String repositoryUrl;\r
+\r
+       protected GroovyScriptEngine gse;\r
+\r
+       public GitblitReceivePack(Repository db, RepositoryModel repository, UserModel user) {\r
+               super(db);\r
+               this.repository = repository;\r
+               this.user = user == null ? UserModel.ANONYMOUS : user;\r
+               this.groovyDir = GitBlit.getGroovyScriptsFolder();\r
+               try {\r
+                       // set Grape root\r
+                       File grapeRoot = GitBlit.getFileOrFolder(Keys.groovy.grapeFolder, "${baseFolder}/groovy/grape").getAbsoluteFile();\r
+                       grapeRoot.mkdirs();\r
+                       System.setProperty("grape.root", grapeRoot.getAbsolutePath());\r
+                       this.gse = new GroovyScriptEngine(groovyDir.getAbsolutePath());\r
+               } catch (IOException e) {\r
+               }\r
+\r
+               // set advanced ref permissions\r
+               setAllowCreates(user.canCreateRef(repository));\r
+               setAllowDeletes(user.canDeleteRef(repository));\r
+               setAllowNonFastForwards(user.canRewindRef(repository));\r
+               \r
+               // setup pre and post receive hook\r
+               setPreReceiveHook(this);\r
+               setPostReceiveHook(this);\r
+       }\r
+\r
+       /**\r
+        * Instrumentation point where the incoming push event has been parsed,\r
+        * validated, objects created BUT refs have not been updated. You might\r
+        * use this to enforce a branch-write permissions model.\r
+        */\r
+       @Override\r
+       public void onPreReceive(ReceivePack rp, Collection<ReceiveCommand> commands) {\r
+\r
+               if (repository.isFrozen) {\r
+                       // repository is frozen/readonly\r
+                       for (ReceiveCommand cmd : commands) {\r
+                               sendRejection(cmd, "Gitblit does not allow pushes to \"{0}\" because it is frozen!", repository.name);\r
+                       }\r
+                       return;\r
+               }\r
+\r
+               if (!repository.isBare) {\r
+                       // repository has a working copy\r
+                       for (ReceiveCommand cmd : commands) {\r
+                               sendRejection(cmd, "Gitblit does not allow pushes to \"{0}\" because it has a working copy!", repository.name);\r
+                       }\r
+                       return;\r
+               }\r
+\r
+               if (!user.canPush(repository)) {\r
+                       // user does not have push permissions\r
+                       for (ReceiveCommand cmd : commands) {\r
+                               sendRejection(cmd, "User \"{0}\" does not have push permissions for \"{1}\"!", user.username, repository.name);\r
+                       }\r
+                       return;\r
+               }\r
+\r
+               if (repository.accessRestriction.atLeast(AccessRestrictionType.PUSH) && repository.verifyCommitter) {\r
+                       // enforce committer verification\r
+                       if (StringUtils.isEmpty(user.emailAddress)) {\r
+                               // emit warning if user does not have an email address\r
+                               LOGGER.warn(MessageFormat.format("Consider setting an email address for {0} ({1}) to improve committer verification.", user.getDisplayName(), user.username));\r
+                       }\r
+\r
+                       // Optionally enforce that the committer of first parent chain\r
+                       // match the account being used to push the commits.\r
+                       //\r
+                       // This requires all merge commits are executed with the "--no-ff"\r
+                       // option to force a merge commit even if fast-forward is possible.\r
+                       // This ensures that the chain first parents has the commit\r
+                       // identity of the merging user.\r
+                       boolean allRejected = false;\r
+                       for (ReceiveCommand cmd : commands) {\r
+                               String firstParent = null;\r
+                               try {\r
+                                       List<RevCommit> commits = JGitUtils.getRevLog(rp.getRepository(), cmd.getOldId().name(), cmd.getNewId().name());\r
+                                       for (RevCommit commit : commits) {\r
+\r
+                                               if (firstParent != null) {\r
+                                       if (!commit.getName().equals(firstParent)) {\r
+                                               // ignore: commit is right-descendant of a merge\r
+                                               continue;\r
+                                       }\r
+                               }\r
+\r
+                                               // update expected next commit id\r
+                                               if (commit.getParentCount() == 0) {\r
+                                       firstParent = null;\r
+                                               } else {\r
+                                                       firstParent = commit.getParents()[0].getId().getName();\r
+                                               }\r
+\r
+                                               PersonIdent committer = commit.getCommitterIdent();\r
+                                               if (!user.is(committer.getName(), committer.getEmailAddress())) {\r
+                                                       String reason;\r
+                                                       if (StringUtils.isEmpty(user.emailAddress)) {\r
+                                                               // account does not have an email address\r
+                                                               reason = MessageFormat.format("{0} by {1} <{2}> was not committed by {3} ({4})",\r
+                                                                               commit.getId().name(), committer.getName(), StringUtils.isEmpty(committer.getEmailAddress()) ? "?":committer.getEmailAddress(), user.getDisplayName(), user.username);\r
+                                                       } else {\r
+                                                               // account has an email address\r
+                                                               reason = MessageFormat.format("{0} by {1} <{2}> was not committed by {3} ({4}) <{5}>",\r
+                                                                               commit.getId().name(), committer.getName(), StringUtils.isEmpty(committer.getEmailAddress()) ? "?":committer.getEmailAddress(), user.getDisplayName(), user.username, user.emailAddress);\r
+                                                       }\r
+                                                       LOGGER.warn(reason);\r
+                                                       cmd.setResult(Result.REJECTED_OTHER_REASON, reason);\r
+                                                       allRejected &= true;\r
+                                                       break;\r
+                                               } else {\r
+                                                       allRejected = false;\r
+                                               }\r
+                                       }\r
+                               } catch (Exception e) {\r
+                                       LOGGER.error("Failed to verify commits were made by pushing user", e);\r
+                               }\r
+                       }\r
+\r
+                       if (allRejected) {\r
+                               // all ref updates rejected, abort\r
+                               return;\r
+                       }\r
+               }\r
+\r
+               // reset branch commit cache on REWIND and DELETE\r
+               for (ReceiveCommand cmd : commands) {\r
+                       String ref = cmd.getRefName();\r
+                       if (ref.startsWith(Constants.R_HEADS)) {\r
+                               switch (cmd.getType()) {\r
+                               case UPDATE_NONFASTFORWARD:\r
+                               case DELETE:\r
+                                       CommitCache.instance().clear(repository.name, ref);\r
+                                       break;\r
+                               default:\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               Set<String> scripts = new LinkedHashSet<String>();\r
+               scripts.addAll(GitBlit.self().getPreReceiveScriptsInherited(repository));\r
+               if (!ArrayUtils.isEmpty(repository.preReceiveScripts)) {\r
+                       scripts.addAll(repository.preReceiveScripts);\r
+               }\r
+               runGroovy(commands, scripts);\r
+               for (ReceiveCommand cmd : commands) {\r
+                       if (!Result.NOT_ATTEMPTED.equals(cmd.getResult())) {\r
+                               LOGGER.warn(MessageFormat.format("{0} {1} because \"{2}\"", cmd.getNewId()\r
+                                               .getName(), cmd.getResult(), cmd.getMessage()));\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Instrumentation point where the incoming push has been applied to the\r
+        * repository. This is the point where we would trigger a Jenkins build\r
+        * or send an email.\r
+        */\r
+       @Override\r
+       public void onPostReceive(ReceivePack rp, Collection<ReceiveCommand> commands) {\r
+               if (commands.size() == 0) {\r
+                       LOGGER.debug("skipping post-receive hooks, no refs created, updated, or removed");\r
+                       return;\r
+               }\r
+\r
+               // log ref changes\r
+               for (ReceiveCommand cmd : commands) {\r
+\r
+                       if (Result.OK.equals(cmd.getResult())) {\r
+                               // add some logging for important ref changes\r
+                               switch (cmd.getType()) {\r
+                               case DELETE:\r
+                                       LOGGER.info(MessageFormat.format("{0} DELETED {1} in {2} ({3})", user.username, cmd.getRefName(), repository.name, cmd.getOldId().name()));\r
+                                       break;\r
+                               case CREATE:\r
+                                       LOGGER.info(MessageFormat.format("{0} CREATED {1} in {2}", user.username, cmd.getRefName(), repository.name));\r
+                                       break;\r
+                               case UPDATE:\r
+                                       LOGGER.info(MessageFormat.format("{0} UPDATED {1} in {2} (from {3} to {4})", user.username, cmd.getRefName(), repository.name, cmd.getOldId().name(), cmd.getNewId().name()));\r
+                                       break;\r
+                               case UPDATE_NONFASTFORWARD:\r
+                                       LOGGER.info(MessageFormat.format("{0} UPDATED NON-FAST-FORWARD {1} in {2} (from {3} to {4})", user.username, cmd.getRefName(), repository.name, cmd.getOldId().name(), cmd.getNewId().name()));\r
+                                       break;\r
+                               default:\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               if (repository.useIncrementalPushTags) {\r
+                       // tag each pushed branch tip\r
+                       String emailAddress = user.emailAddress == null ? rp.getRefLogIdent().getEmailAddress() : user.emailAddress;\r
+                       PersonIdent userIdent = new PersonIdent(user.getDisplayName(), emailAddress);\r
+\r
+                       for (ReceiveCommand cmd : commands) {\r
+                               if (!cmd.getRefName().startsWith(Constants.R_HEADS)) {\r
+                                       // only tag branch ref changes\r
+                                       continue;\r
+                               }\r
+\r
+                               if (!ReceiveCommand.Type.DELETE.equals(cmd.getType())\r
+                                               && ReceiveCommand.Result.OK.equals(cmd.getResult())) {\r
+                                       String objectId = cmd.getNewId().getName();\r
+                                       String branch = cmd.getRefName().substring(Constants.R_HEADS.length());\r
+                                       // get translation based on the server's locale setting\r
+                                       String template = Translation.get("gb.incrementalPushTagMessage");\r
+                                       String msg = MessageFormat.format(template, branch);\r
+                                       String prefix;\r
+                                       if (StringUtils.isEmpty(repository.incrementalPushTagPrefix)) {\r
+                                               prefix = GitBlit.getString(Keys.git.defaultIncrementalPushTagPrefix, "r");\r
+                                       } else {\r
+                                               prefix = repository.incrementalPushTagPrefix;\r
+                                       }\r
+\r
+                                       JGitUtils.createIncrementalRevisionTag(\r
+                                                       rp.getRepository(),\r
+                                                       objectId,\r
+                                                       userIdent,\r
+                                                       prefix,\r
+                                                       "0",\r
+                                                       msg);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // update push log\r
+               try {\r
+                       RefLogUtils.updateRefLog(user, rp.getRepository(), commands);\r
+                       LOGGER.debug(MessageFormat.format("{0} push log updated", repository.name));\r
+               } catch (Exception e) {\r
+                       LOGGER.error(MessageFormat.format("Failed to update {0} pushlog", repository.name), e);\r
+               }\r
+\r
+               // run Groovy hook scripts\r
+               Set<String> scripts = new LinkedHashSet<String>();\r
+               scripts.addAll(GitBlit.self().getPostReceiveScriptsInherited(repository));\r
+               if (!ArrayUtils.isEmpty(repository.postReceiveScripts)) {\r
+                       scripts.addAll(repository.postReceiveScripts);\r
+               }\r
+               runGroovy(commands, scripts);\r
+       }\r
+\r
+       /** Execute commands to update references. */\r
+       @Override\r
+       protected void executeCommands() {\r
+               List<ReceiveCommand> toApply = filterCommands(Result.NOT_ATTEMPTED);\r
+               if (toApply.isEmpty()) {\r
+                       return;\r
+               }\r
+\r
+               ProgressMonitor updating = NullProgressMonitor.INSTANCE;\r
+               boolean sideBand = isCapabilityEnabled(CAPABILITY_SIDE_BAND_64K);\r
+               if (sideBand) {\r
+                       SideBandProgressMonitor pm = new SideBandProgressMonitor(msgOut);\r
+                       pm.setDelayStart(250, TimeUnit.MILLISECONDS);\r
+                       updating = pm;\r
+               }\r
+\r
+               BatchRefUpdate batch = getRepository().getRefDatabase().newBatchUpdate();\r
+               batch.setAllowNonFastForwards(isAllowNonFastForwards());\r
+               batch.setRefLogIdent(getRefLogIdent());\r
+               batch.setRefLogMessage("push", true);\r
+\r
+               for (ReceiveCommand cmd : toApply) {\r
+                       if (Result.NOT_ATTEMPTED != cmd.getResult()) {\r
+                               // Already rejected by the core receive process.\r
+                               continue;\r
+                       }\r
+                       batch.addCommand(cmd);\r
+               }\r
+\r
+               if (!batch.getCommands().isEmpty()) {\r
+                       try {\r
+                               batch.execute(getRevWalk(), updating);\r
+                       } catch (IOException err) {\r
+                               for (ReceiveCommand cmd : toApply) {\r
+                                       if (cmd.getResult() == Result.NOT_ATTEMPTED) {\r
+                                               sendRejection(cmd, "lock error: {0}", err.getMessage());\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       protected void setGitblitUrl(String url) {\r
+               this.gitblitUrl = url;\r
+       }\r
+\r
+       protected void setRepositoryUrl(String url) {\r
+               this.repositoryUrl = url;\r
+       }\r
+\r
+       protected void sendRejection(final ReceiveCommand cmd, final String why, Object... objects) {\r
+               String text;\r
+               if (ArrayUtils.isEmpty(objects)) {\r
+                       text = why;\r
+               } else {\r
+                       text = MessageFormat.format(why, objects);\r
+               }\r
+               cmd.setResult(Result.REJECTED_OTHER_REASON, text);\r
+               LOGGER.error(text + " (" + user.username + ")");\r
+       }\r
+\r
+       protected void sendMessage(String msg, Object... objects) {\r
+               String text;\r
+               if (ArrayUtils.isEmpty(objects)) {\r
+                       text = msg;\r
+                       super.sendMessage(msg);\r
+               } else {\r
+                       text = MessageFormat.format(msg, objects);\r
+                       super.sendMessage(text);\r
+               }\r
+               LOGGER.info(text + " (" + user.username + ")");\r
+       }\r
+\r
+       protected void sendError(String msg, Object... objects) {\r
+               String text;\r
+               if (ArrayUtils.isEmpty(objects)) {\r
+                       text = msg;\r
+                       super.sendError(msg);\r
+               } else {\r
+                       text = MessageFormat.format(msg, objects);\r
+                       super.sendError(text);\r
+               }\r
+               LOGGER.error(text + " (" + user.username + ")");\r
+       }\r
+\r
+       /**\r
+        * Runs the specified Groovy hook scripts.\r
+        *\r
+        * @param repository\r
+        * @param user\r
+        * @param commands\r
+        * @param scripts\r
+        */\r
+       protected void runGroovy(Collection<ReceiveCommand> commands, Set<String> scripts) {\r
+               if (scripts == null || scripts.size() == 0) {\r
+                       // no Groovy scripts to execute\r
+                       return;\r
+               }\r
+\r
+               Binding binding = new Binding();\r
+               binding.setVariable("gitblit", GitBlit.self());\r
+               binding.setVariable("repository", repository);\r
+               binding.setVariable("receivePack", this);\r
+               binding.setVariable("user", user);\r
+               binding.setVariable("commands", commands);\r
+               binding.setVariable("url", gitblitUrl);\r
+               binding.setVariable("logger", LOGGER);\r
+               binding.setVariable("clientLogger", new ClientLogger(this));\r
+               for (String script : scripts) {\r
+                       if (StringUtils.isEmpty(script)) {\r
+                               continue;\r
+                       }\r
+                       // allow script to be specified without .groovy extension\r
+                       // this is easier to read in the settings\r
+                       File file = new File(groovyDir, script);\r
+                       if (!file.exists() && !script.toLowerCase().endsWith(".groovy")) {\r
+                               file = new File(groovyDir, script + ".groovy");\r
+                               if (file.exists()) {\r
+                                       script = file.getName();\r
+                               }\r
+                       }\r
+                       try {\r
+                               Object result = gse.run(script, binding);\r
+                               if (result instanceof Boolean) {\r
+                                       if (!((Boolean) result)) {\r
+                                               LOGGER.error(MessageFormat.format(\r
+                                                               "Groovy script {0} has failed!  Hook scripts aborted.", script));\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       } catch (Exception e) {\r
+                               LOGGER.error(\r
+                                               MessageFormat.format("Failed to execute Groovy script {0}", script), e);\r
+                       }\r
+               }\r
+       }\r
+}\r
index 77a3df63b7ad21bf73b43252db4697930a577d8c..b9eb8a6252ae47070cbc9fb3cb1f90f342363003 100644 (file)
@@ -30,11 +30,11 @@ import com.gitblit.GitBlit;
 import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.HttpUtils;
+import com.gitblit.utils.StringUtils;
 
 /**
- * The receive pack factory creates a receive pack which accepts pushes from
- * clients.
- * 
+ * The receive pack factory creates the receive pack which processes pushes.
+ *
  * @author James Moger
  *
  * @param <X> the connection type
@@ -42,62 +42,59 @@ import com.gitblit.utils.HttpUtils;
 public class GitblitReceivePackFactory<X> implements ReceivePackFactory<X> {
 
        protected final Logger logger = LoggerFactory.getLogger(GitblitReceivePackFactory.class);
-       
+
        @Override
        public ReceivePack create(X req, Repository db)
                        throws ServiceNotEnabledException, ServiceNotAuthorizedException {
 
-               final ReceivePack rp = new ReceivePack(db);
                UserModel user = UserModel.ANONYMOUS;
                String repositoryName = "";
                String origin = "";
                String gitblitUrl = "";
+               String repositoryUrl = "";
                int timeout = 0;
-               
+
                if (req instanceof HttpServletRequest) {
-                       // http/https request may or may not be authenticated 
+                       // http/https request may or may not be authenticated
                        HttpServletRequest request = (HttpServletRequest) req;
                        repositoryName = request.getAttribute("gitblitRepositoryName").toString();
                        origin = request.getRemoteHost();
                        gitblitUrl = HttpUtils.getGitblitURL(request);
+                       repositoryUrl = request.getRequestURI();
 
                        // determine pushing user
                        String username = request.getRemoteUser();
-                       if (username != null && !"".equals(username)) {
-                               user = GitBlit.self().getUserModel(username);
-                               if (user == null) {
-                                       // anonymous push, create a temporary usermodel
-                                       user = new UserModel(username);
+                       if (!StringUtils.isEmpty(username)) {
+                               UserModel u = GitBlit.self().getUserModel(username);
+                               if (u != null) {
+                                       user = u;
                                }
                        }
                } else if (req instanceof GitDaemonClient) {
-                       // git daemon request is alway anonymous
+                       // git daemon request is always anonymous
                        GitDaemonClient client = (GitDaemonClient) req;
                        repositoryName = client.getRepositoryName();
                        origin = client.getRemoteAddress().getHostAddress();
+
                        // set timeout from Git daemon
                        timeout = client.getDaemon().getTimeout();
                }
 
-               // set pushing user identity for reflog
-               rp.setRefLogIdent(new PersonIdent(user.username, user.username + "@" + origin));
-               rp.setTimeout(timeout);
-               
-               // set advanced ref permissions
-               RepositoryModel repository = GitBlit.self().getRepositoryModel(repositoryName);
-               rp.setAllowCreates(user.canCreateRef(repository));
-               rp.setAllowDeletes(user.canDeleteRef(repository));
-               rp.setAllowNonFastForwards(user.canRewindRef(repository));
+               // TODO make this a setting
+               boolean allowAnonymousPushes = true;
+               if (!allowAnonymousPushes && UserModel.ANONYMOUS.equals(user)) {
+                       // prohibit anonymous pushes
+                       throw new ServiceNotEnabledException();
+               }
 
-               // setup the receive hook
-               ReceiveHook hook = new ReceiveHook();
-               hook.user = user;
-               hook.repository = repository;
-               hook.gitblitUrl = gitblitUrl;
+               final RepositoryModel repository = GitBlit.self().getRepositoryModel(repositoryName);
 
-               rp.setPreReceiveHook(hook);
-               rp.setPostReceiveHook(hook);
+               final GitblitReceivePack rp = new GitblitReceivePack(db, repository, user);
+               rp.setGitblitUrl(gitblitUrl);
+               rp.setRepositoryUrl(repositoryUrl);
+               rp.setRefLogIdent(new PersonIdent(user.username, user.username + "@" + origin));
+               rp.setTimeout(timeout);
 
                return rp;
        }
-}
+}
\ No newline at end of file
index 1756ac531d812a8b52bef9524a0480e2345c3b35..6c06fa3dbc1d0569876a58e18d3efce0818b1510 100644 (file)
@@ -16,7 +16,6 @@
 package com.gitblit.git;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -30,6 +29,7 @@ import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.eclipse.jgit.transport.resolver.UploadPackFactory;
 
+import com.gitblit.Constants;
 import com.gitblit.GitBlit;
 import com.gitblit.models.UserModel;
 
@@ -94,7 +94,7 @@ public class GitblitUploadPackFactory<X> implements UploadPackFactory<X> {
                        // JGit's RefMap is custom and does not support iterator removal :(
                        List<String> toRemove = new ArrayList<String>();
                        for (String ref : refs.keySet()) {
-                               if (ref.startsWith("refs/gitblit/")) {
+                               if (ref.startsWith(Constants.R_GITBLIT)) {
                                        toRemove.add(ref);
                                }
                        }
@@ -104,4 +104,4 @@ public class GitblitUploadPackFactory<X> implements UploadPackFactory<X> {
                        return refs;
                }
        }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/git/ReceiveHook.java b/src/main/java/com/gitblit/git/ReceiveHook.java
deleted file mode 100644 (file)
index d75a238..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/*\r
- * Copyright 2011 gitblit.com.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package com.gitblit.git;\r
-\r
-import groovy.lang.Binding;\r
-import groovy.util.GroovyScriptEngine;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.text.MessageFormat;\r
-import java.util.Collection;\r
-import java.util.LinkedHashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-\r
-import org.eclipse.jgit.lib.PersonIdent;\r
-import org.eclipse.jgit.revwalk.RevCommit;\r
-import org.eclipse.jgit.transport.PostReceiveHook;\r
-import org.eclipse.jgit.transport.PreReceiveHook;\r
-import org.eclipse.jgit.transport.ReceiveCommand;\r
-import org.eclipse.jgit.transport.ReceiveCommand.Result;\r
-import org.eclipse.jgit.transport.ReceivePack;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-import com.gitblit.Constants;\r
-import com.gitblit.Constants.AccessRestrictionType;\r
-import com.gitblit.GitBlit;\r
-import com.gitblit.Keys;\r
-import com.gitblit.client.Translation;\r
-import com.gitblit.models.RepositoryModel;\r
-import com.gitblit.models.UserModel;\r
-import com.gitblit.utils.ArrayUtils;\r
-import com.gitblit.utils.ClientLogger;\r
-import com.gitblit.utils.CommitCache;\r
-import com.gitblit.utils.JGitUtils;\r
-import com.gitblit.utils.RefLogUtils;\r
-import com.gitblit.utils.StringUtils;\r
-\r
-/**\r
- * The Gitblit receive hook allows for special processing on push events.\r
- * That might include rejecting writes to specific branches or executing a\r
- * script.\r
- * \r
- * @author James Moger\r
- * \r
- */\r
-public class ReceiveHook implements PreReceiveHook, PostReceiveHook {\r
-\r
-       protected final Logger logger = LoggerFactory.getLogger(ReceiveHook.class);\r
-\r
-       protected UserModel user;\r
-       \r
-       protected RepositoryModel repository;\r
-\r
-       protected String gitblitUrl;\r
-\r
-       private GroovyScriptEngine gse;\r
-\r
-       private File groovyDir;\r
-\r
-       public ReceiveHook() {\r
-               groovyDir = GitBlit.getGroovyScriptsFolder();\r
-               try {\r
-                       // set Grape root\r
-                       File grapeRoot = GitBlit.getFileOrFolder(Keys.groovy.grapeFolder, "${baseFolder}/groovy/grape").getAbsoluteFile();\r
-                       grapeRoot.mkdirs();\r
-                       System.setProperty("grape.root", grapeRoot.getAbsolutePath());\r
-\r
-                       gse = new GroovyScriptEngine(groovyDir.getAbsolutePath());                      \r
-               } catch (IOException e) {\r
-                       //throw new ServletException("Failed to instantiate Groovy Script Engine!", e);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Instrumentation point where the incoming push event has been parsed,\r
-        * validated, objects created BUT refs have not been updated. You might\r
-        * use this to enforce a branch-write permissions model.\r
-        */\r
-       @Override\r
-       public void onPreReceive(ReceivePack rp, Collection<ReceiveCommand> commands) {\r
-               if (repository.isFrozen) {\r
-                       // repository is frozen/readonly\r
-                       String reason = MessageFormat.format("Gitblit does not allow pushes to \"{0}\" because it is frozen!", repository.name);\r
-                       logger.warn(reason);\r
-                       for (ReceiveCommand cmd : commands) {\r
-                               cmd.setResult(Result.REJECTED_OTHER_REASON, reason);\r
-                       }\r
-                       return;\r
-               }\r
-               \r
-               if (!repository.isBare) {\r
-                       // repository has a working copy\r
-                       String reason = MessageFormat.format("Gitblit does not allow pushes to \"{0}\" because it has a working copy!", repository.name);\r
-                       logger.warn(reason);\r
-                       for (ReceiveCommand cmd : commands) {\r
-                               cmd.setResult(Result.REJECTED_OTHER_REASON, reason);\r
-                       }\r
-                       return;\r
-               }\r
-\r
-               if (!user.canPush(repository)) {\r
-                       // user does not have push permissions\r
-                       String reason = MessageFormat.format("User \"{0}\" does not have push permissions for \"{1}\"!", user.username, repository.name);\r
-                       logger.warn(reason);\r
-                       for (ReceiveCommand cmd : commands) {\r
-                               cmd.setResult(Result.REJECTED_OTHER_REASON, reason);\r
-                       }\r
-                       return;\r
-               }\r
-\r
-               if (repository.accessRestriction.atLeast(AccessRestrictionType.PUSH) && repository.verifyCommitter) {\r
-                       // enforce committer verification\r
-                       if (StringUtils.isEmpty(user.emailAddress)) {\r
-                               // emit warning if user does not have an email address \r
-                               logger.warn(MessageFormat.format("Consider setting an email address for {0} ({1}) to improve committer verification.", user.getDisplayName(), user.username));\r
-                       }\r
-\r
-                       // Optionally enforce that the committer of the left parent chain\r
-                       // match the account being used to push the commits.\r
-                       // \r
-                       // This requires all merge commits are executed with the "--no-ff"\r
-                       // option to force a merge commit even if fast-forward is possible.\r
-                       // This ensures that the chain of left parents has the commit\r
-                       // identity of the merging user.\r
-                       boolean allRejected = false;\r
-                       for (ReceiveCommand cmd : commands) {\r
-                               String linearParent = null;\r
-                               try {\r
-                                       List<RevCommit> commits = JGitUtils.getRevLog(rp.getRepository(), cmd.getOldId().name(), cmd.getNewId().name());\r
-                                       for (RevCommit commit : commits) {\r
-                                               \r
-                                               if (linearParent != null) {\r
-                                       if (!commit.getName().equals(linearParent)) {\r
-                                               // ignore: commit is right-descendant of a merge\r
-                                               continue;\r
-                                       }\r
-                               }\r
-                                               \r
-                                               // update expected next commit id\r
-                                               if (commit.getParentCount() == 0) {\r
-                                       linearParent = null;\r
-                                               } else {\r
-                                                       linearParent = commit.getParents()[0].getId().getName();\r
-                                               }\r
-                                               \r
-                                               PersonIdent committer = commit.getCommitterIdent();\r
-                                               if (!user.is(committer.getName(), committer.getEmailAddress())) {\r
-                                                       String reason;\r
-                                                       if (StringUtils.isEmpty(user.emailAddress)) {\r
-                                                               // account does not have an email address\r
-                                                               reason = MessageFormat.format("{0} by {1} <{2}> was not committed by {3} ({4})", \r
-                                                                               commit.getId().name(), committer.getName(), StringUtils.isEmpty(committer.getEmailAddress()) ? "?":committer.getEmailAddress(), user.getDisplayName(), user.username);\r
-                                                       } else {\r
-                                                               // account has an email address\r
-                                                               reason = MessageFormat.format("{0} by {1} <{2}> was not committed by {3} ({4}) <{5}>", \r
-                                                                               commit.getId().name(), committer.getName(), StringUtils.isEmpty(committer.getEmailAddress()) ? "?":committer.getEmailAddress(), user.getDisplayName(), user.username, user.emailAddress);\r
-                                                       }\r
-                                                       logger.warn(reason);\r
-                                                       cmd.setResult(Result.REJECTED_OTHER_REASON, reason);\r
-                                                       allRejected &= true;\r
-                                                       break;\r
-                                               } else {\r
-                                                       allRejected = false;\r
-                                               }\r
-                                       }\r
-                               } catch (Exception e) {\r
-                                       logger.error("Failed to verify commits were made by pushing user", e);\r
-                               }\r
-                       }\r
-\r
-                       if (allRejected) {\r
-                               // all ref updates rejected, abort\r
-                               return;\r
-                       }\r
-               }\r
-               \r
-               // reset branch commit cache on REWIND and DELETE\r
-               for (ReceiveCommand cmd : commands) {\r
-                       String ref = cmd.getRefName();\r
-                       if (ref.startsWith(Constants.R_HEADS)) {\r
-                               switch (cmd.getType()) {\r
-                               case UPDATE_NONFASTFORWARD:\r
-                               case DELETE:\r
-                                       CommitCache.instance().clear(repository.name, ref);\r
-                                       break;\r
-                               default:\r
-                                       break;\r
-                               }\r
-                       }\r
-               }\r
-\r
-               Set<String> scripts = new LinkedHashSet<String>();\r
-               scripts.addAll(GitBlit.self().getPreReceiveScriptsInherited(repository));\r
-               if (!ArrayUtils.isEmpty(repository.preReceiveScripts)) {\r
-                       scripts.addAll(repository.preReceiveScripts);\r
-               }\r
-               runGroovy(repository, user, commands, rp, scripts);\r
-               for (ReceiveCommand cmd : commands) {\r
-                       if (!Result.NOT_ATTEMPTED.equals(cmd.getResult())) {\r
-                               logger.warn(MessageFormat.format("{0} {1} because \"{2}\"", cmd.getNewId()\r
-                                               .getName(), cmd.getResult(), cmd.getMessage()));\r
-                       }\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Instrumentation point where the incoming push has been applied to the\r
-        * repository. This is the point where we would trigger a Jenkins build\r
-        * or send an email.\r
-        */\r
-       @Override\r
-       public void onPostReceive(ReceivePack rp, Collection<ReceiveCommand> commands) {\r
-               if (commands.size() == 0) {\r
-                       logger.debug("skipping post-receive hooks, no refs created, updated, or removed");\r
-                       return;\r
-               }\r
-\r
-               // log ref changes\r
-               for (ReceiveCommand cmd : commands) {\r
-                       if (Result.OK.equals(cmd.getResult())) {\r
-                               // add some logging for important ref changes\r
-                               switch (cmd.getType()) {\r
-                               case DELETE:\r
-                                       logger.info(MessageFormat.format("{0} DELETED {1} in {2} ({3})", user.username, cmd.getRefName(), repository.name, cmd.getOldId().name()));\r
-                                       break;\r
-                               case CREATE:\r
-                                       logger.info(MessageFormat.format("{0} CREATED {1} in {2}", user.username, cmd.getRefName(), repository.name));\r
-                                       break;\r
-                               case UPDATE:\r
-                                       logger.info(MessageFormat.format("{0} UPDATED {1} in {2} (from {3} to {4})", user.username, cmd.getRefName(), repository.name, cmd.getOldId().name(), cmd.getNewId().name()));\r
-                                       break;\r
-                               case UPDATE_NONFASTFORWARD:\r
-                                       logger.info(MessageFormat.format("{0} UPDATED NON-FAST-FORWARD {1} in {2} (from {3} to {4})", user.username, cmd.getRefName(), repository.name, cmd.getOldId().name(), cmd.getNewId().name()));\r
-                                       break;\r
-                               default:\r
-                                       break;\r
-                               }\r
-                       }\r
-               }\r
-\r
-               if (repository.useIncrementalPushTags) {\r
-                       // tag each pushed branch tip\r
-                       String emailAddress = user.emailAddress == null ? rp.getRefLogIdent().getEmailAddress() : user.emailAddress;\r
-                       PersonIdent userIdent = new PersonIdent(user.getDisplayName(), emailAddress);\r
-\r
-                       for (ReceiveCommand cmd : commands) {\r
-                               if (!cmd.getRefName().startsWith("refs/heads/")) {\r
-                                       // only tag branch ref changes\r
-                                       continue;\r
-                               }\r
-\r
-                               if (!ReceiveCommand.Type.DELETE.equals(cmd.getType())\r
-                                               && ReceiveCommand.Result.OK.equals(cmd.getResult())) {\r
-                                       String objectId = cmd.getNewId().getName();\r
-                                       String branch = cmd.getRefName().substring("refs/heads/".length());\r
-                                       // get translation based on the server's locale setting\r
-                                       String template = Translation.get("gb.incrementalPushTagMessage");\r
-                                       String msg = MessageFormat.format(template, branch);\r
-                                       String prefix;\r
-                                       if (StringUtils.isEmpty(repository.incrementalPushTagPrefix)) {\r
-                                               prefix = GitBlit.getString(Keys.git.defaultIncrementalPushTagPrefix, "r");\r
-                                       } else {\r
-                                               prefix = repository.incrementalPushTagPrefix;\r
-                                       }\r
-\r
-                                       JGitUtils.createIncrementalRevisionTag(\r
-                                                       rp.getRepository(),\r
-                                                       objectId,\r
-                                                       userIdent,\r
-                                                       prefix,\r
-                                                       "0",\r
-                                                       msg);\r
-                               }\r
-                       }                               \r
-               }\r
-\r
-               // update push log\r
-               try {\r
-                       RefLogUtils.updateRefLog(user, rp.getRepository(), commands);\r
-                       logger.debug(MessageFormat.format("{0} push log updated", repository.name));\r
-               } catch (Exception e) {\r
-                       logger.error(MessageFormat.format("Failed to update {0} pushlog", repository.name), e);\r
-               }\r
-\r
-               // run Groovy hook scripts \r
-               Set<String> scripts = new LinkedHashSet<String>();\r
-               scripts.addAll(GitBlit.self().getPostReceiveScriptsInherited(repository));\r
-               if (!ArrayUtils.isEmpty(repository.postReceiveScripts)) {\r
-                       scripts.addAll(repository.postReceiveScripts);\r
-               }\r
-               runGroovy(repository, user, commands, rp, scripts);\r
-       }\r
-\r
-       /**\r
-        * Runs the specified Groovy hook scripts.\r
-        * \r
-        * @param repository\r
-        * @param user\r
-        * @param commands\r
-        * @param scripts\r
-        */\r
-       protected void runGroovy(RepositoryModel repository, UserModel user,\r
-                       Collection<ReceiveCommand> commands, ReceivePack rp, Set<String> scripts) {\r
-               if (scripts == null || scripts.size() == 0) {\r
-                       // no Groovy scripts to execute\r
-                       return;\r
-               }\r
-\r
-               Binding binding = new Binding();\r
-               binding.setVariable("gitblit", GitBlit.self());\r
-               binding.setVariable("repository", repository);\r
-               binding.setVariable("receivePack", rp);\r
-               binding.setVariable("user", user);\r
-               binding.setVariable("commands", commands);\r
-               binding.setVariable("url", gitblitUrl);\r
-               binding.setVariable("logger", logger);\r
-               binding.setVariable("clientLogger", new ClientLogger(rp));\r
-               for (String script : scripts) {\r
-                       if (StringUtils.isEmpty(script)) {\r
-                               continue;\r
-                       }\r
-                       // allow script to be specified without .groovy extension\r
-                       // this is easier to read in the settings\r
-                       File file = new File(groovyDir, script);\r
-                       if (!file.exists() && !script.toLowerCase().endsWith(".groovy")) {\r
-                               file = new File(groovyDir, script + ".groovy");\r
-                               if (file.exists()) {\r
-                                       script = file.getName();\r
-                               }\r
-                       }\r
-                       try {\r
-                               Object result = gse.run(script, binding);\r
-                               if (result instanceof Boolean) {\r
-                                       if (!((Boolean) result)) {\r
-                                               logger.error(MessageFormat.format(\r
-                                                               "Groovy script {0} has failed!  Hook scripts aborted.", script));\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       } catch (Exception e) {\r
-                               logger.error(\r
-                                               MessageFormat.format("Failed to execute Groovy script {0}", script), e);\r
-                       }\r
-               }\r
-       }\r
-}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/git/SideBandProgressMonitor.java b/src/main/java/com/gitblit/git/SideBandProgressMonitor.java
new file mode 100644 (file)
index 0000000..0322f18
--- /dev/null
@@ -0,0 +1,127 @@
+/*\r
+ * Copyright (C) 2008-2010, Google Inc.\r
+ * and other copyright owners as documented in the project's IP log.\r
+ *\r
+ * This program and the accompanying materials are made available\r
+ * under the terms of the Eclipse Distribution License v1.0 which\r
+ * accompanies this distribution, is reproduced below, and is\r
+ * available at http://www.eclipse.org/org/documents/edl-v10.php\r
+ *\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ *   copyright notice, this list of conditions and the following\r
+ *   disclaimer in the documentation and/or other materials provided\r
+ *   with the distribution.\r
+ *\r
+ * - Neither the name of the Eclipse Foundation, Inc. nor the\r
+ *   names of its contributors may be used to endorse or promote\r
+ *   products derived from this software without specific prior\r
+ *   written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\r
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package com.gitblit.git;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+\r
+import org.eclipse.jgit.lib.BatchingProgressMonitor;\r
+import org.eclipse.jgit.lib.Constants;\r
+\r
+/** Write progress messages out to the sideband channel. */\r
+class SideBandProgressMonitor extends BatchingProgressMonitor {\r
+       private final OutputStream out;\r
+\r
+       private boolean write;\r
+\r
+       SideBandProgressMonitor(final OutputStream os) {\r
+               out = os;\r
+               write = true;\r
+       }\r
+\r
+       @Override\r
+       protected void onUpdate(String taskName, int workCurr) {\r
+               StringBuilder s = new StringBuilder();\r
+               format(s, taskName, workCurr);\r
+               s.append("   \r"); //$NON-NLS-1$\r
+               send(s);\r
+       }\r
+\r
+       @Override\r
+       protected void onEndTask(String taskName, int workCurr) {\r
+               StringBuilder s = new StringBuilder();\r
+               format(s, taskName, workCurr);\r
+               s.append(", done\n"); //$NON-NLS-1$\r
+               send(s);\r
+       }\r
+\r
+       private void format(StringBuilder s, String taskName, int workCurr) {\r
+               s.append(taskName);\r
+               s.append(": "); //$NON-NLS-1$\r
+               s.append(workCurr);\r
+       }\r
+\r
+       @Override\r
+       protected void onUpdate(String taskName, int cmp, int totalWork, int pcnt) {\r
+               StringBuilder s = new StringBuilder();\r
+               format(s, taskName, cmp, totalWork, pcnt);\r
+               s.append("   \r"); //$NON-NLS-1$\r
+               send(s);\r
+       }\r
+\r
+       @Override\r
+       protected void onEndTask(String taskName, int cmp, int totalWork, int pcnt) {\r
+               StringBuilder s = new StringBuilder();\r
+               format(s, taskName, cmp, totalWork, pcnt);\r
+               s.append("\n"); //$NON-NLS-1$\r
+               send(s);\r
+       }\r
+\r
+       private void format(StringBuilder s, String taskName, int cmp,\r
+                       int totalWork, int pcnt) {\r
+               s.append(taskName);\r
+               s.append(": "); //$NON-NLS-1$\r
+               if (pcnt < 100)\r
+                       s.append(' ');\r
+               if (pcnt < 10)\r
+                       s.append(' ');\r
+               s.append(pcnt);\r
+               s.append("% ("); //$NON-NLS-1$\r
+               s.append(cmp);\r
+               s.append("/"); //$NON-NLS-1$\r
+               s.append(totalWork);\r
+               s.append(")"); //$NON-NLS-1$\r
+       }\r
+\r
+       private void send(StringBuilder s) {\r
+               if (write) {\r
+                       try {\r
+                               out.write(Constants.encode(s.toString()));\r
+                               out.flush();\r
+                       } catch (IOException err) {\r
+                               write = false;\r
+                       }\r
+               }\r
+       }\r
+}
\ No newline at end of file
index 7876407b7b12375f3498c6f9138c98e43c62a17b..0d797b401d1af0a4ef366070af241cdd35fafe39 100644 (file)
@@ -1,7 +1,8 @@
 #
 # Gitblit Unit Testing properties
 #
-
+git.allowAnonymousPushes = true
+git.defaultAccessRestriction = NONE
 git.repositoriesFolder = ${baseFolder}/git
 git.searchRepositoriesSubfolders = true
 git.enableGitServlet = true