这是我在公司服务器上的裸仓库中当前的挂钩:
git push origin master
该挂钩会将更改推送到Assembla。
我需要的是,当有人在我们的服务器上将更改推送到该分支时,只推送一个分支(最好是主分支),并忽略对其他分支的推送。是否可以从裸仓库中选择分支并仅将该分支推送到Assembla?
这是我在公司服务器上的裸仓库中当前的挂钩:
git push origin master
该挂钩会将更改推送到Assembla。
我需要的是,当有人在我们的服务器上将更改推送到该分支时,只推送一个分支(最好是主分支),并忽略对其他分支的推送。是否可以从裸仓库中选择分支并仅将该分支推送到Assembla?
一个 post-receive hook 从 stdin 中获取其参数,格式如下:
<oldrev> <newrev> <refname>
由于这些参数来自标准输入,而不是命令行参数,所以您需要使用 read
而不是 $1 $2 $3
。
post-receive钩子可以一次接收多个分支(例如如果有人执行了 git push --all
),因此我们还需要将read
包装在一个while
循环中。
一个可运行的代码片段大致如下:
#!/bin/bash
while read oldrev newrev refname
do
branch=$(git rev-parse --symbolic --abbrev-ref $refname)
if [ "master" = "$branch" ]; then
# Do something
fi
done
#!/bin/sh
而非#!/bin/bash
? - shuttle87refs/heads/master
而不是refs/tags/master
,那么应该没问题。虽然我想不到其他类似的情况,但这可能是一个好的StackOverflow问题。 - pauljzif branch=$(git rev-parse --symbolic --abbrev-ref $refname 2>/dev/null); then
这个命令,这样当我删除一个分支时,git就不会抱怨了。 - JérômeSTDIN.each do |line|
(old_rev, new_rev, ref_name) = line.split
if ref_name =~ /master/
# do your push
end
end
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"
以上两种解决方案都对我无效。经过大量调试,发现使用“read”命令不起作用——相反,通常的解析命令行参数的方法可以很好地工作。
这是我刚在CentOS 6.3上成功测试的excat post-update钩子:
#!/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
更新:更奇怪的是,pre-receive钩子通过stdin接收输入,因此使用'read'命令读取(哇,从未想过我会这么说)。post-update钩子对我来说仍然使用$1有效。
post-receive
钩子,而不是post-update
钩子。它们以不同的方式接收输入。 - pauljzpost-receive
接受标准输入,如此处所述:https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks - h4xnoodle@pauljz的答案适用于某些git hooks,例如pre-push
,但是pre-commit
没有访问那些变量oldrev newrev refname
的权限。
因此,我创建了这个替代版本,它适用于pre-commit
或任何hook。 这是一个pre-commit
hook,如果我们不在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
语句之间的任何内容。我为自己编写了一个 PHP 脚本来实现这个功能。
https://github.com/fotuzlab/githubdump-php
将此文件托管在您的服务器上,最好是存储库根目录,并在 GitHub Webhooks 中定义 URL。将第8行中的“allcommits”更改为您的分支名称,并在第18行添加您的代码/函数。
例如:
function githubdump($payload_object) {
// Write your code here.
exec('git push origin master');
}
git push origin master
只会将master
分支推送到origin
远程,我猜测这个远程是定义为 Assembla 的。你是说只有当有人推送到master
分支时才需要触发钩子,而不是feature1
或其他分支吗? - Stefan Kendall