Chaining git hooks

て烟熏妆下的殇ゞ 提交于 2019-11-29 20:10:06

After further investigation and testing, here is a working solution:

create file .git/hooks/hook-chain as follows

#!/bin/bash
#
# author: orefalo

hookname=`basename $0`


FILE=`mktemp`
trap 'rm -f $FILE' EXIT
cat - > $FILE

for hook in $GIT_DIR/hooks/$hookname.*
do
    if test -x "$hook"; then
#       echo $hook
        cat $FILE | $hook "$@"
        status=$?

        if test $status -ne 0; then
            echo Hook $hook failed with error code $status
            exit $status
        fi
    fi
done

Now link any hook that requires chaining, for instance

  • ln -s hook-chain update
  • ln -s hook-chain post-receive

finally, create the chains by renaming them as hookname.action

 -rwxr-xr-x. 1 git  git  6710  functions
 -rwxr-xr-x. 1 git  git   280  hook-chain
 -rwxr-xr-x. 1 git  git  1524  post-mirror
 lrwxrwxrwx. 1 root root   10  post-receive -> hook-chain
 -rwxr-xr-x. 1 git  git  8763  post-receive.1email
 -rwxr-xr-x. 1 git  git  1745  post-receive.2github
 -rwxr-xr-x. 1 git  git   473  post-upload-pack
 -rwxr-xr-x. 1 git  git   346  pre-receive
 lrwxrwxrwx. 1 root root   10  update -> hook-chain
 -rwxr-xr-x. 1 git  git  2975  update.1acl
 -rwxr-xr-x. 1 git  git   328  update.2github

for instance, in the sample above, the update hook will run update.1acl followed by update.2github.

The post-receive hook with run post-receive.1email followed by post-receive.2github

sanmai

For those who're not willing to click on every link in comments below other answer, here's a practically unmodified version of the script by @HenrikN:

#!/bin/bash

# Runs all executable hookname-* hooks and exits after,
# if any of them was not successful.
#
# Based on
# http://osdir.com/ml/git/2009-01/msg00308.html

data=$(cat)
exitcodes=()
hookname=$(basename $0)

# Run each hook, passing through STDIN and storing the exit code.
# We don't want to bail at the first failure, as the user might
# then bypass the hooks without knowing about additional issues.

for hook in $GIT_DIR/hooks/$hookname-*; do
  test -x "$hook" || continue
  echo "$data" | "$hook"
  exitcodes+=($?)
done

# If any exit code isn't 0, bail.

for i in "${exitcodes[@]}"; do
  [ "$i" == 0 ] || exit $i
done

I created a shell script based on OP and Olivier Refalo posts (with some modifications):

https://gist.github.com/amirbawab/e9f42ef8d441316707d9b90777e5718b

The script will generate a hook files that will execute scripts inside $hook_file_name.d/$hook_file_name.*

For example: for commit-msg hook, the script will generate commit-msg file under .git/hooks that will execute all script under commit-msg.d/.

Files under commit-msg.d should match the pattern commit-msg.* to allow placing helper shell files in those folder without executing them.

Script usage: ./extend_git_hooks.sh [REPO_PATH]

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!