Created
February 13, 2012 23:13
-
-
Save frimik/1821358 to your computer and use it in GitHub Desktop.
git post-receive IRC notification
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# IRC notification post-receive hook. | |
# Based on https://wiki.icinga.org/display/community/GIT+Commit+Bot | |
# | |
# Author: Mikael Fridh <[email protected]> | |
# | |
# This script pulls out the commit information and sends it to | |
# the Notify plugin in supybot via localhost 5050. | |
# | |
# FIXME read host and port from git config | |
# | |
# Settings needed: | |
# git config hooks.irc.channel "#channel1 #channel2" | |
# git config hooks.irc.prefix "[repoprefix]" | |
# | |
# Optional settings: | |
# git config hooks.gitweb.baseurl "http://git.example.com/gitweb/?p=" | |
# This option should contain everything prior to the repo name which will be | |
# appended. | |
# | |
# How I use it to do multiple notification hooks: | |
# | |
# in post-receive: | |
# FILE=$(mktemp) | |
# cat - > $FILE | |
# | |
# HOOKPATH=$(dirname $0) | |
# | |
# cat $FILE | ${HOOKPATH}/post-receive.email | |
# cat $FILE | ${HOOKPATH}/post-receive.irc | |
# | |
# rm $FILE | |
# | |
max=5 | |
function notify () | |
{ | |
oldrev=$(git rev-parse $1) | |
newrev=$(git rev-parse $2) | |
refname="$3" | |
# --- Interpret | |
# 0000->1234 (create) | |
# 1234->2345 (update) | |
# 2345->0000 (delete) | |
if expr "$oldrev" : '0*$' >/dev/null | |
then | |
change_type="create" | |
else | |
if expr "$newrev" : '0*$' >/dev/null | |
then | |
change_type="delete" | |
else | |
change_type="update" | |
fi | |
fi | |
# --- Get the revision types | |
newrev_type=$(git cat-file -t $newrev 2> /dev/null) | |
oldrev_type=$(git cat-file -t "$oldrev" 2> /dev/null) | |
case "$change_type" in | |
create|update) | |
rev="$newrev" | |
rev_type="$newrev_type" | |
;; | |
delete) | |
rev="$oldrev" | |
rev_type="$oldrev_type" | |
;; | |
esac | |
# The revision type tells us what type the commit is, combined with | |
# the location of the ref we can decide between | |
# - working branch | |
# - tracking branch | |
# - unannoted tag | |
# - annotated tag | |
case "$refname","$rev_type" in | |
refs/tags/*,commit) | |
# un-annotated tag | |
refname_type="tag" | |
short_refname=${refname##refs/tags/} | |
;; | |
refs/tags/*,tag) | |
# annotated tag | |
refname_type="annotated tag" | |
short_refname=${refname##refs/tags/} | |
# change recipients | |
if [ -n "$announcerecipients" ]; then | |
recipients="$announcerecipients" | |
fi | |
;; | |
refs/heads/*,commit) | |
# branch | |
refname_type="branch" | |
short_refname=${refname##refs/heads/} | |
;; | |
refs/remotes/*,commit) | |
# tracking branch | |
refname_type="tracking branch" | |
short_refname=${refname##refs/remotes/} | |
echo >&2 "*** Push-update of tracking branch, $refname" | |
echo >&2 "*** - no notification generated." | |
return 0 | |
;; | |
*) | |
# Anything else (is there anything else?) | |
echo >&2 "*** Unknown type of update to $refname ($rev_type)" | |
echo >&2 "*** - no notification generated" | |
return 0 | |
;; | |
esac | |
channels=$(git config hooks.irc.channel) | |
# plural suffix, default "", changed to "s" if commits > 1 | |
s="" | |
# Repo name, either Gitolite or normal repo. | |
if [ -n "$GL_REPO" ]; then | |
# it's a gitolite repo | |
repodir=$(basename `pwd`) | |
repo=$GL_REPO | |
else | |
repodir=$(basename `pwd`) | |
repo=${repodir%.git} | |
fi | |
gitweb_baseurl=$(git config hooks.gitweb.baseurl) | |
if [ -z "$gitweb_baseurl" ]; then | |
# if there is no value for gitweb_baseurl, fall back to some Marin | |
# default values | |
if [ -n "$GL_REPO" ]; then | |
# gitolite repo, add special gitolite/ prefix (Marin hardcoded until we | |
# move everything to gitolite hosting) | |
gitweb_baseurl="http://git.example.com/gitweb-beta/?p=gitolite/" | |
else | |
# non-gitolite repo, no special prefix | |
gitweb_baseurl="http://git.example.com/gitweb-beta/?p=" | |
fi | |
fi | |
# otherwise, assume git config value is good: | |
url="${gitweb_baseurl}${repodir};a=commit;h=" | |
head="${gitweb_baseurl}${repodir};a=shortlog;h=${3}" | |
repoprefix=$(git config hooks.irc.prefix || git config hooks.emailprefix || echo "[$repo]") | |
# Get the user information | |
# If $GL_USER is set we're running under gitolite. | |
if [ -n "$GL_USER" ]; then | |
user=$GL_USER | |
else | |
user=$USER | |
fi | |
case ${change_type} in | |
"create") | |
header="${repoprefix} $user ${change_type}d the $refname_type $short_refname: ${head}." | |
;; | |
"delete") | |
header="${repoprefix} $user ${change_type}d the $refname_type $short_refname." | |
;; | |
"update") | |
num=$(git log --pretty=oneline ${1}..${2}|wc -l) | |
branch=${3/refs\/heads\//} | |
if [ ${num} -gt 1 ]; then | |
s="s" | |
fi | |
header="${repoprefix} $user pushed ${num} new commit${s} to ${branch}: ${head}" | |
;; | |
*) | |
# most weird ... this should never happen | |
echo >&2 "*** Unknown type of update to $refname ($rev_type)" | |
echo >&2 "*** - notifications will probably screw up." | |
;; | |
esac | |
# Run once for each channel in the notify list: | |
for chan in $channels | |
do | |
echo "${chan} ${header}" | nc -w 1 localhost 5050 | |
if [ "${change_type}" == "update" ]; then | |
if [ ${num} -lt ${max} ]; then | |
git log --pretty=format:"${chan} %h by %an: %s" ${1}..${2} | nc -w 1 localhost 5050 | |
fi | |
fi | |
done | |
} | |
# MAIN PROGRAM | |
# Read all refs from stdin, notify for each | |
while read line; do | |
set -- $line | |
notify $* | |
RET=$? | |
done | |
exit $RET |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Are there any licensing terms associated with this file? Assuming you are the original author, would you allow it or derivatives of it to be included in a GPL-licensed repo ?
edit: I see the disclaimer above points to GIT-Bot, which is licensed under BSD3. I believe your code would qualify as a significant contribution to the original (which is a 10 line script).