49

I have a need to use multiple pre-commit hook scripts. Not sure how to handle them. Should all of them be combined into one single large pre-commit script ? if not, how to handle multiple pre-commit scripts ?

karthik101
  • 1,619
  • 4
  • 17
  • 23
  • same as http://stackoverflow.com/questions/30104343/multiple-git-hooks-for-the-same-trigger – André Feb 08 '17 at 07:07

3 Answers3

37

Should all of them be combined into one single large pre-commit script ?

Yes and no: you can only declare one pre-commit script, so this script should be in charge to:

  • call the actual pre-commit scripts
  • chose an order for those scripts to be called.

So:

  • one pre-commit script
  • calling multiple scripts, each one allowing or not (with their exit status) the commit to proceed.
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 22
    One way to organise this would be to create a `pre-commit.d` directory containing all the scripts you wish to run. Your `pre-commit` script would then run all these scripts in orders as suggested above. – TomDotTom Mar 07 '16 at 17:57
  • @TomDotTom Based on your suggestion I implemented something like this at https://bugs.chromium.org/p/gerrit/issues/detail?id=5999 and https://github.com/tommarshall/git-good-commit/issues/19 – sorin Apr 13 '17 at 18:54
25

You can use a delegating script that only calls others scripts (subhooks):

https://gist.github.com/carlos-jenkins/89da9dcf9e0d528ac978311938aade43

Usage:

Make your building system to create a symbolic link in the Git hooks directory to this script with the name of the hook you want to attend.

For example, pre-commit.

This hook will then execute, in alphabetic order, all executables files (subhooks) found under a folder named after the hook type you're attending suffixed with .d.

For example, pre-commit.d.

How it could look:

.git/hooks/
 |_ pre-commit -> ../../tools/git/multihooks.py
 |_ pre-commit.d/
    |_ 01-cpp_coding_standard
    |_ 02-python_coding_standard
    |_ 03-something_else

This requires Python3, but you could came with something similar using other technologies.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Havok
  • 5,776
  • 1
  • 35
  • 44
  • 4
    Not sure why you included the dependency of Python 3, but whatevs, I just made `pre-commit` a shell script, and then source in the other shell scripts from within the `pre-commit.d` dir. Seems to be working fine thus far. – ipatch Jul 03 '18 at 19:00
15

You can only have one pre-commit script, so you'll have to use that one to call multiple other scripts.

Create an executable /PATH/TO/GIT/.git/hooks/pre-commit file, with these contents:

#!/bin/bash

cd "$(dirname "$0")/pre-commit.d"

for hook in *; do
    bash $hook
    RESULT=$?
    if [ $RESULT != 0 ]; then
        echo "pre-commit.d/$hook returned non-zero: $RESULT, abort commit"
        exit $RESULT
    fi
done

exit 0

Then put all your pre-commit scripts inside a new pre-commit.d/ directory.

/PATH/TO/GIT/.git/hooks/
└── pre-commit.d
    └── SCRIPT1
    └── SCRIPT2

Make sure the script files are executable. Remember that the working dir will be /PATH/TO/GIT/.git/hooks/pre-commit.d/ by default inside the scripts.

Simon Epskamp
  • 8,813
  • 3
  • 53
  • 58