Writing a git post-receive hook to deal with a specific branch

Here's my current hook in a bare repo that lives in the company's server: git push origin master This hooks pushes to Assembla. What i need is to push only one branch (master, ideally) when someone pushes changes to that branch on our server, and ignore pushes to other branches. Is it possible to select the branch from a bare repo and push only that branch to Assembla?

57639 次浏览

后接收钩子在 stdin 上获得的最后一个参数是 ref 被更改的内容,因此我们可以使用该参数检查该值是否为“ refs/head/master”一点红宝石,类似于我在接收后挂钩中使用的:

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

请注意,它为每个被推送的参考文献获取一行,所以如果您推送的不仅仅是 master,它仍然可以工作。

Stefan 的回答对我不起作用,但 这个起作用了:

#!/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"

后接收钩子从 stdin 获取参数的形式如下:

<oldrev> <newrev> <refname>

由于这些参数来自 stdin,而不是命令行参数,因此需要使用 read而不是 $1 $2 $3

接收后的钩子可以同时接收多个分支(例如,如果有人执行 git push --all) ,因此我们还需要将 read包装在 while循环中。

A working snippet looks something like this:

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

以上两种解决方案对我都不管用。在进行了大量的调试之后,结果证明使用“ read”命令不起作用——相反,按照通常的方式解析命令行参数是可行的。

这是我刚刚在 CentOS 6.3上成功测试的更新后挂钩。

#!/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

更新: 更奇怪的是,预接收钩子通过 stdin 接收它的输入,因此使用“ read”进行读取(哇,没想到我会这么说)。更新后的钩子对我来说仍然只需要1美元。

我为自己编写了一个 PHP 脚本来实现这个功能。

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

将这个文件托管在您的服务器上,最好是回收根目录,并在 github webhook 中定义 URL。在第8行使用您的分支名称更改“ allcommit”,并在第18行添加您的代码/函数。

例如:。

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

简单的方法,用 git hook

read refname
echo $refname

Simple - more info on this great link 挂钩系统

来自@pauljz 的答案对于某些 git 挂钩(如 pre-push)可以很好地工作,但是 pre-commit不能访问这些变量 oldrev newrev refname

所以我创建了这个替代版本,它适用于提前提交,或者真的和钩子。这是一个 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语句之间的任何内容。