编写一个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
我希望能帮助别人。 你可以很容易地修改你的需求, if
和fi
语句之间的任何东西。