2011-09-08 2 views
87

여기에 회사 서버에있는 베어 레포의 현재 훅이 있습니다 : git push origin master 그러면 Assembla에 푸시가 연결됩니다. 내가 필요한 것은 누군가가 서버의 해당 지점에 대한 변경 사항을 푸시하고 다른 지점으로 푸시를 무시할 때 하나의 지점 (마스터, 이상적으로) 만 푸시하는 것입니다. 베어 레포에서 지점을 선택하고 해당 지점 만 Assembla로 푸시 할 수 있습니까?특정 지점을 처리하기 위해 git post-receive 후크 작성하기

+0

무엇을 의미합니까? 'git push origin master'는'master' 브랜치를'origin' 리모트로 푸시합니다. 이것은 Assembla로 정의됩니다. 누군가가'feature1'과 반대로'master'를 밀 때만 후크를 트리거해야한다고 말하는 것입니까? –

+0

@ 스탄 정확히. 나는 hehe라는 단어를 찾을 수 없었다. –

+0

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

답변

7

post-receive 후크가 stdin에 도달하는 마지막 매개 변수는 ref가 변경된 것이므로이 값을 사용하여 해당 값이 "refs/heads/master"인지 확인할 수 있습니다. 나는에서 사용하는 것과 유사한 루비의 비트 후크 포스트 - 수신 :이 추진 된 각 심판에 대한 행을 얻을 수 있음을

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
스테판의 대답은 나를 위해 작동하지 않았다

하지만 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

간단한 이름 (master, test, etc.)을 가진 브랜치에서 저를 위해 일했습니다. 그러나 브랜치 이름이 다음과 같은 경우 : prod12/proj250/ropesPatch12. 그것은 잘 작동하지 않습니다. 특수 문자를 사용할 수있는 솔루션이 있습니까? –

335

는 후크 양식 <oldrev> <newrev> <refname>에, 표준 입력에서 인수를 얻을 후받을 수 있습니다. 이러한 인수는 명령 줄 인수가 아니라 표준 입력에서 오는 것이므로 $1 $2 $3 대신 read을 사용해야합니다.

포스트 수신 (누군가가 git push --all를 않는 경우, 예를 들어) 한 번에 여러 가지를 수신 할 수있는 후크를, 그래서 우리는 또한 while 루프에서 read을 포장해야합니다. 이상은 나를 위해 일한 솔루션의

#!/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

그건 이상합니다. Double equals와 Single equals는 모두 잘 작동해야합니다 (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'는 여기에 명시된 바와 같이 표준 입력을받습니다. https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks – h4xnoodle

0

이 기능을 수행하기 위해 PHP 스크립트를 직접 작성했습니다.

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

호스트 서버에서이 파일을, 바람직하게는 REPO 루트 및 GitHub의에 webhooks의 URL을 정의합니다. 8 행의 '모든 커밋'을 지사 이름으로 변경하고 18 행에 코드/기능을 추가하십시오.

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

간단한 방법은 git hook 쓰기에

read refname 
echo $refname 

간단한 - 더이 위대한 링크 hooking system

0

pre-push 같은 특정 자식 후크 잘 작동 @pauljz에서 그 답에 대한 정보 만 pre-commit는 않습니다 해당 변수에 액세스 할 수 없습니다. oldrev newrev refname

그래서이 대체 버전을 만들었습니다. 사전 커밋, 또는 정말로 후크를 위해 작동합니다. 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 문 사이에서 필요한 사항을 쉽게 수정할 수 있습니다.

관련 문제