Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 269 lines (250 sloc) 7.69 KB
#!/bin/bash
#
# Copyright (c) 2010, Benjamin C. Meyer <ben@meyerhome.net>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of the project nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
function usage {
echo 'Git Hooks'
echo 'git hook [option] [cmd]'
echo ''
echo 'Options:'
echo ' --install Replace existing hooks in this repository with a call to'
echo ' git hooks run [hook]. Move old hooks directory to hooks.old'
echo ' --uninstall Remove existing hooks in this repository and rename hooks.old'
echo ' back to hooks'
echo ' --enable, -e [HOOK] Enable the specified hook, if no hook name is specified, all'
echo ' hooks will be enabled'
echo ' --disable, -d [HOOK] Disable the specified hook, if no hook name is specified, all'
echo ' hooks will be disabled'
echo 'Commands:'
echo ' run [cmd] Run the hooks for cmd (such as pre-commit)'
echo ' list Show currently installed hooks'
}
function run_hooks
{
dir="${1}"
if [[ -z ${dir} || ! -d "${dir}" ]] ; then
echo "run_hooks requires a directory name as an argument."
return 1
fi
shift 1
for hook in `list_hooks_in_dir "${dir}"`
do
export last_run_hook="${hook} $@"
if [ ! -z ${GIT_HOOKS_VERBOSE} ] ; then
echo -n "@@ Running hook: "
echo -n `basename \`dirname "${hook}"\``
echo "/`basename "${hook}"`"
fi
if [[ -x ${hook} ]]; then
${hook} "$@"
fi
done
}
##
# Run hooks
##
function report_error {
echo "Hook failed: $last_run_hook"
exit 1
}
function run_hook
{
set -e
hook=`basename "${1}"`
if [ -z ${hook} ] ; then
echo "run requires a hook argument"
return 1
fi
shift 1
for dir in `hook_dirs "${hook}"`; do
if [ ! -d "${dir}" ] ; then
continue
fi
run_hooks "${dir}" "$@"
done
set +e
}
##
# Install / Uninstall hooks in the git repository
##
function install_hooks
{
GITDIR=`git rev-parse --git-dir`
if [ ! $? -eq 0 ] ; then
echo "$1 must be run inside a git repository"
return 1
fi
cd $GITDIR
if [ "${1}" = "--install" ] ; then
mv hooks hooks.old
mkdir hooks
cd hooks
for file in applypatch-msg commit-msg post-applypatch post-checkout post-commit post-merge post-receive pre-applypatch pre-auto-gc pre-commit prepare-commit-msg pre-rebase pre-receive update
do
echo '#!/bin/bash
git-hooks run "$0" "$@"' > "${file}"
chmod +x "${file}"
done
if [[ ! -e "../../.githooks" ]]; then
mkdir "../../.githooks"
fi
else
if [ ! -d hooks.old ] ; then
echo "Error, hooks.old doesn't exists, aborting uninstall to not destroy something"
return 1
fi
rm -rf hooks
mv hooks.old hooks
fi
}
##
# List function
##
# Return the directories in which search hooks
# $1 ??
function hook_dirs
{
if [ ! -z "${1}" ] ; then
hook="/${1}"
else
hook=""
fi
echo "${HOME}/.git_hooks${hook}"
GITDIR=`git rev-parse --git-dir`
cd $GITDIR/..
echo "${PWD}/.githooks${hook}"
eval echo "`git config hooks.global`"${hook}
}
# List all hooks in the specified folder
# $1 - the folder supposed to contain hooks
function list_hooks_in_dir
{
if [[ $OSTYPE =~ 'darwin' ]] ; then
find -L "${1}/" -type f 2>/dev/null | grep -v "^.$" | sort
else
# find "${1}" -executable -type f 2>/dev/null | grep -v "^.$" | sort -V
find -L "${1}" -type f 2>/dev/null | grep -v "^.$" | sort -V
fi
}
# List all available hooks
function list_hooks
{
GITDIR=`git rev-parse --git-dir`
cat $GITDIR/hooks/pre-commit 2> /dev/null | grep 'git-hooks' > /dev/null 2> /dev/null
if [ $? = 0 ] ; then
echo "Git hooks ARE installed in this repository."
echo ""
else
echo "Git hooks are NOT installed in this repository."
echo ""
fi
echo 'Listing User, Project, and Global hooks:'
echo '---'
for dir in `hook_dirs`; do
echo "${dir}:"
for hook in `list_hooks_in_dir "${dir}"` ; do
# Display if hook is enable or not ( is executable or not )
if [[ -x ${hook} ]]; then
echo -en "\x1b[32m E \x1b[0m\t" # output green E
else
echo -en "\x1b[31m D \x1b[0m\t" # output red D
fi
echo -n `basename \`dirname "${hook}"\``
echo -ne "/`basename "${hook}"`"
if [[ -x ${hook} ]]; then
echo -e "\t- `${hook} --about 2>/dev/null`"
else
echo -e ""
fi
done
echo ""
done
}
##
# Enable / Disable hooks
##
# Enable the specified hook
# $1 - the file name of the hook to be enabled
function enable_hook {
for dir in `hook_dirs`; do
for hook in `list_hooks_in_dir "${dir}"` ; do
if [[ $# -eq 0 ]]; then
echo "Enabling ${hook}"
chmod +x ${hook}
else
if [[ $1 = `echo "${hook}" | rev | cut -d"/" -f1,2 | rev` ]]; then
echo "Enabling ${hook}"
chmod +x ${hook}
fi
fi
done
done
}
# Disable the specified hook
# $1 - the file name of the hook to be disabled
function disable_hook {
for dir in `hook_dirs`; do
for hook in `list_hooks_in_dir "${dir}"` ; do
if [[ $# -eq 0 ]]; then
echo "Disabling ${hook}"
chmod -x ${hook}
else
if [[ $1 = `echo "${hook}" | rev | cut -d"/" -f1,2 | rev` ]]; then
echo "Disabling ${hook}"
chmod -x ${hook}
fi
fi
done
done
}
case $1 in
list )
list_hooks
;;
run )
if [ ! -z "${GIT_DIR}" ] ; then
unset GIT_DIR
fi
shift
trap report_error ERR
run_hook "$@"
;;
--install|--uninstall )
install_hooks "$1"
;;
-e|--enable )
enable_hook $2
;;
-d|--disable )
disable_hook $2
;;
-h|--help )
usage
;;
* )
usage
;;
esac
Jump to Line
Something went wrong with that request. Please try again.