2012-01-04 143 views
32

很多人可能知道,git中只能有一個鉤子類型。 如果需要評估兩個更新掛鉤。 git的管理留下兩個不可收拾解決方案:鏈接git鉤子

  1. 合併的鉤子腳本一起
  2. 手動與exec

我找一個優雅的解決方案(寫在BASH)把它們連,就像一個文件夾hooks/update.dhooks/post-receive.d,這將允許鉤評估的鬆散耦合。一旦鉤子失敗,鏈接應該停止。

我居然發現perl寫一個可接受的解決方案,在這個URL http://blog.bluefeet.net/2011/08/chained-git-hooks

問題:我的服務器上運行不同版本的Perl和我得到PERLLIB版本不匹配。它失敗。

+1

相關答案:http://stackoverflow.com/a/3464399/119963有跟蹤的掛鉤,而不是鏈接它們,但鏈接基本上是一個平凡擴張的重點:一包循環執行鉤子程序(例如'hook for hooks/update.d/*; do ...') – Cascabel 2012-01-04 18:03:36

+0

謝謝你的指針,它有幫助 – 2012-01-04 22:16:14

回答

32

經過進一步調查和測試,這裏是一個有效的解決方案:

創建文件.git/hooks/hook-chain如下

#!/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 "[email protected]" 
     status=$? 

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

現在鏈接需要鏈接任何掛鉤,例如

  • LN - s鉤鏈更新
  • ln -s鉤鏈後接收

最後,通過將它們重命名爲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 

例如,上面的示例中,所述更新鉤將運行update.1acl隨後update.2github

後收到鉤與運行後receive.1email隨後後receive.2github

+3

這不是代碼評論網站,而是......而是除了明確刪除tmpfile,通過在調用mktemp之前添加以下行來自動刪除它:trap'rm -f $ FILE'0 – 2012-01-04 22:48:04

+0

好的建議,謝謝 – 2012-01-05 02:07:28

+1

在[this mail](http://osdir.com/ ml/git/2009-01/msg00308.html),而不是臨時文件,有人做'data = $(cat)',然後'echo「$ data」| 「$鉤」'。 – 2012-06-19 20:11:14

3

對於那些誰是不是願意點擊每一個環節上的評論below other answer,這裏的的the script一個幾乎未修改的版本由@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 
0

我創建了一個shell腳本基於OP和Olivier Refalo職位(有一些修改):

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

該腳本將生成一個鉤子文件將執行腳本里面$hook_file_name.d/$hook_file_name.*

例如:commit-msg掛鉤,腳本會產生.git/hookscommit-msg文件,該文件將執行commit-msg.d/下的所有腳本。

commit-msg.d下的文件應匹配的模式commit-msg.*允許將幫助Shell文件夾那些在沒有執行它們。

腳本使用:./extend_git_hooks.sh [REPO_PATH]