Git 推后的本地执行钩子?

我已经看了 Githooks 页面,但除非我遗漏了什么,否则我看不到一个本地的,后推 git 钩子的选项。我想有一个更新 api 文档在我的网络服务器(我已经有一个脚本)后,我推主分支到 GitHub 回购。当然,我也可以编写自己的脚本,将 git push 和 api docs 运行结合起来,但是这样感觉有点不雅观。

52299 次浏览

Git 不支持这种类型的钩子。它不属于 Git 挂钩的正当理由 由 Git 的维护者提供。

上述链接信息中的介绍性语句几乎直接说明了您的情况:

我不是特别喜欢那个钩子 在行动开始后采取行动 本地化,并且只对本地数据采取行动。 这可能是因为我还在考虑 适用于 更高层次的脚本 人们会的。

附注,一个“单击”提示

  • 有太多的警告需要一个完整的解释,但是如果你能弄清楚所有的事情,你应该能够处理细节。

一个额外的 pushurl到一个带有“备用”对象存储的本地回购可以给你一个低开销的方式来本地执行一个推钩。但实际上,这种工作要比 git push upstream && update-web-server多得多(可能在 shell 别名、 git 别名或脚本中)。

我最近也遇到了同样的问题。我需要一个钩子,这样来自 git 子模块的一个 push 就可以在“ superproject”中提交新的子模块引用。

正如 Chris 提到的,最好的方法就是使用 git 别名,如下所示:

$ git config alias.xpush '!git push $1 $2 && update-server.sh'
# (remember the backslash before the ! if your shell requires it)

这会将以下内容添加到. git/config 文件中:

[alias]
xpush = !git push $1 $2 && update-server.sh

现在,如果你输入:

$ git xpush

您的更改将被推送,然后执行 update-server.sh。

这个问题的另一个解决方案是为 git push设置一个包装器,在 git push调用之前和之后执行 .git/hooks/pre-push.git/hooks/post-push脚本。可能的包装可以是这样的:

#!/bin/sh


GIT_DIR_="$(git rev-parse --git-dir)"
BRANCH="$(git rev-parse --symbolic --abbrev-ref $(git symbolic-ref HEAD))"


PRE_PUSH="$GIT_DIR_/hooks/pre-push"
POST_PUSH="$GIT_DIR_/hooks/post-push"


test -x "$PRE_PUSH" &&
exec "$PRE_PUSH" "$BRANCH" "$@"


git push "$@"


test $? -eq 0 && test -x "$POST_PUSH" &&
exec "$POST_PUSH" "$BRANCH" "$@"

保存为 git-push-wh在您的 PATH的某个地方,然后可以被称为 git push-wh,如果你想用钩子推。

在 Git1.8.2中,在 push 操作之前调用了一个新的钩子: 预推如果脚本返回的值不是0,那么 push 操作将被取消。

在发布说明中提到: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt#L167

样本: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample

我用了一个函数:

current_branch() {
local ref=$(git symbolic-ref HEAD 2> /dev/null) || return
echo ${ref#refs/heads/}
}


gp() {
local post_push="$(git rev-parse --git-dir)/hooks/post-push"
git push "$@" && {
[[ -x "$post_push" ]] && "$post_push" "$(current_branch)" "$@"
}
}
compdef _git gp=git-push

Compdef 部分用于 ZSH。

只要创建一个 pre-push钩子,在顶部睡眠。确保睡眠时间足够长,以便根据网络连接速度将提交上传到上游服务器。理想情况下,添加一个 &来在后台运行脚本:

(sleep 30 && .git/hooks/post-push) &

通过使用 reference-transaction钩子,实现后推钩子实际上是可能的。在推送完成之后,git 将在本地更新远程跟踪分支,从而触发 refs/remotes/REMOTE/BRANCH上的引用事务。

下面是一个使用这种技术的钩子示例:

#!/bin/bash
set -eu


while read oldvalue newvalue refname
do
if [ $1 = committed -a $refname = refs/remotes/origin/main ]
then
exec .git/hooks/post-push
fi
done

此脚本必须具有可执行位,并放置在 .git/hooks/reference-transaction中。钩子在将主枝推向原点后运行。将实际的钩子脚本放在 .git/hooks/post-push中。