Git 사전 푸시 후크


답변:


14

차라리 사전 커밋 후크에서 테스트를 실행하고 싶습니다. 커밋 할 때 변경 사항이 이미 기록되어 있기 때문입니다. 밀고 당기는 것은 이미 기록 된 변경 사항에 대한 정보를 교환합니다. 테스트가 실패하면 이미 저장소에 "깨진"개정이있을 것입니다. 당신이 그것을 밀고 있든 안하든.


203
나는 일반적으로 동의하지만 나중에 스쿼시하기 위해 많은 점진적 커밋을 만드는 습관이 있고 테스트 스위트가 크면 비실용적 일 수 있습니다.
Cascabel

내가 참조. 따라서 메인 브랜치와 병합하기 전에 테스트를 실행하는 것이 좋지만 사전 병합 후크도 없습니다. 그러나 원격 저장소에서 ref를 업데이트하는 것을 방지하는 데 사용할 수있는 "update"후크가 있습니다. "원격 저장소에서 ref를 업데이트하기 직전에 업데이트 후크가 호출됩니다. 종료 상태는 ref의 성공 또는 실패를 결정합니다. 후크는 업데이트 할 각 참조에 대해 한 번씩 실행되며 업데이트중인 참조의 이름, 참조에 저장된 이전 개체 이름, 참조에 저장할 새 개체 이름의 세 가지 매개 변수를 사용합니다. "
ordnungswidrig 2010

18
정보를 제공하는 동안 OP의 질문을 완전히 무시하기 때문에 투표했습니다.
The Dembinski

1
@TheDembinski 나는 그것이 OP 질문을 무시한다고 말하지 않을 것입니다. 실제로 그것은 그것을 고려하고 OP가 생각했던 방식보다 더 나은 방법이 있다고 말합니다. 그것은 일반적으로 내가 받고 싶은 대답의 종류입니다.
calder.ty

9
@ calder.ty-아니. manojlds는 중요한 문제를 더 잘 해결합니다. 사실, 테스트를 실행하는 사전 커밋 후크는 일반적으로 나쁜 생각입니다. 커밋 된 모든 것이 테스트를 통과해야한다고 가정합니다. 공동 작업에 중점을 둔 일반적인 작업 흐름에는 좋지 않습니다. 그래서 그래 ... 나는 동의하지 않는다. "그것"을 수행하는 더 좋은 방법이 아니며 질문을 해결하지도 않습니다.
The Dembinski

209

Git은 릴리스 에서 pre-push후크를 얻었습니다 1.8.2.

샘플 pre-push스크립트 : https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample

1.8.2 새로운 프리 푸시 후크에 대한 릴리스 정보 : https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt


1
@manojlds이 훅이 어떤 용도로 사용되는지 알고 계십니까? 특정 지점에 푸시 할 때 내 바이너리를 고객에게 푸시하는 데 사용하고 싶습니다 (예 : 야간 버전을 빌드하고 푸시하기 전에 curl로 업로드). 문제는 빌드 및 업로드에 시간이 걸리고 원격으로 연결이 종료된다는 것입니다. 따라서 원격 저장소가 연결을 닫기 때문에 바이너리가 빌드되고 고객에게 업로드되었지만 저장소에 푸시되지는 않습니다. 이 문제를 해결하는 방법을 아십니까? 아니면 뿌리에서 나쁜 생각 일 수도 있습니다.
igrek

@igrek 연결 종료 문제에 대한 해결책을 찾았습니까?
Mario Estrada

1
@MarioEstrada, 예, 정확히 어떻게 기억이 나지 않지만 두 번 푸시했습니다. 첫 번째 git 명령은 단위 테스트를 실행 한 다음 연결을 끊지 않으면 다른 스레드에서 푸시하고 다른 푸시를 시작합니다. 밖으로, 다른 스레드의 두 번째 것이 나를 위해 작동합니다. 첫 번째와 두 번째가 성공하면 첫 번째 푸시는 변경 사항을 푸시하고 두 번째 푸시는 아무것도 푸시하지 않습니다. 트릭은 내가 (다시 단위 테스트를 시작하지 않았다, 그래서 두 번째 자식 푸시에 사용 된) 단위 테스트를 거치지 추가 일부 인수 한 것입니다
igrek

24

Git은 1.8.2 릴리스에서 사전 푸시 후크를 얻었습니다.

Pre-push 후크는 사전 커밋 후크와 함께 필요한 것입니다. 브랜치를 보호하는 것 외에도 사전 커밋 후크와 결합 된 추가 보안을 제공 할 수도 있습니다.

그리고 사용 방법에 대한 예 ( 이 멋진 항목 에서 가져 와서 채택 및 향상됨 )

방랑자에 로그인하고 테스트를 실행 한 다음 푸시하는 간단한 예제

#!/bin/bash
# Run the following command in the root of your project to install this pre-push hook:
# cp git-hooks/pre-push .git/hooks/pre-push; chmod 700 .git/hooks/pre-push

CMD="ssh vagrant@192.168.33.10 -i ~/.vagrant.d/insecure_private_key 'cd /vagrant/tests; /vagrant/vendor/bin/phpunit'"
protected_branch='master'

# Check if we actually have commits to push
commits=`git log @{u}..`
if [ -z "$commits" ]; then
    exit 0
fi

current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')

if [[ $current_branch = $protected_branch ]]; then
    eval $CMD
    RESULT=$?
    if [ $RESULT -ne 0 ]; then
        echo "failed $CMD"
        exit 1
    fi
fi
exit 0

보시다시피이 예제는 pre-push hook의 주제 인 보호 된 분기를 사용합니다.


14

명령 줄을 사용하는 경우 가장 쉬운 방법은 단위 테스트를 실행하고 성공하면 푸시를 완료하는 푸시 스크립트를 작성하는 것입니다.

편집하다

git 1.8.2 부터이 답변은 구식입니다. 위의 manojlds의 답변을 참조하십시오.


후크를 전혀 사용하지 않는다는 뜻입니까? 예를 들어 "git pull"을 "git uinttestspull"로 바꾸시겠습니까? 그것은 정확히 내가 필요한 것이 아닙니다
sheepwalker 2010-11-16

1
@sheepwalker : s / pull / push /, 별칭을 사용하여 멋지고 짧게 만드십시오.
Cascabel

@sheepwalker 네, 정확히 당신이 요청한 것은 아니지만 @calmh가 말했듯이, pre-push hooks는 없습니다.
kubi 2011

8

푸시는 리포지토리를 수정하는 작업이 아니기 때문에 후크가 없습니다.

수신 측에서 확인을 할 수 있습니다 post-receive. 일반적으로 들어오는 푸시를 거부하는 곳입니다. 단위 테스트를 실행하는 것은 훅에서 수행하는 데 약간 집약적 일 수 있지만 그것은 당신에게 달려 있습니다.


6

기록을 위해 사전 푸시 후크를 추가하는 Git 1.6에 대한 패치가 있습니다. 1.7에 대해 작동하는지 모르겠습니다.

엉망으로 만드는 대신 @kubi 권장과 같은 푸시 스크립트를 실행할 수 있습니다. 대신 Rake 작업으로 만들 수도 있으므로 저장소에 있습니다. ruby-git 이 도움이 될 수 있습니다. 대상 저장소를 확인하면 프로덕션 저장소로 푸시 할 때만 테스트를 실행할 수 있습니다.

마지막으로 pre-commit후크 에서 테스트를 실행할 수 있지만 어떤 분기가 커밋되고 있는지 확인할 수 있습니다. 그런 다음 production커밋을 수락하기 전에 모든 테스트를 통과해야하지만 master신경 쓰지 않는 분기를 가질 수 있습니다 . 이 시나리오에서는 limerick_rake 가 유용 할 수 있습니다.


감사합니다. 실제로 저는 이미 마지막 변형을 선택했습니다 (마지막으로 사전 커밋 후크에서 테스트를 실행할 수 있습니다 ..)
sheepwalker

1

응답 높은 투표에 의해 연결 스크립트를 받는 쇼를 매개 변수 등을 pre-push후크 ( $1원격 이름입니다 $2어떻게 커밋에 액세스하는 방법과 URL) (라인 read표준 입력에서이 구조를 가지고 <local ref> <local sha1> <remote ref> <remote sha1>)

#!/bin/sh

# An example hook script to verify what is about to be pushed.  Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed.  If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
#   <local ref> <local sha1> <remote ref> <remote sha1>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).

remote="$1"
url="$2"

z40=0000000000000000000000000000000000000000

while read local_ref local_sha remote_ref remote_sha
do
    if [ "$local_sha" = $z40 ]
    then
        # Handle delete
        :
    else
        if [ "$remote_sha" = $z40 ]
        then
            # New branch, examine all commits
            range="$local_sha"
        else
            # Update to existing branch, examine new commits
            range="$remote_sha..$local_sha"
        fi

        # Check for WIP commit
        commit=`git rev-list -n 1 --grep '^WIP' "$range"`
        if [ -n "$commit" ]
        then
            echo >&2 "Found WIP commit in $local_ref, not pushing"
            exit 1
        fi
    fi
done

exit 0
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.