Git 预推钩子
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4196148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git pre-push hooks
提问by sheepwalker
I would like to run a unit-tests before every git push and if tests fails, cancel the push, but I can't even find pre-push hook, there is pre-commit and pre-rebase only.
我想在每次 git push 之前运行单元测试,如果测试失败,取消推送,但我什至找不到 pre-push 钩子,只有 pre-commit 和 pre-rebase。
采纳答案by ordnungswidrig
I would rather run the test in a pre-commit-hook. Because the change is already recorded when committing. Push and pull only exchange information about already recorded changed. If a test fails you would already have a "broken" revision in your repository. Whether you're pushing it or not.
我宁愿在预提交挂钩中运行测试。因为提交时已经记录了更改。推拉仅交换有关已记录更改的信息。如果测试失败,您的存储库中就已经有一个“损坏的”修订版。不管你推不推。
回答by manojlds
Git got the pre-push
hook in the 1.8.2
release.
Gitpre-push
在1.8.2
发布中获得了 钩子。
Sample pre-push
script: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample
示例pre-push
脚本:https: //github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample
1.8.2 release notes talking about the new pre-push hook: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt
1.8.2 发行说明谈论新的 pre-push hook:https: //github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt
回答by Jimmy Kane
Git got the pre-push hook in the 1.8.2 release.
Git 在 1.8.2 版本中获得了 pre-push hook。
Pre-push hooks are what I needed along with pre-commit hooks. Apart from protecting a branch, they can also provide extra security combined with pre-commit hooks.
预推钩子和预提交钩子是我需要的。除了保护分支之外,它们还可以与预提交挂钩相结合,提供额外的安全性。
And for an example on how to use (taken and adopted and enhanced from this nice entry)
以及如何使用的示例(从这个不错的条目中采用、采用和增强)
Simple example to login to vagrant, run tests and then push
登录 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,.*/\(.*\),,')
if [[ $current_branch = $protected_branch ]]; then
eval $CMD
RESULT=$?
if [ $RESULT -ne 0 ]; then
echo "failed $CMD"
exit 1
fi
fi
exit 0
As you can see the example uses a protected branch, subject of the pre-push hook.
如您所见,该示例使用受保护的分支,即 pre-push 钩子的主题。
回答by kubi
If you are using the command line, the easiest way to do this is to write a push script that runs your unit tests and, if they succeed, completes the push.
如果您使用命令行,最简单的方法是编写一个运行单元测试的推送脚本,如果它们成功,则完成推送。
Edit
编辑
As of git 1.8.2 this answer is outdated. See manojlds's answer above.
从 git 1.8.2 开始,这个答案已经过时了。请参阅上面的 manojlds 的回答。
回答by Jakob Borg
There isn't a hook for it, because a push isn't an operation that modifies your repository.
它没有钩子,因为推送不是修改存储库的操作。
You can do the checks on the receiving side though, in the post-receive
hook. That is where you would usually reject an incoming push. Running unit tests might be a little intensive to do in a hook, but that's up to you.
不过,您可以在接收方的post-receive
挂钩中进行检查。这就是您通常会拒绝传入推送的地方。在钩子中运行单元测试可能有点密集,但这取决于您。
回答by Turadg
For the record, there is a patch to Git 1.6 that adds a pre-push hook. I don't know whether it works against 1.7.
作为记录,Git 1.6有一个补丁添加了一个 pre-push hook。我不知道它是否适用于 1.7。
Rather than mess with that, you could run push script like @kubi recommended. You could also make it a Rake task instead so it's in your repo. ruby-gitcould help with this. If you check the target repo, you could run tests only when pushing to the production repo.
您可以像@kubi 推荐的那样运行推送脚本,而不是搞砸。你也可以把它变成一个 Rake 任务,所以它在你的仓库中。ruby-git可以帮助解决这个问题。如果您检查目标存储库,则只能在推送到生产存储库时运行测试。
Finally, you could run your tests in your pre-commit
hook but check for what branch is being committed to. Then you could have a, say, a production
branch that requires all tests pass before accepting a commit but your master
doesn't care. limerick_rakemay be useful in that scenario.
最后,您可以在您的pre-commit
钩子中运行您的测试,但检查正在提交的分支。然后你可以有一个production
分支,它需要在接受提交之前通过所有测试,但你master
并不关心。在这种情况下,limerick_rake可能很有用。
回答by serv-inc
The script linked by the highly-voted answershows the parameters etc to the pre-push
hook($1
is remote name, $2
URL) and how to access the commits (lines read
from stdin have structure <local ref> <local sha1> <remote ref> <remote sha1>
)
高票答案链接的脚本显示了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:
#
# -- Name of the remote to which the push is being done
# -- 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=""
url=""
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