2011-09-08 68 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之間的聲明。