Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christophercurrie/1591079 to your computer and use it in GitHub Desktop.
Save christophercurrie/1591079 to your computer and use it in GitHub Desktop.
gitolite update hooks to reject CRLF line endings and require formatted commit messages
#!/bin/bash
#
# see https://github.com/kahseng/redmine_gitolite_hook/blob/master/README.rdoc
#
# The "post-receive" script is run after receive-pack has accepted a pack
# and the repository has been updated. It is passed arguments in through
# stdin in the form
# <oldrev> <newrev> <refname>
# For example:
# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
REDMINE_SERVER=https://www.example.com/redmine
FETCH_URL=sys/fetch_changesets
APIKEY=YOUR_REDMINE_WS_API_KEY
# Project identifier defaults to repo name, but can be mapped
PROJECT="$GL_REPO"
MAP=( "foo:foo2"
"bar:baz" )
# Above can be overridden in ~/.redmine file
if [ -f ~/.redmine ]; then
. ~/.redmine
fi
for repomap in ${MAP[@]}; do
REPO=${repomap%%:*}
_PROJECT=${repomap#*:}
if [ "$GL_REPO" = "$REPO" ]; then
PROJECT="$_PROJECT"
break
fi
done
curl -s "$REDMINE_SERVER/$FETCH_URL?id=$PROJECT&key=$APIKEY" > /dev/null
#!/bin/bash
$GL_BINDIR/hooks/update-reject-crlf $@ || exit 1
$GL_BINDIR/hooks/update-require-issue $@ || exit 1
exit 0
#!/bin/bash
#
# An "update" hook which rejects any update containing CRLF.
#
# Author: Gerhard Gappmeier, ascolab GmbH
# Author: Colin Mollenhour
#
# This script is based on the update.sample in git/contrib/hooks.
# You are free to use this script for whatever you want.
#
BINARY_REGEX='\.(pdb|dll|exe|png|gif|jpg|mwb|zip|tgz|gz|bz2|7z|rar|swf|fla|jar|mo)$'
OVERRIDE_REGEX='Contains CRLF'
refname="$1"
oldrev="$2"
newrev="$3"
[ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ] && \
{ echo "Usage: $0 <ref> <oldrev> <newrev>" >&2; exit 1; }
# Skip checks on branch creations
[ "$oldrev" = "0000000000000000000000000000000000000000" ] && exit 0
# Skip checks on branch deletions
[ "$newrev" = "0000000000000000000000000000000000000000" ] && exit 0
# skip when commit mesage contains override
MESSAGE=$(git show -s --format=format:"%s" $newrev)
[[ $MESSAGE =~ $OVERRIDE_REGEX ]] && exit 0
ERRORS=""
ret=0
while read old_mode new_mode old_sha1 new_sha1 status name
do
# skip lines showing parent commit
test -z "$new_sha1" && continue
# skip deletions
[ "$new_sha1" = "0000000000000000000000000000000000000000" ] && continue
# don't do a CRLF check for binary files
[[ $name =~ $BINARY_REGEX ]] && continue
# check for CRLF
CR=$(printf "\r")
if git cat-file blob $new_sha1 | grep -Eq "$CR$"; then
ERRORS="${ERRORS}CRLF DETECTED: $name\n"
ret=1
fi
done < <(git diff-tree -r "$oldrev" "$newrev")
if [ "$ret" = "1" ]; then
echo "###################################################################"
echo "# One or more files contained CRLF (Windows) line endings which are"
echo "# not allowed. Activate the autocrlf feature and/or change the line"
echo "# endings to LF before committing and before trying to push. You "
echo "# will have to amend your existing commits to not contain CRLF. "
echo "# \"git config core.autocrlf true\" to activate CRLF conversion."
echo "# \"git commit --amend\" to change your most recent commit."
echo "# \"git rebase -i ${oldrev:0:7}\" to change all commits."
echo "###################################################################"
echo -e "$ERRORS"
fi
exit $ret
#!/bin/bash
#
# An "update" hook which rejects any update with poor commit messages.
#
# Author: Colin Mollenhour
#
ISSUE_REGEX='\s*(refs|references|ticket|issue|feature|bug|task|fixes|closes|fixed) \#([0-9]+)[.:,]?\s*'
NO_ISSUE_REGEX='noref'
NO_ISSUE_GL_USER_REGEX='^(www-data)$'
NO_ISSUE_AUTHOR_EMAIL_REGEX='^(colin@mollenhour\.com|paul@example\.com)$'
MYSQL='mysql'
# Add authentication or put authentication in ~/.my.cnf
#MYSQL="$MYSQL -u redmine -pPASSWORD"
refname="$1"
oldrev="$2"
newrev="$3"
#echo "DEBUG - refname: $1, oldrev: $2, newrev: $3"
sep="---------------------------------------------"
function die { echo -e "$1" 1>&2; exit 1; }
[ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ] && \
die "Usage: $0 <ref> <oldrev> <newrev>"
[ -z "$GL_USER" ] && \
die "Gitolite user is not defined."
# Skip checks on branch deletions
[ "$newrev" = "0000000000000000000000000000000000000000" ] && exit 0
function reject {
die "
Your commit message was rejected for the following reason:
$1
$sep
$SHORT: $MESSAGE
$sep
HINT: Use 'git commit --amend' to modify your last commit or 'git rebase -i ${oldrev:0:7}' to modify all commits.
"
}
function checkMessage {
REF=$1
SHORT=${REF:0:7}
MESSAGE=$(git show -s --format=format:"%s%+b" $REF | tr '\n' ' ')
AUTHOR_EMAIL=$(git show -s --format=format:"%ae" $REF)
shopt -s nocasematch
# Make sure the author email is populated
[ -z $AUTHOR_EMAIL ] && \
reject "You must configure your name and email address."
# Make sure that the log message contains some text.
[[ $MESSAGE =~ [a-zA-Z0-9]+ ]] || \
reject "You must supply a descriptive commit message."
# Allow an issue reference to be omitted if "noref" is added to message
if [[ $MESSAGE =~ $NO_ISSUE_REGEX ]]; then
[ -z $NO_ISSUE_GL_USER_REGEX ] && [ -z $NO_ISSUE_AUTHOR_EMAIL_REGEX ] && \
return
[ -n $NO_ISSUE_GL_USER_REGEX ] && [[ $GL_USER =~ $NO_ISSUE_GL_USER_REGEX ]] && \
return
[ -n $NO_ISSUE_AUTHOR_EMAIL_REGEX ] && [[ $AUTHOR_EMAIL =~ $NO_ISSUE_AUTHOR_EMAIL_REGEX ]] && \
return
fi
# Skip merge commits
NUMPARENTS=$(git cat-file -p $REF | grep '^parent ' | wc -l)
[ $NUMPARENTS -gt 1 ] && \
return
# Make sure that the log message references a Redmine issue.
[[ $MESSAGE =~ $ISSUE_REGEX ]] || \
reject "You must specify a Redmine issue number matching the following pattern:\n$ISSUE_REGEX\nExample: Issue #123, Refs #123, Fixes #123"
# Make sure the referenced issue actually exists
REDMINE_ISSUE=${BASH_REMATCH[2]}
REDMINE_ISSUE_EXISTS=$(${MYSQL} -N redmine -e "SELECT COUNT(*) FROM issues I WHERE I.id = ${REDMINE_ISSUE};")
[[ ${REDMINE_ISSUE_EXISTS} -ne 0 ]] || \
reject "Issue #${REDMINE_ISSUE} does not exist."
# Check message length, ignoring issue refs
MSGNOREF=${MESSAGE/${BASH_REMATCH[0]}}
[[ ${#MSGNOREF} -gt 10 ]] || \
reject "Your commit message \"$MSGNOREF\" is too short. Be more descriptive."
}
for rev in $(git rev-list --reverse ^$oldrev $newrev); do
checkMessage $rev
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment