编写一个 git post-receive 钩子来处理特定的分支
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7351551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Writing a git post-receive hook to deal with a specific branch
提问by Jorge Guberte
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?
这是我当前在公司服务器中的裸仓库中的git push origin master
钩子:
此钩子推送到 Assembla。当有人将更改推送到我们服务器上的该分支时,我需要只推送一个分支(理想情况下是主分支),而忽略对其他分支的推送。是否可以从裸仓库中选择分支并仅将该分支推送到 Assembla?
回答by pauljz
A post-receive hook gets its arguments from stdin, in the form <oldrev> <newrev> <refname>
. Since these arguments are coming from stdin, not from a command line argument, you need to use read
instead of $1 $2 $3
.
post-receive 钩子从标准输入获取它的参数,格式为<oldrev> <newrev> <refname>
. 由于这些参数来自标准输入,而不是来自命令行参数,因此您需要使用read
代替$1 $2 $3
。
The post-receive hook can receive multiple branches at once (for example if someone does a git push --all
), so we also need to wrap the read
in a while
loop.
post-receive 钩子可以一次接收多个分支(例如,如果有人做了 a 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
回答by ebneter
The last parameter that a post-receive hook gets on stdin is what ref was changed, so we can use that to check if that value was "refs/heads/master." A bit of ruby similar to what I use in a post-receive hook:
post-receive hook 在 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
Note that it gets a line for each ref that was pushed, so if you pushed more than just master, it will still work.
请注意,它为每个推送的 ref 获取一行,因此如果您推送的不仅仅是 master,它仍然可以工作。
回答by Dean Rather
Stefan's answer didn't work for me, but thisdid:
斯特凡的答案并没有对我来说有效,但这样做的:
#!/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"
回答by razvan
Neither of the solutions above worked for me. After much, much debugging, it turns out that using the 'read' command doesn't work -- instead, parsing command line arguments the usual way works fine.
上述两种解决方案都不适合我。经过多次调试,结果证明使用“read”命令不起作用——相反,以通常的方式解析命令行参数可以正常工作。
Here is the exact post-update hook that I just successfully tested now on CentOS 6.3.
这是我刚刚在 CentOS 6.3 上成功测试的确切更新后挂钩。
#!/bin/bash
echo "determining branch"
branch=`echo | 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
UPDATE: on an even stranger note, the pre-receive hook takes its input via stdin, therefore read with 'read' (wow, never thought I'd say that). The post-update hook still works with $1 for me.
更新:在一个更奇怪的笔记上,预接收钩子通过标准输入获取输入,因此用“读”读取(哇,从没想过我会这么说)。更新后挂钩对我来说仍然适用于 $1。
回答by TetraDev
The answer from @pauljz works fine for certain git hooks like pre-push
, but pre-commit
does not have access to those variables oldrev newrev refname
@pauljz 的答案适用于某些 git 钩子,例如pre-push
,但pre-commit
无法访问这些变量oldrev newrev refname
So I created this alternate version which works for pre-commit, or really and hook. This is a pre-commit
hook that will run a husky
script if we're NOT on the master
branch.
所以我创建了这个替代版本,它适用于预提交,或者真的和钩子。如果我们不在分支上,这是一个pre-commit
将运行husky
脚本的钩子master
。
#!/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 "" >/dev/null 2>&1
}
has_hook_script () {
[ -f package.json ] && cat package.json | grep -q "\"\"[[: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
I hope that helps someone. You can easily modify for your needs, anything in between the if
and fi
statements.
我希望能帮助某人。您可以根据需要轻松修改if
andfi
语句之间的任何内容。
回答by fotuzlab
I had written a PHP script for myself to do this functionality.
我为自己编写了一个 PHP 脚本来完成此功能。
https://github.com/fotuzlab/githubdump-php
https://github.com/fotuzlab/githubdump-php
Host this file on your server, preferably repo root and define the url in github webhooks. Change 'allcommits' on line 8 with your branch name and add your code/function at line 18.
将此文件托管在您的服务器上,最好是 repo root 并在 github webhooks 中定义 url。使用您的分支名称更改第 8 行的“allcommits”,并在第 18 行添加您的代码/函数。
e.g.
例如
function githubdump($payload_object) {
// Write your code here.
exec('git push origin master');
}
回答by Haris Krajina
Simple approach, in git hook
write
简单的方法,在git hook
写
read refname
echo $refname
Simple - more info on this great link hooking system
简单 - 关于这个伟大的链接挂钩系统的更多信息