编写一个git post-receive hook来处理特定的分支

这里是我目前在公司的服务器上的裸回购钩: git push origin master这个钩子推到Assembla。 我需要的只是推一个分支(主,理想),当有人推动到我们的服务器上的分支的变化,并忽略推其他分支。 是否有可能从裸露的回购中select分支并只将该分支推送到Assembla?

post-receive钩子以stdinforms从<oldrev> <newrev> <refname>获取参数。 由于这些参数来自stdin,而不是来自命令行参数,所以您需要使用read而不是$1 $2 $3

后接收钩子可以一次接收多个分支(例如,如果有人做了一个git push --all ),所以我们还需要在while循环中包装read

工作片段如下所示:

 #!/bin/bash while read oldrev newrev refname do branch=$(git rev-parse --symbolic --abbrev-ref $refname) if [ "master" == "$branch" ]; then # Do something fi done 

post-receive钩子在stdin上的最后一个参数是ref被修改了,所以我们可以用它来检查这个值是否是“refs / heads / master”。 一些类似于我在post-receive hook中使用的ruby:

 STDIN.each do |line| (old_rev, new_rev, ref_name) = line.split if ref_name =~ /master/ # do your push end end 

请注意,它会为每个推送的参考文件添加一行,所以如果您推送的不仅仅是主文件,它仍然可以工作。

斯蒂芬的回答对我来说不起作用,但是这样做:

 #!/bin/bash echo "determining branch" if ! [ -t 0 ]; then read -a ref fi IFS='/' read -ra REF <<< "${ref[2]}" branch="${REF[2]}" if [ "master" == "$branch" ]; then echo 'master was pushed' fi if [ "staging" == "$branch" ]; then echo 'staging was pushed' fi echo "done" 

以上两种解决scheme都不适合我。 经过大量的debugging之后,事实certificate,使用'read'命令是行不通的,相反,parsing命令行参数通常是正常的。

这里是我刚刚在CentOS 6.3上成功testing过的确切的更新后钩子。

 #!/bin/bash echo "determining branch" branch=`echo $1 | cut -d/ -f3` if [ "master" == "$branch" ]; then echo "master branch selected" fi if [ "staging" == "$branch" ]; then echo "staging branch selected" fi exec git update-server-info 

更新:更奇怪的是,预接收钩子通过stdininput,因此用“read”读取(哇,从来没有想过我会这么说)。 更新后的钩子仍然适用于我$ 1。

我为自己写了一个PHP脚本来完成这个function。

https://github.com/fotuzlab/githubdump-php

在你的服务器上托pipe这个文件,最好是repo root,并在github webhooks中定义这个url。 用你的分行名称更改第8行的“allcommits”,并在第18行添加你的代码/function。

例如

 function githubdump($payload_object) { // Write your code here. exec('git push origin master'); } 

简单的方法,在git hook

 read refname echo $refname 

简单 – 这个伟大的链接钩系统的更多信息

@pauljz的回答对于某些像pre-push这样的git钩子工作正常,但是pre-commit不能访问这些variablesoldrev newrev refname

所以我创build了这个替代版本,它适用于预先提交,或真正的和挂钩。 这是一个pre-commit钩子,如果我们不在master分支上,它将运行一个husky脚本。

 #!/bin/bash # git 'commit' does not have access to these variables: oldrev newrev refname # So get the branch name off the head branchPath=$(git symbolic-ref -q HEAD) # Something like refs/heads/myBranchName branch=${branchPath##*/} # Get text behind the last / of the branch path echo "Head: $branchPath"; echo "Current Branch: $branch"; if [ "master" != "$branch" ]; then # If we're NOT on the Master branch, then Do something # Original Pre-push script from husky 0.14.3 command_exists () { command -v "$1" >/dev/null 2>&1 } has_hook_script () { [ -f package.json ] && cat package.json | grep -q "\"$1\"[[:space:]]*:" } cd "frontend" # change to your project directory, if .git is a level higher # Check if precommit script is defined, skip if not has_hook_script precommit || exit 0 # Node standard installation export PATH="$PATH:/c/Program Files/nodejs" # Check that npm exists command_exists npm || { echo >&2 "husky > can't find npm in PATH, skipping precommit script in package.json" exit 0 } # Export Git hook params export GIT_PARAMS="$*" # Run npm script echo "husky > npm run -s precommit (node `node -v`)" echo npm run -s precommit || { echo echo "husky > pre-commit hook failed (add --no-verify to bypass)" exit 1 } fi 

我希望能帮助别人。 你可以很容易地修改你的需求, iffi语句之间的任何东西。