在预推钩中,获得"git push"按钮.命令全部内容? [英] In pre-push hook, get "git push" command full content?

查看:96
本文介绍了在预推钩中,获得"git push"按钮.命令全部内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当Git pre-push 钩子脚本工作时,如何获取完整的 git push 命令内容?

When a Git pre-push hooks script is working, how to get the full git push command content?

例如,当我运行: git push origin master 时,执行了预推钩子.我想获取 origin & master 在这个钩子中.

Example, when I run: git push origin master, pre-push hooks executed.
I want to get origin & master in this hook.

如何获取参数列表?

推荐答案

TL; DR摘要:您需要进行while循环

您的钩子脚本(假设为sh/bash)应包含以下形式的循环:

TL;DR summary: you need a while loop

Your hook script (assuming sh/bash) should include a loop of the form:

while read localname localhash remotename remotehash; do
    ... code here using $localname etc ...
done

说明

the githooks页面中描述了所有Git挂钩. pre-push 挂钩描述始于:

此钩子由 git push 调用,可用于防止进行推送.该挂钩由两个参数调用,这些参数提供目标远程服务器的名称和位置,如果未使用命名远程服务器,则两个值将相同.

This hook is called by git push and can be used to prevent a push from taking place. The hook is called with two parameters which provide the name and location of the destination remote, if a named remote is not being used both values will be the same.

钩子的标准输入上提供了有关要推送的内容的信息,格式为:

Information about what is to be pushed is provided on the hook’s standard input with lines of the form:

<local ref> SP <local sha1> SP <remote ref> SP <remote sha1> LF

例如,如果运行命令 git push origin master:foreign ,则该钩子将收到类似以下内容的行:

For instance, if the command git push origin master:foreign were run the hook would receive a line like the following:

refs/heads/master 67890 refs/heads/foreign 12345

尽管将提供完整的40个字符的SHA-1....

although the full, 40-character SHA-1s would be supplied. ...

第一段意味着在shell脚本中, $ 1 $ 2 是远程服务器的名称(例如 origin )及其名称.URL,或者如果用户运行,则URL重复两次:

The first paragraph means that in a shell script, $1 and $2 are the name of the remote—e.g., origin—and its URL, or the URL repeated twice if the user ran:

git push https://some.host.name/some/path ...

第二段是重要. git push 命令可以将个分支推入多个.例如,我可以运行:

The second paragraph is important. A git push command can push more than one branch. For instance, I can run:

git push origin feature-A feature-B

同时按下 feature-A feature-B .您必须一次阅读所有输入行,以发现要推送的内容.存储库中的 current 分支并不重要:读取 HEAD 会给您错误的答案除非用户碰巧按下了当前分支.另一方面,大多数用户大多只是推送当前分支.这会给您一种错觉,即您的钩子实际上是92.37%时是100%可靠的. 1

to push both feature-A and feature-B. You must read all input lines, one line at a time, to discover what is to be pushed. The current branch in the repository is not important: reading HEAD will give you the wrong answer unless the user happens to be pushing the current branch. On the other hand, most users mostly just push the current branch. This will give you the illusion that your hook is 100% reliable, when it's actually only 92.37% reliable.1

如文档所述,该钩子获取每个引用的全名.如果您要推送分支,则全名以 refs/heads/开头,但是您可以推送标签,在这种情况下,全名以 refs/tags/开头.要编写可靠的钩子,您必须检查全名,而不是简单地剥离前两个组件. 2

As the documentation notes, the hook gets the full name of each reference. If you are pushing a branch, that full name starts with refs/heads/, but you can push a tag, in which case the full name starts with refs/tags/. To write a reliable hook, you must inspect the full name, rather than simply stripping off the first two components.2

1 就像统计数据的38.61%一样,它是在现场弥补的.:-)

1Like 38.61% of statistics, this one was made up on the spot. :-)

2 那里有很多不好的示例钩子(不是全部都是预推钩子),它们使用:

2There are a lot of bad sample hooks (not all of them pre-push hooks) out there that use:

branch=$(echo $ref | cut -d/ -f3)

如果您要推送标记 v2.3 ,则此挂钩将认为您正在推送名为 v2.3 分支.如果您正在推送名为 bugfix/1234 的分支,它将认为您正在推送名为 bugfix 的分支! cut 技术是错误的,但是后者的快速解决方案是使用 -f3-,它至少会产生 bugfix/1234 .最好验证参考的第一部分,即执行以下操作:

If you are pushing tag v2.3, this hook will think you are pushing a branch named v2.3. If you are pushing a branch named bugfix/1234, it will think you are pushing a branch named bugfix! The cut technique is just wrong, but a quick fix for the latter is to use -f3-, which at least produces bugfix/1234. It's better to verify the first components of the ref—i.e., do something like:

case $ref in
refs/heads/*) ... it's a branch ...;;
refs/tags/*) ... it's a tag ...;;
*) ... it's something else entirely, such as refs/notes/* ...;;
esac

一旦知道了前缀,就可以使用 $ {ref#refs/heads/} $ {ref#refs/tags/} 剥离已知的前缀前缀并获取完整但不合格的分支或标记名称.不过,如果有很多情况,您可以直接使用完整的参考名称.

Once you know the prefix, you can use ${ref#refs/heads/} or ${ref#refs/tags/} to strip off the known prefix and get the full but unqualified branch or tag name. If many cases, though, you can just work directly with the full reference name.

这篇关于在预推钩中,获得"git push"按钮.命令全部内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆