git push 后本地执行钩子?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1797074/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 07:24:35  来源:igfitidea点击:

Local executing hook after a git push?

gitgithooks

提问by scotchi

I've looked at the githooks manpagebut unless I'm missing something I don't see an option for local, post-push git hooks. I'd like to have one that updates the api docs on my web server (for which I already have a script) after I push the master branch to the GitHub repo. Of course I could just write my own script that combines the git push and the api docs run, but that feels somewhat inelegant.

我查看了 githooks 联机帮助页,但除非我遗漏了某些内容,否则我看不到本地推送后 git 挂钩的选项。在将主分支推送到 GitHub 存储库后,我希望有一个更新我的 Web 服务器上的 api 文档(我已经有一个脚本)。当然,我可以编写自己的脚本,将 git push 和 api docs run 结合起来,但这感觉有些不雅。

采纳答案by Adrián Deccico

From Git 1.8.2 there is a new hook invoked before the push operation: pre-pushIf the script returns other than 0 the push operation will be cancelled.

从 Git 1.8.2 开始,在推送操作之前调用了一个新的钩子:pre-push如果脚本返回的不是 0,推送操作将被取消。

Mention in the release notes: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt#L167

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

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

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

回答by Frank S. Thomas

Another solution to this problem is to have a wrapper for git pushthat executes .git/hooks/pre-pushand .git/hooks/post-pushscripts before and after the git pushcall. A possible wrapper could look like this:

这个问题的另一个解决方案是在调用之前和之后为git push执行.git/hooks/pre-push.git/hooks/post-push脚本提供一个包装器git 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" "$@"

Saved as git-push-whsomewhere in your PATH, it can then be called as git push-whif you want to push with hooks.

保存git-push-wh在你的某个地方,PATH然后可以像git push-wh你想用钩子推送一样调用它。

回答by Chris Johnsen

This type of hook is not supported by Git. It falls outside the valid reasons for a Git hookas given by Git's maintainer.

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

The introductory remark in the above linked message speaks almost directly to your case:

上述链接消息中的介绍性评论几乎直接说明了您的情况:

I do not particularly like hooks that act after an operation is initiated locally and act solely on local data. This is maybe because I still consider git tools building blocks suitable for higher level scripting more than other people do.

我并不特别喜欢在本地启动操作后仅作用于本地数据的钩子。这可能是因为我仍然认为 git 工具构建块比其他人更适合更高级的脚本编写。

P.S. A “Single Push” Hint

PS“单推”提示

  • There are too many caveats for a full explanation, but if you can figure it all out you should be able to deal with the details.
  • 一个完整的解释有太多的警告,但如果你能全部弄清楚,你应该能够处理细节。

An extra pushurlto a local repo with an “alternates” objects store could give you a low overhead way to locally execute a push hook. But really, the effort is much more than git push upstream && update-web-server(maybe in a shell alias, git alias, or script).

pushurl具有“替代”对象存储的本地存储库的额外功能可以为您提供一种在本地执行推送钩子的低开销方式。但实际上,工作量远不止git push upstream && update-web-server(可能在 shell 别名、git 别名或脚本中)。

回答by ndbroadbent

I recently came across the same issue. I wanted a hook so that a push from my git submodule would commit the new submodule reference in the 'superproject'.

我最近遇到了同样的问题。我想要一个钩子,以便从我的 git 子模块推送将在“超级项目”中提交新的子模块引用。

As Chris mentioned, the best way is to just use a git alias, like this:

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

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

This adds the following to your .git/config file:

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

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

And so now, if you type:

所以现在,如果你输入:

$ git xpush

your changes will be pushed, and then update-server.sh will be executed.

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

回答by pschmitt

I'm using a function for this:

我为此使用了一个函数:

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

The compdef part is for ZSH.

compdef 部分用于 ZSH。