预推
适用于 Git 1.8.2 及更高版本。
Version >= 1.8
可以使用预推钩来防止推动。这有用的原因包括:阻止意外手动推送到特定分支,或者如果已建立的检查失败则阻止推送(单元测试,语法)。
只需在 .git/hooks/
下创建一个名为 pre-push
的文件和(gotcha alert ) 创建一个预推钩,确保该文件是可执行的:chmod +x ./git/hooks/pre-push
。
以下是汉娜·沃尔夫 ( Hannah Wolfe)阻止推动掌握的一个例子 :
#!/bin/bash
protected_branch='master'
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
if [ $protected_branch = $current_branch ]
then
read -p "You're about to push master, is that what you intended? [y|n] " -n 1 -r < /dev/tty
echo
if echo $REPLY | grep -E '^[Yy]$' > /dev/null
then
exit 0 # push will execute
fi
exit 1 # push will not execute
else
exit 0 # push will execute
fi
这是 Volkan Unsal 的一个例子,它确保 RSpec 测试在允许推送之前通过:
#!/usr/bin/env ruby
require 'pty'
html_path = "rspec_results.html"
begin
PTY.spawn( "rspec spec --format h > rspec_results.html" ) do |stdin, stdout, pid|
begin
stdin.each { |line| print line }
rescue Errno::EIO
end
end
rescue PTY::ChildExited
puts "Child process exit!"
end
# find out if there were any errors
html = open(html_path).read
examples = html.match(/(\d+) examples/)[0].to_i rescue 0
errors = html.match(/(\d+) errors/)[0].to_i rescue 0
if errors == 0 then
errors = html.match(/(\d+) failure/)[0].to_i rescue 0
end
pending = html.match(/(\d+) pending/)[0].to_i rescue 0
if errors.zero?
puts "0 failed! #{examples} run, #{pending} pending"
# HTML Output when tests ran successfully:
# puts "View spec results at #{File.expand_path(html_path)}"
sleep 1
exit 0
else
puts "\aCOMMIT FAILED!!"
puts "View your rspec results at #{File.expand_path(html_path)}"
puts
puts "#{errors} failed! #{examples} run, #{pending} pending"
# Open HTML Ooutput when tests failed
# `open #{html_path}`
exit 1
end
正如你所看到的,有很多可能性,但核心部分是如果好事发生的话,那就是发生了坏事。任何时候你都可以防止推送,你的代码将处于运行 git push...
之前的状态。
使用客户端挂钩时,请记住,用户可以通过在推送时使用选项“–no-verify”来跳过所有客户端挂钩。如果你依赖钩子来强制执行流程,那么你可能会被烧毁。
文档: https : //git-scm.com/docs/githooks#_pre_push
官方样本: https : //github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks–pre-push.sample