summaryrefslogtreecommitdiffstats
path: root/distrib
diff options
context:
space:
mode:
authorJames Moger <james.moger@gitblit.com>2013-01-15 22:17:08 -0500
committerJames Moger <james.moger@gitblit.com>2013-01-15 22:41:20 -0500
commit93d506581010cdb6308ae3d282a8bc513966d70d (patch)
treea0b11035f4feb010a3e68f92c22ff4d74b062ff3 /distrib
parent657a6596eb95635abd29c0a21befffc43da49d09 (diff)
downloadgitblit-93d506581010cdb6308ae3d282a8bc513966d70d.tar.gz
gitblit-93d506581010cdb6308ae3d282a8bc513966d70d.zip
Support --baseFolder parameter and small data reorganization
Diffstat (limited to 'distrib')
-rw-r--r--distrib/authority.cmd2
-rw-r--r--distrib/gitblit5
-rw-r--r--distrib/gitblit-centos5
-rw-r--r--distrib/gitblit-stop.cmd2
-rw-r--r--distrib/gitblit-ubuntu3
-rw-r--r--distrib/gitblit.cmd2
-rw-r--r--distrib/gitblit.properties47
-rw-r--r--distrib/groovy/.gitignore1
-rw-r--r--distrib/groovy/blockpush.groovy94
-rw-r--r--distrib/groovy/jenkins.groovy76
-rw-r--r--distrib/groovy/localclone.groovy106
-rw-r--r--distrib/groovy/protect-refs.groovy113
-rw-r--r--distrib/groovy/sendmail-html.groovy516
-rw-r--r--distrib/groovy/sendmail.groovy176
-rw-r--r--distrib/groovy/thebuggenie.groovy88
-rw-r--r--distrib/installService.cmd4
-rw-r--r--distrib/projects.conf3
17 files changed, 1223 insertions, 20 deletions
diff --git a/distrib/authority.cmd b/distrib/authority.cmd
index 145f5242..75cb0cf7 100644
--- a/distrib/authority.cmd
+++ b/distrib/authority.cmd
@@ -1 +1 @@
-@java -jar authority.jar
+@java -jar authority.jar --baseFolder data
diff --git a/distrib/gitblit b/distrib/gitblit
index cd1f967e..6c74d547 100644
--- a/distrib/gitblit
+++ b/distrib/gitblit
@@ -3,6 +3,7 @@
set -e
GITBLIT_PATH=/opt/gitblit
+GITBLIT_BASE_FOLDER=/opt/gitblit/data
GITBLIT_HTTP_PORT=0
GITBLIT_HTTPS_PORT=8443
source ${GITBLIT_PATH}/java-proxy-config.sh
@@ -14,13 +15,13 @@ case "$1" in
start)
log_action_begin_msg "Starting gitblit server"
cd $GITBLIT_PATH
- $JAVA $GITBLIT_PATH/gitblit.jar --httpsPort $GITBLIT_HTTPS_PORT --httpPort $GITBLIT_HTTP_PORT > /dev/null &
+ $JAVA $GITBLIT_PATH/gitblit.jar --httpsPort $GITBLIT_HTTPS_PORT --httpPort $GITBLIT_HTTP_PORT --baseFolder $GITBLIT_BASE_FOLDER > /dev/null &
log_action_end_msg $?
;;
stop)
log_action_begin_msg "Stopping gitblit server"
cd $GITBLIT_PATH
- $JAVA $GITBLIT_PATH/gitblit.jar --stop > /dev/null &
+ $JAVA $GITBLIT_PATH/gitblit.jar --baseFolder $GITBLIT_BASE_FOLDER --stop > /dev/null &
log_action_end_msg $?
;;
force-reload|restart)
diff --git a/distrib/gitblit-centos b/distrib/gitblit-centos
index c608097e..04c9a9b4 100644
--- a/distrib/gitblit-centos
+++ b/distrib/gitblit-centos
@@ -6,6 +6,7 @@
# change theses values (default values)
GITBLIT_PATH=/opt/gitblit
+GITBLIT_BASE_FOLDER=/opt/gitblit/data
GITBLIT_HTTP_PORT=0
GITBLIT_HTTPS_PORT=8443
source ${GITBLIT_PATH}/java-proxy-config.sh
@@ -19,7 +20,7 @@ case "$1" in
then
echo $"Starting gitblit server"
cd $GITBLIT_PATH
- $JAVA $GITBLIT_PATH/gitblit.jar --httpsPort $GITBLIT_HTTPS_PORT --httpPort $GITBLIT_HTTP_PORT > /dev/null &
+ $JAVA $GITBLIT_PATH/gitblit.jar --httpsPort $GITBLIT_HTTPS_PORT --httpPort $GITBLIT_HTTP_PORT --baseFolder $GITBLIT_BASE_FOLDER > /dev/null &
echo "."
exit $RETVAL
fi
@@ -30,7 +31,7 @@ case "$1" in
then
echo $"Stopping gitblit server"
cd $GITBLIT_PATH
- $JAVA $GITBLIT_PATH/gitblit.jar --stop > /dev/null &
+ $JAVA $GITBLIT_PATH/gitblit.jar --baseFolder $GITBLIT_BASE_FOLDER --stop > /dev/null &
echo "."
exit $RETVAL
fi
diff --git a/distrib/gitblit-stop.cmd b/distrib/gitblit-stop.cmd
index c139d57b..5820c491 100644
--- a/distrib/gitblit-stop.cmd
+++ b/distrib/gitblit-stop.cmd
@@ -1 +1 @@
-@java -jar gitblit.jar --stop
+@java -jar gitblit.jar --stop --baseFolder data
diff --git a/distrib/gitblit-ubuntu b/distrib/gitblit-ubuntu
index b047ed97..4ff275d0 100644
--- a/distrib/gitblit-ubuntu
+++ b/distrib/gitblit-ubuntu
@@ -8,9 +8,10 @@ PATH=/sbin:/bin:/usr/bin:/usr/sbin
# change theses values (default values)
GITBLIT_PATH=/opt/gitblit
+GITBLIT_BASE_FOLDER=/opt/gitblit/data
GITBLIT_USER="gitblit"
source ${GITBLIT_PATH}/java-proxy-config.sh
-ARGS="-server -Xmx1024M ${JAVA_PROXY_CONFIG} -Djava.awt.headless=true -jar gitblit.jar"
+ARGS="-server -Xmx1024M ${JAVA_PROXY_CONFIG} -Djava.awt.headless=true -jar gitblit.jar --baseFolder $GITBLIT_BASE_FOLDER"
RETVAL=0
diff --git a/distrib/gitblit.cmd b/distrib/gitblit.cmd
index ce96a797..3006a687 100644
--- a/distrib/gitblit.cmd
+++ b/distrib/gitblit.cmd
@@ -1 +1 @@
-@java -jar gitblit.jar
+@java -jar gitblit.jar --baseFolder data
diff --git a/distrib/gitblit.properties b/distrib/gitblit.properties
index 758137e3..f5cc19b6 100644
--- a/distrib/gitblit.properties
+++ b/distrib/gitblit.properties
@@ -1,4 +1,19 @@
#
+# Gitblit Settings
+#
+
+# This settings file supports parameterization from the command-line for the
+# following command-line parameters:
+#
+# --baseFolder ${baseFolder} SINCE 1.2.1
+#
+# Settings that support ${baseFolder} parameter substitution are indicated with the
+# BASEFOLDER attribute. If the --baseFolder argument is unspecified, ${baseFolder}
+# and it's trailing / will be discarded from the setting value leaving a relative
+# path that is equivalent to pre-1.2.1 releases.
+#
+# e.g. "${baseFolder}/git" becomes "git", if --baseFolder is unspecified
+#
# Git Servlet Settings
#
@@ -10,7 +25,8 @@
#
# SINCE 0.5.0
# RESTART REQUIRED
-git.repositoriesFolder = git
+# BASEFOLDER
+git.repositoriesFolder = ${baseFolder}/git
# Build the available repository list at startup and cache this list for reuse.
# This reduces disk io when presenting the repositories page, responding to rpcs,
@@ -299,14 +315,16 @@ git.packedGitMmap = false
#
# RESTART REQUIRED
# SINCE 0.8.0
-groovy.scriptsFolder = groovy
+# BASEFOLDER
+groovy.scriptsFolder = ${baseFolder}/groovy
# Specify the directory Grape uses for downloading libraries.
# http://groovy.codehaus.org/Grape
#
# RESTART REQUIRED
# SINCE 1.0.0
-groovy.grapeFolder = groovy/grape
+# BASEFOLDER
+groovy.grapeFolder = ${baseFolder}/groovy/grape
# Scripts to execute on Pre-Receive.
#
@@ -437,7 +455,8 @@ web.allowCookieAuthentication = true
# Config file for storing project metadata
#
# SINCE 1.2.0
-web.projectsFile = projects.conf
+# BASEFOLDER
+web.projectsFile = ${baseFolder}/projects.conf
# Either the full path to a user config file (users.conf)
# OR the full path to a simple user properties file (users.properties)
@@ -451,7 +470,8 @@ web.projectsFile = projects.conf
#
# SINCE 0.5.0
# RESTART REQUIRED
-realm.userService = users.conf
+# BASEFOLDER
+realm.userService = ${baseFolder}/users.conf
# How to store passwords.
# Valid values are plain, md5, or combined-md5. md5 is the hash of password.
@@ -510,7 +530,8 @@ web.enableRpcAdministration = false
# http://googlewebmastercentral.blogspot.com/2008/06/improving-on-robots-exclusion-protocol.html
#
# SINCE 1.0.0
-web.robots.txt =
+# BASEFOLDER
+web.robots.txt = ${baseFolder}/robots.txt
# If true, the web ui layout will respond and adapt to the browser's dimensions.
# if false, the web ui will use a 940px fixed-width layout.
@@ -609,6 +630,7 @@ web.showFederationRegistrations = false
# Specifying "gitblit" uses the internal login message.
#
# SINCE 0.7.0
+# BASEFOLDER
web.loginMessage = gitblit
# This is the message displayed above the repositories table.
@@ -616,6 +638,7 @@ web.loginMessage = gitblit
# Specifying "gitblit" uses the internal welcome message.
#
# SINCE 0.5.0
+# BASEFOLDER
web.repositoriesMessage = gitblit
# Ordered list of charsets/encodings to use when trying to display a blob.
@@ -925,7 +948,8 @@ federation.allowProposals = false
# Use forward slashes even on Windows!!
#
# SINCE 0.6.0
-federation.proposalsFolder = proposals
+# BASEFOLDER
+federation.proposalsFolder = ${baseFolder}/proposals
# The default pull frequency if frequency is unspecified on a registration
#
@@ -1027,7 +1051,8 @@ realm.ldap.password = password
#
# SINCE 1.0.0
# RESTART REQUIRED
-realm.ldap.backingUserService = users.conf
+# BASEFOLDER
+realm.ldap.backingUserService = ${baseFolder}/users.conf
# Delegate team membership control to LDAP.
#
@@ -1123,7 +1148,8 @@ realm.ldap.email = email
# default: users.conf
#
# RESTART REQUIRED
-realm.redmine.backingUserService = users.conf
+# BASEFOLDER
+realm.redmine.backingUserService = ${baseFolder}/users.conf
# URL of the Redmine.
realm.redmine.url = http://example.com/redmine
@@ -1136,7 +1162,8 @@ realm.redmine.url = http://example.com/redmine
#
# SINCE 0.5.0
# RESTART REQUIRED
-server.tempFolder = temp
+# BASEFOLDER
+server.tempFolder = ${baseFolder}/temp
# Use Jetty NIO connectors. If false, Jetty Socket connectors will be used.
#
diff --git a/distrib/groovy/.gitignore b/distrib/groovy/.gitignore
new file mode 100644
index 00000000..e58dc47f
--- /dev/null
+++ b/distrib/groovy/.gitignore
@@ -0,0 +1 @@
+/grape
diff --git a/distrib/groovy/blockpush.groovy b/distrib/groovy/blockpush.groovy
new file mode 100644
index 00000000..caef3306
--- /dev/null
+++ b/distrib/groovy/blockpush.groovy
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2011 gitblit.com.
+ *
+ * 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.
+ */
+import java.text.MessageFormat;
+
+import com.gitblit.GitBlit
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.UserModel
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.slf4j.Logger
+import com.gitblit.utils.ClientLogger
+
+/**
+ * Sample Gitblit Pre-Receive Hook: blockpush
+ *
+ * This script could and perhaps should be further developed to provide
+ * a full repository-branch permissions system similar to gitolite or gitosis.
+ *
+ * The Pre-Receive hook is executed after an incoming push has been parsed,
+ * validated, and objects have been written but BEFORE the refs are updated.
+ * This is the appropriate point to block a push for some reason.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.preReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * If you want this hook script to fail and abort all subsequent scripts in the
+ * chain, "return false" at the appropriate failure points.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * receivePack JGit Receive Pack org.eclipse.jgit.transport.ReceivePack
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+
+// Indicate we have started the script
+logger.info("blockpush hook triggered by ${user.username} for ${repository.name}: checking ${commands.size} commands")
+
+/*
+ * Example rejection of pushes to the master branch of example.git
+ */
+def blocked = false
+switch (repository.name) {
+ case 'ex@mple.git':
+ for (ReceiveCommand command : commands) {
+ def updatedRef = command.refName
+ if (updatedRef.equals('refs/heads/master')) {
+ // to reject a command set it's result to anything other than Result.NOT_ATTEMPTED
+ command.setResult(Result.REJECTED_OTHER_REASON, "You are not permitted to write to ${repository.name}:${updatedRef}")
+ blocked = true
+ }
+ }
+ break
+
+ default:
+ break
+}
+
+if (blocked) {
+ // return false to break the push hook chain
+ return false
+} \ No newline at end of file
diff --git a/distrib/groovy/jenkins.groovy b/distrib/groovy/jenkins.groovy
new file mode 100644
index 00000000..d76a3d66
--- /dev/null
+++ b/distrib/groovy/jenkins.groovy
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2011 gitblit.com.
+ *
+ * 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.
+ */
+import com.gitblit.GitBlit
+import com.gitblit.Keys
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.UserModel
+import com.gitblit.utils.JGitUtils
+import org.eclipse.jgit.lib.Repository
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.slf4j.Logger
+
+/**
+ * Sample Gitblit Post-Receive Hook: jenkins
+ *
+ * The Post-Receive hook is executed AFTER the pushed commits have been applied
+ * to the Git repository. This is the appropriate point to trigger an
+ * integration build or to send a notification.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * receivePack JGit Receive Pack org.eclipse.jgit.transport.ReceivePack
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+// Indicate we have started the script
+logger.info("jenkins hook triggered by ${user.username} for ${repository.name}")
+
+// This script requires Jenkins Git plugin 1.1.14 or later
+// http://kohsuke.org/2011/12/01/polling-must-die-triggering-jenkins-builds-from-a-git-hook/
+
+// define your jenkins url here or set groovy.jenkinsServer in
+// gitblit.properties or web.xml
+def jenkinsUrl = gitblit.getString('groovy.jenkinsServer', 'http://yourserver/jenkins')
+
+// define the trigger url
+def triggerUrl = jenkinsUrl + "/git/notifyCommit?url=$url/git/$repository.name"
+
+// trigger the build
+new URL(triggerUrl).getContent()
diff --git a/distrib/groovy/localclone.groovy b/distrib/groovy/localclone.groovy
new file mode 100644
index 00000000..49b7f8b3
--- /dev/null
+++ b/distrib/groovy/localclone.groovy
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2012 gitblit.com.
+ *
+ * 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.
+ */
+import com.gitblit.GitBlit
+import com.gitblit.Keys
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.TeamModel
+import com.gitblit.models.UserModel
+import com.gitblit.utils.JGitUtils
+import com.gitblit.utils.StringUtils
+import java.text.SimpleDateFormat
+import org.eclipse.jgit.api.CloneCommand
+import org.eclipse.jgit.api.Git
+import org.eclipse.jgit.lib.Repository
+import org.eclipse.jgit.lib.Config
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.eclipse.jgit.util.FileUtils
+import org.slf4j.Logger
+
+/**
+ * Sample Gitblit Post-Receive Hook: localclone
+ *
+ * The Post-Receive hook is executed AFTER the pushed commits have been applied
+ * to the Git repository. This is the appropriate point to trigger an
+ * integration build or to send a notification.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * If you want this hook script to fail and abort all subsequent scripts in the
+ * chain, "return false" at the appropriate failure points.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * receivePack JGit Receive Pack org.eclipse.jgit.transport.ReceivePack
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+
+// Indicate we have started the script
+logger.info("localclone hook triggered by ${user.username} for ${repository.name}")
+
+def rootFolder = 'c:/test'
+def bare = false
+def cloneAllBranches = true
+def cloneBranch = 'refs/heads/master'
+def includeSubmodules = true
+
+def repoName = repository.name
+def destinationFolder = new File(rootFolder, StringUtils.stripDotGit(repoName))
+def srcUrl = 'file://' + new File(GitBlit.getRepositoriesFolder(), repoName).absolutePath
+
+// delete any previous clone
+if (destinationFolder.exists()) {
+ FileUtils.delete(destinationFolder, FileUtils.RECURSIVE)
+}
+
+// clone the repository
+logger.info("cloning ${srcUrl} to ${destinationFolder}")
+CloneCommand cmd = Git.cloneRepository();
+cmd.setBare(bare)
+if (cloneAllBranches)
+ cmd.setCloneAllBranches(true)
+else
+ cmd.setBranch(cloneBranch)
+cmd.setCloneSubmodules(includeSubmodules)
+cmd.setURI(srcUrl)
+cmd.setDirectory(destinationFolder)
+Git git = cmd.call();
+git.repository.close()
+
+// report clone operation success back to pushing Git client
+clientLogger.info("${repoName} cloned to ${destinationFolder}") \ No newline at end of file
diff --git a/distrib/groovy/protect-refs.groovy b/distrib/groovy/protect-refs.groovy
new file mode 100644
index 00000000..b1b611f4
--- /dev/null
+++ b/distrib/groovy/protect-refs.groovy
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2012 Philip L. McMahon.
+ *
+ * Derived from blockpush.groovy, copyright 2011 gitblit.com.
+ *
+ * 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.
+ */
+import com.gitblit.GitBlit
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.UserModel
+
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.slf4j.Logger
+
+/**
+ * Sample Gitblit Pre-Receive Hook: protect-refs
+ *
+ * This script provides basic authorization of receive command types for a list
+ * of known ref patterns. Command types and unmatched ref patterns will be
+ * ignored, meaning this script has an "allow by default" policy.
+ *
+ * This script works best when a repository requires authentication on push, but
+ * can be used to enforce fast-forward commits or prohibit ref deletion by
+ * setting the *authorizedTeams* variable to an empty list and adding a ".+"
+ * entry to the *protectedRefs* list.
+ *
+ * The Pre-Receive hook is executed after an incoming push has been parsed,
+ * validated, and objects have been written but BEFORE the refs are updated.
+ * This is the appropriate point to block a push for some reason.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.preReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * This script may reject one or more commands, but will never return false.
+ * Subsequent scripts, if any, will always be invoked.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * receivePack JGit Receive Pack org.eclipse.jgit.transport.ReceivePack
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+
+// map of protected command types to returned results type
+// commands not included will skip authz check
+def protectedCmds = [
+ UPDATE_NONFASTFORWARD: Result.REJECTED_NONFASTFORWARD,
+ DELETE: Result.REJECTED_NODELETE
+]
+
+// list of regex patterns for protected refs
+def protectedRefs = [
+ "refs/heads/master",
+ "refs/tags/.+"
+]
+
+// teams which are authorized to perform protected commands on protected refs
+def authorizedTeams = [ "admins" ]
+
+for (ReceiveCommand command : commands) {
+ def updateType = command.type
+ def updatedRef = command.refName
+
+ // find first regex which matches updated ref, if any
+ def refPattern = protectedRefs.find { updatedRef.matches ~it }
+
+ // find rejection result for update type, if any
+ def result = protectedCmds[updateType.name()]
+
+ // command requires authz if ref is protected and has a mapped rejection result
+ if (refPattern && result) {
+
+ // verify user is a member of any authorized team
+ def team = authorizedTeams.find { user.isTeamMember it }
+ if (team) {
+ // don't adjust command result
+ logger.info "${user.username} authorized for ${updateType} of protected ref ${repository.name}:${updatedRef} (${command.oldId.name} -> ${command.newId.name})"
+ } else {
+ // mark command result as rejected
+ command.setResult(result, "${user.username} cannot ${updateType} protected ref ${repository.name}:${updatedRef} matching pattern ${refPattern}")
+ }
+ }
+}
diff --git a/distrib/groovy/sendmail-html.groovy b/distrib/groovy/sendmail-html.groovy
new file mode 100644
index 00000000..16920735
--- /dev/null
+++ b/distrib/groovy/sendmail-html.groovy
@@ -0,0 +1,516 @@
+/*
+ * Copyright 2012 gitblit.com.
+ *
+ * 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.
+ */
+import com.gitblit.GitBlit
+import com.gitblit.Keys
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.TeamModel
+import com.gitblit.models.UserModel
+import com.gitblit.utils.JGitUtils
+import java.text.SimpleDateFormat
+
+import org.eclipse.jgit.api.Status;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.diff.RawTextComparator;
+import org.eclipse.jgit.diff.DiffEntry.ChangeType;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.IndexDiff;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository
+import org.eclipse.jgit.lib.Config
+import org.eclipse.jgit.patch.FileHeader;
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.treewalk.EmptyTreeIterator;
+import org.eclipse.jgit.treewalk.CanonicalTreeParser;
+import org.eclipse.jgit.util.io.DisabledOutputStream;
+import org.slf4j.Logger
+import groovy.xml.MarkupBuilder
+
+import java.io.IOException;
+import java.security.MessageDigest
+
+
+/**
+ * Sample Gitblit Post-Receive Hook: sendmail-html
+ *
+ * The Post-Receive hook is executed AFTER the pushed commits have been applied
+ * to the Git repository. This is the appropriate point to trigger an
+ * integration build or to send a notification.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * If you want this hook script to fail and abort all subsequent scripts in the
+ * chain, "return false" at the appropriate failure points.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit java.lang.String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+
+com.gitblit.models.UserModel userModel = user
+
+// Indicate we have started the script
+logger.info("sendmail-html hook triggered by ${user.username} for ${repository.name}")
+
+/*
+ * Primitive email notification.
+ * This requires the mail settings to be properly configured in Gitblit.
+ */
+
+Repository r = gitblit.getRepository(repository.name)
+
+// reuse existing repository config settings, if available
+Config config = r.getConfig()
+def mailinglist = config.getString('hooks', null, 'mailinglist')
+def emailprefix = config.getString('hooks', null, 'emailprefix')
+
+// set default values
+def toAddresses = []
+if (emailprefix == null) {
+ emailprefix = '[Gitblit]'
+}
+
+if (mailinglist != null) {
+ def addrs = mailinglist.split(/(,|\s)/)
+ toAddresses.addAll(addrs)
+}
+
+// add all mailing lists defined in gitblit.properties or web.xml
+toAddresses.addAll(GitBlit.getStrings(Keys.mail.mailingLists))
+
+// add all team mailing lists
+def teams = gitblit.getRepositoryTeams(repository)
+for (team in teams) {
+ TeamModel model = gitblit.getTeamModel(team)
+ if (model.mailingLists) {
+ toAddresses.addAll(model.mailingLists)
+ }
+}
+
+// add all mailing lists for the repository
+toAddresses.addAll(repository.mailingLists)
+
+// define the summary and commit urls
+def repo = repository.name
+def summaryUrl = url + "/summary?r=$repo"
+def baseCommitUrl = url + "/commit?r=$repo&h="
+def baseBlobDiffUrl = url + "/blobdiff/?r=$repo&h="
+def baseCommitDiffUrl = url + "/commitdiff/?r=$repo&h="
+def forwardSlashChar = gitblit.getString(Keys.web.forwardSlashCharacter, '/')
+
+if (gitblit.getBoolean(Keys.web.mountParameters, true)) {
+ repo = repo.replace('/', forwardSlashChar).replace('/', '%2F')
+ summaryUrl = url + "/summary/$repo"
+ baseCommitUrl = url + "/commit/$repo/"
+ baseBlobDiffUrl = url + "/blobdiff/$repo/"
+ baseCommitDiffUrl = url + "/commitdiff/$repo/"
+}
+
+class HtmlMailWriter {
+ Repository repository
+ def url
+ def baseCommitUrl
+ def baseCommitDiffUrl
+ def baseBlobDiffUrl
+ def mountParameters
+ def forwardSlashChar
+ def includeGravatar
+ def shortCommitIdLength
+ def commitCount = 0
+ def commands
+ def writer = new StringWriter();
+ def builder = new MarkupBuilder(writer)
+
+ def writeStyle() {
+ builder.style(type:"text/css", '''
+ .table td {
+ vertical-align: middle;
+ }
+ tr.noborder td {
+ border: none;
+ padding-top: 0px;
+ }
+ .gravatar-column {
+ width: 5%;
+ }
+ .author-column {
+ width: 20%;
+ }
+ .commit-column {
+ width: 5%;
+ }
+ .status-column {
+ width: 10%;
+ }
+ .table-disable-hover.table tbody tr:hover td,
+ .table-disable-hover.table tbody tr:hover th {
+ background-color: inherit;
+ }
+ .table-disable-hover.table-striped tbody tr:nth-child(odd):hover td,
+ .table-disable-hover.table-striped tbody tr:nth-child(odd):hover th {
+ background-color: #f9f9f9;
+ }
+ ''')
+ }
+
+ def writeBranchTitle(type, name, action, number) {
+ builder.div('class' : 'pageTitle') {
+ builder.span('class':'project') {
+ mkp.yield "$type "
+ span('class': 'repository', name )
+ if (number > 0) {
+ mkp.yield " $action ($number commits)"
+ } else {
+ mkp.yield " $action"
+ }
+ }
+ }
+ }
+
+ def writeBranchDeletedTitle(type, name) {
+ builder.div('class' : 'pageTitle', 'style':'color:red') {
+ builder.span('class':'project') {
+ mkp.yield "$type "
+ span('class': 'repository', name )
+ mkp.yield " deleted"
+ }
+ }
+ }
+
+ def commitUrl(RevCommit commit) {
+ "${baseCommitUrl}$commit.id.name"
+ }
+
+ def commitDiffUrl(RevCommit commit) {
+ "${baseCommitDiffUrl}$commit.id.name"
+ }
+
+ def encoded(String path) {
+ path.replace('/', forwardSlashChar).replace('/', '%2F')
+ }
+
+ def blobDiffUrl(objectId, path) {
+ if (mountParameters) {
+ // REST style
+ "${baseBlobDiffUrl}${objectId.name()}/${encoded(path)}"
+ } else {
+ "${baseBlobDiffUrl}${objectId.name()}&f=${path}"
+ }
+
+ }
+
+ def writeCommitTable(commits, includeChangedPaths=true) {
+ // Write commits table
+ builder.table('class':"table table-disable-hover") {
+ thead {
+ tr {
+ th(colspan: includeGravatar ? 2 : 1, "Author")
+ th( "Commit" )
+ th( "Message" )
+ }
+ }
+ tbody() {
+
+ // Write all the commits
+ for (commit in commits) {
+ writeCommit(commit)
+
+ if (includeChangedPaths) {
+ // Write detail on that particular commit
+ tr('class' : 'noborder') {
+ td (colspan: includeGravatar ? 3 : 2)
+ td (colspan:2) { writeStatusTable(commit) }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ def writeCommit(commit) {
+ def abbreviated = repository.newObjectReader().abbreviate(commit.id, shortCommitIdLength).name()
+ def author = commit.authorIdent.name
+ def email = commit.authorIdent.emailAddress
+ def message = commit.shortMessage
+ builder.tr {
+ if (includeGravatar) {
+ td('class':"gravatar-column") {
+ img(src:gravatarUrl(email), 'class':"gravatar")
+ }
+ }
+ td('class':"author-column", author)
+ td('class':"commit-column") {
+ a(href:commitUrl(commit)) {
+ span('class':"label label-info", abbreviated )
+ }
+ }
+ td {
+ mkp.yield message
+ a('class':'link', href:commitDiffUrl(commit), " [commitdiff]" )
+ }
+ }
+ }
+
+ def writeStatusLabel(style, tooltip) {
+ builder.span('class' : style, 'title' : tooltip )
+ }
+
+ def writeAddStatusLine(ObjectId id, FileHeader header) {
+ builder.td('class':'changeType') {
+ writeStatusLabel("addition", "addition")
+ }
+ builder.td {
+ a(href:blobDiffUrl(id, header.newPath), header.newPath)
+ }
+ }
+
+ def writeCopyStatusLine(ObjectId id, FileHeader header) {
+ builder.td('class':'changeType') {
+ writeStatusLabel("rename", "rename")
+ }
+ builder.td() {
+ a(href:blobDiffUrl(id, header.newPath), header.oldPath + " copied to " + header.newPath)
+ }
+ }
+
+ def writeDeleteStatusLine(ObjectId id, FileHeader header) {
+ builder.td('class':'changeType') {
+ writeStatusLabel("deletion", "deletion")
+ }
+ builder.td() {
+ a(href:blobDiffUrl(id, header.oldPath), header.oldPath)
+ }
+ }
+
+ def writeModifyStatusLine(ObjectId id, FileHeader header) {
+ builder.td('class':'changeType') {
+ writeStatusLabel("modification", "modification")
+ }
+ builder.td() {
+ a(href:blobDiffUrl(id, header.oldPath), header.oldPath)
+ }
+ }
+
+ def writeRenameStatusLine(ObjectId id, FileHeader header) {
+ builder.td('class':'changeType') {
+ writeStatusLabel("rename", "rename")
+ }
+ builder.td() {
+ mkp.yield header.oldPath
+ mkp.yieldUnescaped "<b> -&rt; </b>"
+ a(href:blobDiffUrl(id, header.newPath), header.newPath)
+ }
+ }
+
+ def writeStatusLine(ObjectId id, FileHeader header) {
+ builder.tr {
+ switch (header.changeType) {
+ case ChangeType.ADD:
+ writeAddStatusLine(id, header)
+ break;
+ case ChangeType.COPY:
+ writeCopyStatusLine(id, header)
+ break;
+ case ChangeType.DELETE:
+ writeDeleteStatusLine(id, header)
+ break;
+ case ChangeType.MODIFY:
+ writeModifyStatusLine(id, header)
+ break;
+ case ChangeType.RENAME:
+ writeRenameStatusLine(id, header)
+ break;
+ }
+ }
+ }
+
+ def writeStatusTable(RevCommit commit) {
+ DiffFormatter formatter = new DiffFormatter(DisabledOutputStream.INSTANCE)
+ formatter.setRepository(repository)
+ formatter.setDetectRenames(true)
+ formatter.setDiffComparator(RawTextComparator.DEFAULT);
+
+ def diffs
+ RevWalk rw = new RevWalk(repository)
+ if (commit.parentCount > 0) {
+ RevCommit parent = rw.parseCommit(commit.parents[0].id)
+ diffs = formatter.scan(parent.tree, commit.tree)
+ } else {
+ diffs = formatter.scan(new EmptyTreeIterator(),
+ new CanonicalTreeParser(null, rw.objectReader, commit.tree))
+ }
+ rw.dispose()
+ // Write status table
+ builder.table('class':"plain") {
+ tbody() {
+ for (DiffEntry entry in diffs) {
+ FileHeader header = formatter.toFileHeader(entry)
+ writeStatusLine(commit.id, header)
+ }
+ }
+ }
+ }
+
+
+ def md5(text) {
+
+ def digest = MessageDigest.getInstance("MD5")
+
+ //Quick MD5 of text
+ def hash = new BigInteger(1, digest.digest(text.getBytes()))
+ .toString(16)
+ .padLeft(32, "0")
+ hash.toString()
+ }
+
+ def gravatarUrl(email) {
+ def cleaned = email.trim().toLowerCase()
+ "http://www.gravatar.com/avatar/${md5(cleaned)}?s=30"
+ }
+
+ def writeNavbar() {
+ builder.div('class':"navbar navbar-fixed-top") {
+ div('class':"navbar-inner") {
+ div('class':"container") {
+ a('class':"brand", href:"${url}", title:"GitBlit") {
+ img(src:"${url}/gitblt_25_white.png",
+ width:"79",
+ height:"25",
+ 'class':"logo")
+ }
+ }
+ }
+ }
+ }
+
+ def write() {
+ builder.html {
+ head {
+ link(rel:"stylesheet", href:"${url}/bootstrap/css/bootstrap.css")
+ link(rel:"stylesheet", href:"${url}/gitblit.css")
+ link(rel:"stylesheet", href:"${url}/bootstrap/css/bootstrap-responsive.css")
+ writeStyle()
+ }
+ body {
+
+ writeNavbar()
+
+ div('class':"container") {
+
+ for (command in commands) {
+ def ref = command.refName
+ def refType = 'Branch'
+ if (ref.startsWith('refs/heads/')) {
+ ref = command.refName.substring('refs/heads/'.length())
+ } else if (ref.startsWith('refs/tags/')) {
+ ref = command.refName.substring('refs/tags/'.length())
+ refType = 'Tag'
+ }
+
+ switch (command.type) {
+ case ReceiveCommand.Type.CREATE:
+ def commits = JGitUtils.getRevLog(repository, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ if (refType == 'Branch') {
+ // new branch
+ writeBranchTitle(refType, ref, "created", commits.size())
+ writeCommitTable(commits, true)
+ } else {
+ // new tag
+ writeBranchTitle(refType, ref, "created", 0)
+ writeCommitTable(commits, false)
+ }
+ break
+ case ReceiveCommand.Type.UPDATE:
+ def commits = JGitUtils.getRevLog(repository, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ // fast-forward branch commits table
+ // Write header
+ writeBranchTitle(refType, ref, "updated", commits.size())
+ writeCommitTable(commits)
+ break
+ case ReceiveCommand.Type.UPDATE_NONFASTFORWARD:
+ def commits = JGitUtils.getRevLog(repository, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ // non-fast-forward branch commits table
+ // Write header
+ writeBranchTitle(refType, ref, "updated [NON fast-forward]", commits.size())
+ writeCommitTable(commits)
+ break
+ case ReceiveCommand.Type.DELETE:
+ // deleted branch/tag
+ writeBranchDeletedTitle(refType, ref)
+ break
+ default:
+ break
+ }
+ }
+ }
+ }
+ }
+ writer.toString()
+ }
+
+}
+
+def mailWriter = new HtmlMailWriter()
+mailWriter.repository = r
+mailWriter.baseCommitUrl = baseCommitUrl
+mailWriter.baseBlobDiffUrl = baseBlobDiffUrl
+mailWriter.baseCommitDiffUrl = baseCommitDiffUrl
+mailWriter.forwardSlashChar = forwardSlashChar
+mailWriter.commands = commands
+mailWriter.url = url
+mailWriter.mountParameters = GitBlit.getBoolean(Keys.web.mountParameters, true)
+mailWriter.includeGravatar = GitBlit.getBoolean(Keys.web.allowGravatar, true)
+mailWriter.shortCommitIdLength = GitBlit.getInteger(Keys.web.shortCommitIdLength, 8)
+
+def content = mailWriter.write()
+
+// close the repository reference
+r.close()
+
+// tell Gitblit to send the message (Gitblit filters duplicate addresses)
+def repositoryName = repository.name.substring(0, repository.name.length() - 4)
+gitblit.sendHtmlMail("${emailprefix} ${userModel.displayName} pushed ${mailWriter.commitCount} commits => $repositoryName",
+ content,
+ toAddresses)
diff --git a/distrib/groovy/sendmail.groovy b/distrib/groovy/sendmail.groovy
new file mode 100644
index 00000000..c832bc64
--- /dev/null
+++ b/distrib/groovy/sendmail.groovy
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2011 gitblit.com.
+ *
+ * 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.
+ */
+import com.gitblit.GitBlit
+import com.gitblit.Keys
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.TeamModel
+import com.gitblit.models.UserModel
+import com.gitblit.utils.JGitUtils
+import java.text.SimpleDateFormat
+import org.eclipse.jgit.lib.Repository
+import org.eclipse.jgit.lib.Config
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.slf4j.Logger
+
+/**
+ * Sample Gitblit Post-Receive Hook: sendmail
+ *
+ * The Post-Receive hook is executed AFTER the pushed commits have been applied
+ * to the Git repository. This is the appropriate point to trigger an
+ * integration build or to send a notification.
+ *
+ * This script is only executed when pushing to *Gitblit*, not to other Git
+ * tooling you may be using.
+ *
+ * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
+ * or web.xml then it will be executed by any repository when it receives a
+ * push. If you choose to share your script then you may have to consider
+ * tailoring control-flow based on repository access restrictions.
+ *
+ * Scripts may also be specified per-repository in the repository settings page.
+ * Shared scripts will be excluded from this list of available scripts.
+ *
+ * This script is dynamically reloaded and it is executed within it's own
+ * exception handler so it will not crash another script nor crash Gitblit.
+ *
+ * If you want this hook script to fail and abort all subsequent scripts in the
+ * chain, "return false" at the appropriate failure points.
+ *
+ * Bound Variables:
+ * gitblit Gitblit Server com.gitblit.GitBlit
+ * repository Gitblit Repository com.gitblit.models.RepositoryModel
+ * receivePack JGit Receive Pack org.eclipse.jgit.transport.ReceivePack
+ * user Gitblit User com.gitblit.models.UserModel
+ * commands JGit commands Collection<org.eclipse.jgit.transport.ReceiveCommand>
+ * url Base url for Gitblit String
+ * logger Logs messages to Gitblit org.slf4j.Logger
+ * clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger
+ *
+ * Accessing Gitblit Custom Fields:
+ * def myCustomField = repository.customFields.myCustomField
+ *
+ */
+
+// Indicate we have started the script
+logger.info("sendmail hook triggered by ${user.username} for ${repository.name}")
+
+/*
+ * Primitive email notification.
+ * This requires the mail settings to be properly configured in Gitblit.
+ */
+
+Repository r = gitblit.getRepository(repository.name)
+
+// reuse existing repository config settings, if available
+Config config = r.getConfig()
+def mailinglist = config.getString('hooks', null, 'mailinglist')
+def emailprefix = config.getString('hooks', null, 'emailprefix')
+
+// set default values
+def toAddresses = []
+if (emailprefix == null)
+emailprefix = '[Gitblit]'
+
+if (mailinglist != null) {
+ def addrs = mailinglist.split(/(,|\s)/)
+ toAddresses.addAll(addrs)
+}
+
+// add all mailing lists defined in gitblit.properties or web.xml
+toAddresses.addAll(gitblit.getStrings(Keys.mail.mailingLists))
+
+// add all team mailing lists
+def teams = gitblit.getRepositoryTeams(repository)
+for (team in teams) {
+ TeamModel model = gitblit.getTeamModel(team)
+ if (model.mailingLists) {
+ toAddresses.addAll(model.mailingLists)
+ }
+}
+
+// add all mailing lists for the repository
+toAddresses.addAll(repository.mailingLists)
+
+// define the summary and commit urls
+def repo = repository.name
+def summaryUrl
+def commitUrl
+if (gitblit.getBoolean(Keys.web.mountParameters, true)) {
+ repo = repo.replace('/', gitblit.getString(Keys.web.forwardSlashCharacter, '/')).replace('/', '%2F')
+ summaryUrl = url + "/summary/$repo"
+ commitUrl = url + "/commit/$repo/"
+} else {
+ summaryUrl = url + "/summary?r=$repo"
+ commitUrl = url + "/commit?r=$repo&h="
+}
+
+// construct a simple text summary of the changes contained in the push
+def branchBreak = '>---------------------------------------------------------------\n'
+def commitBreak = '\n\n ----\n'
+def commitCount = 0
+def changes = ''
+SimpleDateFormat df = new SimpleDateFormat(gitblit.getString(Keys.web.datetimestampLongFormat, 'EEEE, MMMM d, yyyy h:mm a z'))
+def table = { "\n ${JGitUtils.getDisplayName(it.authorIdent)}\n ${df.format(JGitUtils.getCommitDate(it))}\n\n $it.shortMessage\n\n $commitUrl$it.id.name" }
+for (command in commands) {
+ def ref = command.refName
+ def refType = 'branch'
+ if (ref.startsWith('refs/heads/')) {
+ ref = command.refName.substring('refs/heads/'.length())
+ } else if (ref.startsWith('refs/tags/')) {
+ ref = command.refName.substring('refs/tags/'.length())
+ refType = 'tag'
+ }
+
+ switch (command.type) {
+ case ReceiveCommand.Type.CREATE:
+ def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ // new branch
+ changes += "\n$branchBreak new $refType $ref created ($commits.size commits)\n$branchBreak"
+ changes += commits.collect(table).join(commitBreak)
+ changes += '\n'
+ break
+ case ReceiveCommand.Type.UPDATE:
+ def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ // fast-forward branch commits table
+ changes += "\n$branchBreak $ref $refType updated ($commits.size commits)\n$branchBreak"
+ changes += commits.collect(table).join(commitBreak)
+ changes += '\n'
+ break
+ case ReceiveCommand.Type.UPDATE_NONFASTFORWARD:
+ def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
+ commitCount += commits.size()
+ // non-fast-forward branch commits table
+ changes += "\n$branchBreak $ref $refType updated [NON fast-forward] ($commits.size commits)\n$branchBreak"
+ changes += commits.collect(table).join(commitBreak)
+ changes += '\n'
+ break
+ case ReceiveCommand.Type.DELETE:
+ // deleted branch/tag
+ changes += "\n$branchBreak $ref $refType deleted\n$branchBreak"
+ break
+ default:
+ break
+ }
+}
+// close the repository reference
+r.close()
+
+// tell Gitblit to send the message (Gitblit filters duplicate addresses)
+gitblit.sendMail("$emailprefix $user.username pushed $commitCount commits => $repository.name", "$summaryUrl\n$changes", toAddresses) \ No newline at end of file
diff --git a/distrib/groovy/thebuggenie.groovy b/distrib/groovy/thebuggenie.groovy
new file mode 100644
index 00000000..b4385a26
--- /dev/null
+++ b/distrib/groovy/thebuggenie.groovy
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2011 Wolfgang Gassler gassler.org
+ *
+ * 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.
+ */
+
+import com.gitblit.GitBlit
+import com.gitblit.Keys
+import com.gitblit.models.RepositoryModel
+import com.gitblit.models.TeamModel
+import com.gitblit.models.UserModel
+import com.gitblit.utils.JGitUtils
+import java.text.SimpleDateFormat
+import org.eclipse.jgit.lib.Repository
+import org.eclipse.jgit.lib.Config
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.transport.ReceiveCommand
+import org.eclipse.jgit.transport.ReceiveCommand.Result
+import org.slf4j.Logger
+import org.eclipse.jgit.lib.IndexDiff
+import org.eclipse.jgit.lib.Constants
+import com.gitblit.utils.DiffUtils
+
+/**
+ * Gitblit Post-Receive Hook: thebuggenie
+ * www.thebuggenie.com
+ *
+ * Submit the commit information to thebuggenie bug tracker by calling thebuggenie client tool
+ *
+ * Config of the Script:
+ *
+ * Setup a custom gitblit field in the proprties file of gitblit by adding the following line
+ * groovy.customFields = "thebuggenieProjectId=TheBugGennie project id (used for thebuggenie hoocks)"
+ * This field allows to specify the project id of thebuggenie project in the edit section of gitblit
+ *
+ * Furthermore you need to set the path to thebuggenie client tool by adding the following property to
+ * the gitblit properties file
+ * thebuggenie.tbg_cli = /var/www/thebuggenie_root/tbg_cli
+ */
+
+// Indicate we have started the script
+logger.info("thebuggenie hook triggered by ${user.username} for ${repository.name}")
+
+//fetch the repository data
+Repository r = gitblit.getRepository(repository.name)
+
+//get project id which is defined in the git repo metadata
+def tbgProjectId = repository.customFields.thebuggenieProjectId
+//get path to the thebuggenie client tool which is defined in the gitblit proprties files
+def tbgCliPath = gitblit.getString('thebuggenie.tbg_cli', '/var/www/thebuggenie/tbg_cli')
+def tbgCliDirPath = new File(tbgCliPath).getParent()
+
+for(command in commands) {
+ //fetch all pushed commits
+ def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
+ for (commit in commits) {
+ //get hashes and author data of commit
+ def oldhash = commit.getParent(0).getId().getName()
+ def newhash = commit.getId().getName()
+ def authorIdent = commit.getAuthorIdent()
+ def author = "${authorIdent.name} <${authorIdent.emailAddress}>"
+ //fetch all changed files of the commit
+ def files = JGitUtils.getFilesInCommit(r,commit)
+ def changedFiles = ""
+ for (f in files) {
+ //transform file data to the format which is needed by thebuggenie
+ changedFiles += f.changeType.toString().substring(0,1)+"\t${f.path}\n"
+ }
+ //ok let's submit all information to thebuggenie by calling the client tool
+// def shc = "$tbgCliPath vcs_integration:report_commit $tbgProjectId \"$author\" $newhash \"${commit.fullMessage}\" \"$changedFiles\" $oldhash ${commit.commitTime}"
+ def shc = [tbgCliPath, "vcs_integration:report_commit", tbgProjectId, author, newhash, commit.getFullMessage(), changedFiles, oldhash, commit.getCommitTime()];
+ logger.info("executing in path " + tbgCliDirPath + ": "+shc)
+ shc.execute(null, new File(tbgCliDirPath))
+ }
+}
+
+// close the repository reference
+r.close()
diff --git a/distrib/installService.cmd b/distrib/installService.cmd
index 77b641e8..d254d679 100644
--- a/distrib/installService.cmd
+++ b/distrib/installService.cmd
@@ -25,12 +25,12 @@ SET ARCH=amd64
--StartPath="%CD%" ^
--StartClass=com.gitblit.Launcher ^
--StartMethod=main ^
- --StartParams="--storePassword;gitblit" ^
+ --StartParams="--storePassword;gitblit;--baseFolder;%CD%\data" ^
--StartMode=jvm ^
--StopPath="%CD%" ^
--StopClass=com.gitblit.Launcher ^
--StopMethod=main ^
- --StopParams="--stop" ^
+ --StopParams="--stop;--baseFolder;%CD%\data" ^
--StopMode=jvm ^
--Classpath="%CD%\gitblit.jar" ^
--Jvm=auto ^
diff --git a/distrib/projects.conf b/distrib/projects.conf
new file mode 100644
index 00000000..d43f4829
--- /dev/null
+++ b/distrib/projects.conf
@@ -0,0 +1,3 @@
+[project "main"]
+ title = Main Repositories
+ description = main group of repositories \ No newline at end of file