web-dev-qa-db-ja.com

Git事前プッシュフック

すべてのgit Pushの前に単体テストを実行したいと思います。テストが失敗した場合、Pushをキャンセルしますが、Push事前フックを見つけることもできません。Pre-CommitとPre-Rebaseのみがあります。

101
sheepwalker

事前コミットフックでテストを実行したいです。変更はコミット時にすでに記録されているためです。プッシュとプルは、すでに記録された変更に関する情報のみを交換します。テストが失敗した場合、リポジトリにすでに「壊れた」リビジョンがあります。それを押しているかどうか。

21
ordnungswidrig

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

195
manojlds

Gitは1.8.2リリースでプッシュ前のフックを取得しました。

事前プッシュフックは、事前コミットフックとともに必要なものです。ブランチを保護するだけでなく、事前コミットフックと組み合わせて追加のセキュリティを提供することもできます。

また、使用方法の例については( このNiceエントリ から取得および採用および拡張されています)

Vagrantにログインし、テストを実行してからプッシュする簡単な例

#!/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 [email protected] -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

ご覧のとおり、この例では、プッシュ前のフックの対象である保護されたブランチを使用しています。

19
Jimmy Kane

コマンドラインを使用している場合、これを行う最も簡単な方法は、ユニットテストを実行し、成功した場合にプッシュを完了するプッシュスクリプトを記述することです。

編集

Git 1.8.2現在、この答えは時代遅れです。上記のmanojldsの回答を参照してください。

13
kubi

Pushはリポジトリを変更する操作ではないため、フックはありません。

ただし、受信側でpost-receiveフック。これは、通常、着信プッシュを拒否する場所です。単体テストの実行は、フックで行うのに少し集中的かもしれませんが、それはあなた次第です。

7
Jakob Borg

レコードには、 プッシュ前のフックを追加するGit 1.6へのパッチ があります。 1.7に対して機能するかどうかはわかりません。

それを台無しにするのではなく、@ kubiが推奨するようなプッシュスクリプトを実行できます。代わりにRakeタスクにして、レポジトリに含めることもできます。 Ruby-git はこれに役立ちます。ターゲットリポジトリを確認すると、本番リポジトリにプッシュするときにのみテストを実行できます。

最後に、pre-commitフックでテストを実行できますが、どのブランチがコミットされているかを確認します。次に、たとえば、コミットを受け入れる前にすべてのテストに合格する必要があるproductionブランチがありますが、masterは気にしません。 limerick_rake はそのシナリオで役立つかもしれません。

5
Turadg

高投票の回答によってリンクされたスクリプト は、パラメータなどを pre-Pushフック$1はリモート名、$2 URL)およびコミットへのアクセス方法(stdinの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
1
serv-inc