这是我当前存放在公司服务器中的裸存储库中的git push origin master
钩子:
该钩子将推到Assembla。我需要的是,当有人将更改推送到我们服务器上的该分支时,仅推送一个分支(理想情况下为master),而忽略推送到其他分支。是否可以从裸仓库中选择分支,然后仅将该分支推送到Assembla?
这是我当前存放在公司服务器中的裸存储库中的git push origin master
钩子:
该钩子将推到Assembla。我需要的是,当有人将更改推送到我们服务器上的该分支时,仅推送一个分支(理想情况下为master),而忽略推送到其他分支。是否可以从裸仓库中选择分支,然后仅将该分支推送到Assembla?
Answers:
接收后挂钩从stdin获取其参数,形式为<oldrev> <newrev> <refname>
。由于这些参数来自标准输入,而不是命令行参数,因此需要使用read
代替$1 $2 $3
。
后收到钩可以同时接收多个分支(例如,如果有人做了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
吗?
refs/heads/master
而不是refs/tags/master
您应该没事。也许还有其他我无法想到的极端情况。就其本身而言,这可能是一个很好的StackOverflow问题。
if branch=$(git rev-parse --symbolic --abbrev-ref $refname 2>/dev/null); then
以便在删除分支时git不会抱怨。
斯特凡的答案并没有为我工作,但这样做的:
#!/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上成功测试的确切的更新后挂钩。
#!/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。
post-receive
挂钩而不是post-update
挂钩。他们以不同的方式接受他们的意见。
post-receive
以stdin如下所示:git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
@pauljz的答案适用于某些git钩子,如pre-push
,但pre-commit
无法访问这些变量oldrev newrev refname
因此,我创建了此备用版本,该版本适用于预提交或真正的钩子。如果我们不在分支上,这是一个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 "$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