blob: 88571fe7ed49ee44c112c64cbdf5e8ddd773b972 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<!-- Begin Header -->
<title>Gitblit</title>
<meta charset="utf-8">
<meta name="ROBOTS" content="INDEX">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./bootstrap/css/bootstrap.css">
<link rel='shortcut icon' type='image/png' href='./gitblt-favicon.png' />
<link rel="stylesheet" href="./prettify/prettify.css" />
<!-- Google Plus Profile Page -->
<link rel="publisher" href="https://plus.google.com/114464678392593421684" />
<style type="text/css"> a.gpluspage { margin-top:3px;text-decoration: none; } </style>
<!-- Google Plus One -->
<link rel="canonical" href="http://gitblit.com" />
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
<style type="text/css"> div.gplusone { margin-top:12px; } </style>
<script src="./prettify/prettify.js"></script>
<script src="./bootstrap/js/jquery.js"></script>
<script src="./bootstrap/js/bootstrap.min.js"></script>
</head>
<body onload='prettyPrint()'> <!-- Navigation Bar -->
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="./"><img src="./gitblt_25_white.png" alt="Gitblit"></img></a>
<div class="nav-collapse">
<ul class="nav">
<li class='dropdown'> <!-- Menu -->
<a class='dropdown-toggle' href='#' data-toggle='dropdown'>about<b class='caret'></b></a>
<ul class='dropdown-menu'>
<li><a href='index.html'>overview</a></li>
<li><a href='features.html'>features</a></li>
<li><a href='screenshots.html'>screenshots</a></li>
</ul></li> <!-- End Menu -->
<li class='dropdown'> <!-- Menu -->
<a class='dropdown-toggle' href='#' data-toggle='dropdown'>documentation<b class='caret'></b></a>
<ul class='dropdown-menu'>
<li class='dropdown-submenu'> <!-- Submenu -->
<a tabindex='-1' href='#'>Gitblit GO</a>
<ul class='dropdown-menu'>
<li><a href='setup_go.html'>setup GO</a></li>
<li><a href='upgrade_go.html'>upgrade GO</a></li>
</ul></li> <!-- End Submenu -->
<li class='divider'></li>
<li class='dropdown-submenu'> <!-- Submenu -->
<a tabindex='-1' href='#'>Gitblit WAR</a>
<ul class='dropdown-menu'>
<li><a href='setup_war.html'>setup WAR</a></li>
<li><a href='upgrade_war.html'>upgrade WAR</a></li>
</ul></li> <!-- End Submenu -->
<li class='divider'></li>
<li class='dropdown-submenu'> <!-- Submenu -->
<a tabindex='-1' href='#'>Server Configuration</a>
<ul class='dropdown-menu'>
<li><a href='administration.html'>administration</a></li>
<li><a href='setup_authentication.html'>authentication</a></li>
<li><a href='setup_hooks.html'>push hooks</a></li>
<li><a href='setup_lucene.html'>lucene indexing</a></li>
<li><a href='setup_proxy.html'>reverse proxies</a></li>
<li><a href='setup_clientmenus.html'>client app menus</a></li>
<li><a href='setup_bugtraq.html'>bugtraq</a></li>
<li><a href='setup_mirrors.html'>mirrors</a></li>
<li><a href='setup_scaling.html'>scaling</a></li>
<li><a href='setup_fail2ban.html'>fail2ban</a></li>
<li><a href='setup_filestore.html'>filestore (Git LFS)</a></li>
<li class='divider'></li>
<li><a href='setup_viewer.html'>Gitblit as a viewer</a></li>
</ul></li> <!-- End Submenu -->
<li class='divider'></li>
<li class='dropdown-submenu'> <!-- Submenu -->
<a tabindex='-1' href='#'>Client Usage</a>
<ul class='dropdown-menu'>
<li><a href='setup_transport_http.html'>using HTTP/HTTPS</a></li>
<li><a href='setup_transport_ssh.html'>using SSH</a></li>
<li><a href='eclipse_plugin.html'>using the Eclipse plugin</a></li>
</ul></li> <!-- End Submenu -->
<li class='divider'></li>
<li class='dropdown-submenu'> <!-- Submenu -->
<a tabindex='-1' href='#'>Tickets</a>
<ul class='dropdown-menu'>
<li><a href='tickets_overview.html'>overview</a></li>
<li><a href='tickets_using.html'>using</a></li>
<li><a href='tickets_barnum.html'>barnum</a></li>
<li><a href='tickets_setup.html'>setup</a></li>
<li><a href='tickets_replication.html'>replication & advanced administration</a></li>
</ul></li> <!-- End Submenu -->
<li class='divider'></li>
<li class='dropdown-submenu'> <!-- Submenu -->
<a tabindex='-1' href='#'>Plugins</a>
<ul class='dropdown-menu'>
<li><a href='plugins_overview.html'>overview</a></li>
<li><a href='plugins_extensions.html'>extension points</a></li>
</ul></li> <!-- End Submenu -->
<li class='divider'></li>
<li><a href='federation.html'>federation</a></li>
<li class='divider'></li>
<li><a href='properties.html'>settings</a></li>
<li><a href='faq.html'>faq</a></li>
<li class='divider'></li>
<li><a href='design.html'>design</a></li>
<li><a href='rpc.html'>rpc</a></li>
</ul></li> <!-- End Menu -->
<li class='dropdown'> <!-- Menu -->
<a class='dropdown-toggle' href='#' data-toggle='dropdown'>releases<b class='caret'></b></a>
<ul class='dropdown-menu'>
<li><a href='releasenotes.html'>release notes</a></li>
<li><a href='releases.html'>release history</a></li>
</ul></li> <!-- End Menu -->
<li class='dropdown'> <!-- Menu -->
<a class='dropdown-toggle' href='#' data-toggle='dropdown'>downloads<b class='caret'></b></a>
<ul class='dropdown-menu'>
<li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.8.0.zip'>Gitblit GO (Windows)</a></li>
<li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.8.0.tar.gz'>Gitblit GO (Linux/OSX)</a></li>
<li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.8.0.war'>Gitblit WAR</a></li>
<li class='divider'></li>
<li><a href='https://registry.hub.docker.com/u/jmoger/gitblit/'>Gitblit GO (Docker)</a></li>
<li class='divider'></li>
<li><a href='http://plugins.gitblit.com'>Plugins Registry</a></li>
<li class='divider'></li>
<li><a href='http://dl.bintray.com/gitblit/releases/manager-1.8.0.zip'>Gitblit Manager</a></li>
<li><a href='http://dl.bintray.com/gitblit/releases/fedclient-1.8.0.zip'>Federation Client</a></li>
<li class='divider'></li>
<li><a href='http://dl.bintray.com/gitblit/releases/gbapi-1.8.0.zip'>API Library</a></li>
<li class='divider'></li>
<li><a href='https://bintray.com/gitblit/releases/gitblit'>Bintray (1.4.0+)</a></li>
<li><a href='https://code.google.com/p/gitblit/downloads/list?can=1'>GoogleCode (pre-1.4.0)</a></li>
<li class='divider'></li>
<li><a href='http://gitblit.github.io/gitblit-maven'>Maven Repository</a></li>
</ul></li> <!-- End Menu -->
<li class='dropdown'> <!-- Menu -->
<a class='dropdown-toggle' href='#' data-toggle='dropdown'>links<b class='caret'></b></a>
<ul class='dropdown-menu'>
<li><a href='https://dev.gitblit.com'>dev.gitblit.com (self-hosted)</a></li>
<li class='divider'></li>
<li><a href='http://plugins.gitblit.com'>Plugins Registry</a></li>
<li class='divider'></li>
<li><a href='https://github.com/gitblit/gitblit'>Github</a></li>
<li><a href='https://github.com/gitblit/gitblit'>Issues</a></li>
<li><a href='http://groups.google.com/group/gitblit'>Discussion</a></li>
<li><a href='https://twitter.com/gitblit'>Twitter</a></li>
<li><a href='http://www.ohloh.net/p/gitblit'>Ohloh</a></li>
<li class='divider'></li>
<li><a href='https://vimeo.com/86164723'>Gitblit Tickets screencast</a></li>
<li><a href='https://asciinema.org/a/9342'>Gitblit SSH and Plugin Management asciicast</a></li>
<li><a href='http://episodes.gitminutes.com/2014/05/gitminutes-29-james-moger-on-gitblit.html'>GitMinutes #29: James Moger on Gitblit</a></li>
<li class='divider'></li>
<li><a href='https://twitter.com/JamesMoger'>@JamesMoger</a></li>
</ul></li> <!-- End Menu -->
<li class='divider-vertical'></li>
<li><a href='https://plus.google.com/114464678392593421684?prsrc=3' class='gpluspage'><img src='https://ssl.gstatic.com/images/icons/gplus-16.png' width='16' height='16 style='order: 0;'/></a></li><li><div class='gplusone'><g:plusone size='small' href='http://gitblit.com'></g:plusone></div></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div><!-- end Navigation Bar -->
<div class='container'>
<!-- Begin Markdown -->
<h2 class="section" id='H1'><a href="#H1" class="sectionlink"><i class="icon-share-alt"> </i></a>Groovy Hook Scripts</h2><p>Gitblit uses Groovy for its push hook mechanism. This mechanism only executes when pushing to Gitblit, not when pushing to some other Git tooling in your stack.</p><p>The Groovy hook mechanism allows for dynamic extension of Gitblit to execute custom tasks on receiving and processing push events. The scripts run within the context of your Gitblit instance and therefore have access to Gitblit's internals at runtime.</p>
<h3 class="section" id='H2'><a href="#H2" class="sectionlink"><i class="icon-share-alt"> </i></a>Rules, Requirements, & Behaviors</h3>
<ol>
<li>Your Groovy scripts must be stored in the <em>groovy.scriptsFolder</em> as specified in <code>gitblit.properties</code> or <code>web.xml</code>.</li>
<li>All script files must have the <em>.groovy</em> extension. Because of this you may omit the extension when specifying the script.</li>
<li>Script filenames must not have spaces!</li>
<li>Scripts must be explicitly specified to be executed, no scripts are <em>automatically</em> executed by name or extension.</li>
<li>A script can be specified to run on <em>all repositories</em> by adding the script file name to <em>groovy.preReceiveScripts</em> or <em>groovy.postReceiveScripts</em> in <code>gitblit.properties</code> or <code>web.xml</code>.</li>
<li>Scripts can be specified for a team.</li>
<li>Scripts may also be specified per-repository in the repository's settings.</li>
<li>Globally-specified scripts and team-specified scripts are excluded from the list of available scripts in a repository's settings</li>
<li>Globally-specified scripts are executed first, in their listed order; followed by team-specified scripts in their listed order by alphabetical team order; followed by per-repository scripts, in their listed order.</li>
<li>A script may only be defined once in a pre-receive chain and once in a post-receive chain.<br/>You may execute the same script on pre-receive and post-receive, just not multiple times within a pre-receive or post-receive event.</li>
<li>Gitblit does not differentiate between what can be a pre-receive script and what can be a post-receive script.</li>
<li>If a script <em>returns false</em> then the hook chain is aborted and none of the subsequent scripts will execute.</li>
</ol><p>Some sample scripts are included in the GO and WAR distributions to show you how you can tap into Gitblit with the provided bound variables. Additional implementation details may be specified in the header comment of these examples.</p><p>Hook contributions and improvements are welcome.</p>
<h3 class="section" id='H3'><a href="#H3" class="sectionlink"><i class="icon-share-alt"> </i></a>Grapes</h3><p><em>SINCE 1.0.0</em></p><p><a href="http://groovy.codehaus.org/Grape">Grape</a> lets you quickly add maven repository dependencies to your Groovy hook script. </p>
<blockquote>Grape (The Groovy Adaptable Packaging Engine or Groovy Advanced Packaging Engine) is the infrastructure enabling the grab() calls in Groovy, a set of classes leveraging <a href="http://ant.apache.org/ivy">Ivy</a> to allow for a repository driven module system for Groovy. This allows a developer to write a script with an essentially arbitrary library requirement, and ship just the script. Grape will, at runtime, download as needed and link the named libraries and all dependencies forming a transitive closure when the script is run from existing repositories such as Ibiblio, Codehaus, and java.net.</blockquote><p><pre>// create and use a primitive array
import org.apache.commons.collections.primitives.ArrayIntList
@Grab(group='commons-primitives', module='commons-primitives', version='1.0')
def createEmptyInts() { new ArrayIntList() }
def ints = createEmptyInts()
ints.add(0, 42)
assert ints.size() == 1
assert ints.get(0) == 42
</pre></p>
<h3 class="section" id='H4'><a href="#H4" class="sectionlink"><i class="icon-share-alt"> </i></a>Custom Fields</h3><p><em>SINCE 1.0.0</em></p><p>Gitblit allows custom repository string fields to be defined in <code>gitblit.properties</code> or <code>web.xml</code>. Entry textfields are automatically created for these fields in the Edit Repository page of Gitblit and the Edit Repository dialog of the Gitblit Manager. These fields are accessible from your Groovy hook scripts as</p>
<pre><code>repository.customFields.myField
</code></pre><p>This feature allows you to customize the behavior of your hook scripts without hard-coding values in the hook scripts themselves.</p>
<h3 class="section" id='H5'><a href="#H5" class="sectionlink"><i class="icon-share-alt"> </i></a>Pre-Receive</h3><p>Pre-Receive scripts execute after the pushed objects have all been written to the Git repository but before the refs have been updated to point to these new objects.</p><p>This is the appropriate point to block a push and is how many Git tools implement branch-write permissions.</p>
<h3 class="section" id='H6'><a href="#H6" class="sectionlink"><i class="icon-share-alt"> </i></a>Post-Receive</h3><p>Post-Receive scripts execute after all refs have been updated.</p><p>This is the appropriate point to trigger continuous integration builds or send email notifications, etc.</p>
<h2 class="section" id='H7'><a href="#H7" class="sectionlink"><i class="icon-share-alt"> </i></a>Push Email Notifications</h2><p>Gitblit implements email notifications in <em>sendmail.groovy</em> which uses the Groovy Hook Script mechanism. This allows for dynamic customization of the notification process at the installation site and serves as an example push script.</p>
<h3 class="section" id='H8'><a href="#H8" class="sectionlink"><i class="icon-share-alt"> </i></a>Enabling Push Notifications</h3><p>In order to send email notifications on a push to Gitblit, this script must be specified somewhere in the <em>post-receive</em> script chain.<br/>You may specify <em>sendmail</em> in one of three places:</p>
<ol>
<li><em>groovy.postReceiveScripts</em> in <code>gitblit.properties</code> or <code>web.xml</code>, globally applied to all repositories</li>
<li>post-receive scripts of a Team definition</li>
<li>post-receive scripts of a Repository definition</li>
</ol>
<h3 class="section" id='H9'><a href="#H9" class="sectionlink"><i class="icon-share-alt"> </i></a>Destination Addresses</h3><p>Gitblit does not currently support individual subscriptions to repositories; i.e. a <em>user</em> can not subscribe or unsubscribe from push notifications.</p><p>However, Repository Managers and Administrators can specify subscribed email addresses in one of three places:</p>
<ol>
<li><em>mail.mailingLists</em> in <code>gitblit.properties</code> or <code>web.xml</code>, globally applied to all push-notified repositories</li>
<li>mailing lists in a Team definition, applied to all repositories that are part of the team definition</li>
<li>mailing lists in a Repository definition</li>
</ol><p>All three sources are checked and merged into a unique list of destination addresses for push notifications.</p><p><strong>NOTE:</strong><br/>Care should be taken when devising your notification scheme as it relates to any VIEW restricted repositories you might have. Setting a global mailing list and activating push notifications for a VIEW restricted repository may send unwanted emails.
<!-- End Markdown -->
<div ><ul class="pager"><li class="previous"><a href="setup_authentication.html">&larr; authentication</a></li> <li class="next"><a href="setup_lucene.html">lucene indexing &rarr;</a></li></ul></div><footer class="footer"><p class="pull-right">generated 2016-06-22</p>
<p>The content of this page is licensed under the <a href="http://creativecommons.org/licenses/by/3.0">Creative Commons Attribution 3.0 License</a>.</p>
</footer>
</div>
<!-- Google Analytics -->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-24377072-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>