2011-09-08 101 views
87

下面是我在当前公司服务器中的裸回购的钩子: git push origin master 这个钩子会推送到Assembla。 我需要的是只推送一个分支(主,理想),当有人推动到我们的服务器上的分支的变化,并忽略推到其他分支。是否可以从裸仓库中选择分支并只将该分支推送到Assembla?编写一个git post-receive hook来处理特定的分支

+0

你是什么意思? 'git push origin master'只会将'master'分支推送到'origin'远端,我认为它被定义为Assembla。你是说你只有在有人推到'master'时才需要触发* hook,而不是'feature1',或者类似的东西? –

+0

@Stefan正是这样。我找不到这个词,嘿嘿。 –

+0

Duplicate http://stackoverflow.com/questions/6372334/git-commit-hooks-per-branch – insign

回答

7

post-receive钩子在stdin上的最后一个参数是ref被修改了,所以我们可以用它来检查这个值是否为“refs/heads/master”。类似于我在使用Ruby的位后收到钩:

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

注意,它会因为这是每个被推参考线,所以如果你不只是主推多,它仍然会正常工作。

+0

感谢您的Ruby示例。我将要做类似的事情。 – Leif

5

Stefan的回答并没有为我工作,但this做的:

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

为我的分支用一个简单的名字(主,测试等)工作,但是当我有分支名称如:prod12/proj250/ropesPatch12。它不能很好地工作。你有可以与这些特殊字符一起工作的解决方案吗? –

335

一个后收到钩获取它的参数从标准输入,形式<oldrev> <newrev> <refname>。由于这些参数来自stdin,而不是来自命令行参数,因此您需要使用read而不是$1 $2 $3

的后收到钩可以同时接收多个分支(例如,如果有人做了git push --all),所以我们还需要来包装readwhile循环。

的工作片段看起来是这样的:

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

这应该被标记为正确的答案。 – jackyalcine

+2

“==”不适合我。单独的“=”对我很好。 – Ray

+0

这很奇怪。双等于和单等于应该在这里工作正常(见http://stackoverflow.com/questions/2600281/what-is-the-difference-between-operator-and-in-bash)。你可能使用除bash以外的东西吗?无论如何,很高兴你找到了解决办法。 – pauljz

3

以上为我工作的解决方案都不是。经过大量的调试之后,事实证明,使用'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 

UPDATE:在一个更奇怪的纸条,预先收到挂钩接收通过标准输入的输入,因此与“读”(哇,没想到我会这么说)读取。更新后的钩子仍然适用于我的$ 1。

+2

上面的解决方案可能没有用,因为它们专门用于'post-receive'钩子,而不是'post-update'钩子。他们以不同的方式接受他们的意见。 – pauljz

+0

'post-receive'需要stdin,如下所示:https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks – h4xnoodle

0

我已经为自己写了一个PHP脚本来完成这个功能。

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

主机服务器上的这个文件,最好回购根和定义GitHub的网络挂接的URL。将第8行的'allcommits'更改为您的分行名称,并在第18行添加您的代码/功能。

例如

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

简单的办法,在git hook

read refname 
echo $refname 

简单 - 这个伟大的链接hooking system

0

从@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之间的声明。