How to use Git Hooks to save some time Who am I? Marian HackMan Marinov @OpenFest @турнето Chairman of Open Projects Foundation CEO & Co-founder of 1H Ltd. Part time lecturer at FMI and Telerik What is git? [ my repo ] <-----> [ central ] | \ | \ <----> [ stefan ] [ github ] <---> / What is a git hook? A simple script And what types of hooks do we have? pre-commit prepare-commit-msg commit-msg [--no-verify] post-commit post-checkout post-merge pre-receive post-receive My pre-commit #!/bin/bash change=($(git diff --name-status --cached)) st=${change[0]} name=${change[1]} function err() { echo -n "\nThere is an issue with the committed" echo -e "file: \e[31m$1\e[0m\n" echo "Please fix it before trying to commit again." exit 1 } ###### # Handle only files that are changed or newly added ###### if [ "$st" != 'M' ] && [ "$st" != 'A' ]; then exit 0 fi ###### # Bash syntax checks ###### if [[ "$name" =~ \.sh$ ]] && ( ! bash -n $name ); then err $name fi ###### # Perl handling ###### if [[ "$name" =~ \.pl$ ]]; then # Syntax checks if ( ! perl -c $name ); then err $name fi # Indentify the code # -syn - syntax checks # -dws - remove trailing white spaces # -et=4 - replace every 4 spaces with one tab # -bbs - blank lines before subs and packages # -ce - cuddled else; } else { if ( ! perltidy -syn -dws -et=4 -bbs -ce $name ); then err $name fi if [ -f ${name}.tdy ] && ( ! diff $name ${name}.tdy > /dev/null ); then /bin/mv -f ${name}.tdy $name fi # Produce some major critics about the code if ( ! perlcritic -2 $name ); then err $name fi fi ###### # PHP handling ###### if [[ "$name" =~ \.pl$ ]]; then # Syntax checks if ( ! php -l $name ); then err $name fi fi exit 0 What else can I do with hooks: * prepare-commit-msg / commit-msg - Auto format your commit messages - Add additional information into the commit, like signatures - Add third party CC for the patch(to be used by post-receive-email) * post-commit - auto generate patches or patch sets - auto push to default and non default remotes * post-checkout - fast deployment deploy everything in a separate branch and switch to it later - reconfigure your local copy * pre-receive - check the incoming data verify that there is no malicious code syntax checks * post-receive - Run code tests have a separate directory and make a pull in that dir and start test - Upload your project to the live environment pull the uploaded data directly into the live environment - Very fast deploy to live pull the new changes in a separate branch and switch to it - Update changes to your database - Use post-receive-email to send e-mail notifications - Auto push to other remotes /usr/share/git-core/contrib/hooks/post-receive-email [hooks] mailinglist = mm@1h.com emailprefix = [GIT] project/description How can you make use of the hooks for different languages: * Do syntax checks - bash -n - perl -c - ruby -c - php -l - python -m py_compile * Do Indentation - beautify_bash - Perl::Tidy - PHP Tidy - PythonTidy, untabify.py, reindent.py * Do sanity checks - Bash - checkbashisms - Perl::Critic - Python - pep8, pyflakes