Answers:
我宁愿在提交前进行测试。因为更改已在提交时记录下来。推和拉仅交换有关已记录更改的信息。如果测试失败,则您的存储库中已经有一个“损坏的”修订版。无论您是否推动它。
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
Git在1.8.2版本中获得了预推钩子。
预推钩是我需要的,还有预提交钩。除了保护分支外,它们还可以结合预提交的钩子提供额外的安全性。
并举例说明如何使用(从这个不错的条目中摘录,采用和增强)
登录到无业游民,运行测试然后推送的简单示例
#!/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
如您所见,该示例使用了一个受保护的分支,即预推钩子的主题。
作为记录,Git 1.6有一个补丁,其中添加了一个预推钩子。我不知道它是否适用于1.7。
您可以运行@kubi推荐的推送脚本,而不用为此烦恼。您也可以改为使其成为Rake任务,因此它位于您的存储库中。ruby-git可以帮助解决这个问题。如果检查目标存储库,则只能在推送到生产存储库时运行测试。
最后,您可以在pre-commit
挂钩中运行测试,但要检查提交到哪个分支。然后,您可能会有一个production
分支,例如,它要求所有测试通过之后才能接受提交,但您master
不在乎。limerick_rake在这种情况下可能很有用。
高投票答案链接的脚本显示了pre-push
挂钩的参数等($1
是远程名称,$2
URL)以及如何访问提交(read
stdin中的行具有结构<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