关于githooks:可以与存储库一起管理Git hook脚本吗?

Can Git hook scripts be managed along with the repository?

我们想制作一些我们可以共享的基本钩子脚本-用于诸如预格式化提交消息之类的事情。 Git的钩子脚本通常存储在/.git/hooks/下。 但是,当人们进行克隆时,这些脚本不会传播,并且不受版本控制。

有没有一种好的方法可以帮助每个人获得正确的钩子脚本? 我可以仅使这些挂钩脚本指向我的存储库中的版本控制脚本吗?


在Git 2.9中,
配置选项core.hooksPath指定自定义的挂钩目录。

将挂钩移动到存储库中hooks跟踪的目录中。然后,将存储库的每个实例配置为使用跟踪的hooks而不是$GIT_DIR/hooks

1
git config core.hooksPath hooks

通常,路径可以是绝对路径,也可以是相对于运行挂钩的目录的路径(通常是工作树的根;请参见man githooks的DESCRIPTION部分)。


从理论上讲,您可以使用所有脚本在项目目录中创建一个hooks目录(或您喜欢的任何名称),然后在.git/hooks中将它们符号链接。当然,每个克隆该存储库的人都必须设置这些符号链接(尽管您可能真的很喜欢,并且拥有一个部署脚本,克隆程序可以运行该脚本来半自动设置它们)。

要在* nix上执行符号链接,您需要做的是:

1
2
root="$(pwd)"
ln -s"$root/hooks""$root/.git/hooks"

如果您准备覆盖.git/hooks中的内容,请使用ln -sf


如果您的项目是JavaScript项目,并且您使用npm作为程序包管理器,则可以使用shared-git-hooks在npm install上实施githooks。


大多数现代编程语言,或者更确切地说,它们的构建工具,都支持管理git hook的插件。这意味着您只需要配置package.json,pom.xml等,团队中的任何人就别无选择,除非他们更改构建文件。
该插件将为您添加内容到.git目录。

例子:

https://github.com/olukyrich/githook-maven-plugin

https://www.npmjs.com/package/git-hooks


git-hooks怎么样,它将.git/hooks调用路由到项目目录githooks下的脚本中。

还有很多功能可以使您在各处最小化复制和符号链接挂钩。


我们正在使用具有生成前和生成后事件的Visual Studio解决方案(以及项目)。我要添加一个名为" GitHookDeployer"的附加项目。项目自行在发布后事件中修改文件。该文件设置为复制到构建目录。因此,项目每次都会构建,并且永远不会被跳过。在构建事件中,它还确保所有git钩子都到位。

请注意,这不是一个通用的解决方案,因为某些项目当然没有任何建置。


对于Nodejs用户,一个简单的解决方案是使用以下命令更新package.json

1
2
3
4
5
6
{
 "name":"name",
 "version":"0.0.1",
  ......
 "scripts": {
   "preinstall":"git config core.hooksPath hooks",

预安装将在

npm install

并重定向git在。 hooks(或您选择的任何名称)目录内查找挂钩。该目录应在文件名(减去.sample)和结构方面模仿。。git hooks。

想象一下,Maven和其他构建工具将具有等同于预安装的功能。

它也应该在所有平台上工作。

如果您需要更多信息,请参见https://www.viget.com/articles/two-ways-to-share-git-hooks-with-your-team/


您可以使用托管解决方案进行预提交挂钩管理,如预提交。
或针对服务器端git-hooks(如Datree.io)的集中式解决方案。
它具有内置策略,例如:

  • 检测并防止机密合并。
  • 强制执行正确的Git用户配置。
  • 强制执行Jira票证集成-在请求请求名称/提交消息中提及票证编号。
  • 它不会取代您所有的钩子,但是可以帮助开发人员使用最明显的钩子,而无需在每个钩子上安装钩子
    开发人员计算机/仓库。

    免责声明:我是Datrees创始人之一


    您可以将您的hooks文件夹设为另一个git存储库,并将其链接为子模块...
    我猜只有在您定期更改很多成员和挂钩的情况下才值得。


    理想情况下,如果遵循示例文件,则钩子将以bash编写。但是您可以用任何可用的语言编写它,只需确保它具有可执行标志。

    因此,您可以编写Python或Go代码以实现您的目标,并将其放在hooks文件夹下。它将起作用,但将不会与存储库一起进行管理。

    两种选择

    a)多脚本

    您可以在帮助中编写钩子代码,并在钩子中添加一小段代码,以调用完美的脚本,如下所示:

    1
    2
    3
    $ cat .git/hooks/pre-commit
    #!/bin/bash
    ../../hooks/myprecommit.js

    b)单个脚本

    一个比较酷的选择是仅添加一个脚本来统治所有脚本,而不是多个脚本。因此,您创建了一个hooks / mysuperhook.go并指向您想要的每个钩子。

    1
    2
    3
    $ cat .git/hooks/pre-commit
    #!/bin/bash
    ../../hooks/mysuperhook.go $(basename $0)

    该参数将为您的脚本提供触发了哪个挂钩,并且您可以在代码中对其进行区分。为什么?例如,有时您可能想对提交和推送运行相同的检查。

    接着?

    然后,您可能需要更多功能,例如:

    • 手动触发该钩子,以检查是否在提交或推送之前一切正常。如果只调用脚本(选项a或b),就可以解决问题。
    • 在CI上触发钩子,因此您不需要重写相同的CI检查,例如,只需调用commit和push触发器即可。与上述相同应解决。
    • 调用外部工具,例如降价验证器或YAML验证器。您可以进行系统调用,并且需要处理STDOUT和STDERR。
    • 确保所有开发人员都有安装钩子的简单方法,因此需要向存储库中添加漂亮的脚本,以将正确的钩子替换为默认钩子
    • 有一些全局助手,例如检查阻止开发和掌握分支的提交,而不必将其添加到每个存储库中。您可以通过使用具有全局脚本的另一个存储库来解决它。

    这可以更简单吗?

    是的,有几种工具可以帮助您管理git-hook。他们每个人都是量身定制的,以从不同的角度解决问题,您可能需要了解所有这些因素,才能找到最适合您或您的团队的东西。 GitHooks.com提供了大量有关钩子的信息,并且提供了许多可用的工具。

    截至今天,这里列出了21个项目,这些项目采用不同的策略来管理git hooks。有些仅针对单个钩子执行此操作,某些仅针对特定语言执行此操作,依此类推。

    由我编写并作为一个开源项目免费提供的那些工具之一称为hooks4git。它是用Python编写的(因为我喜欢它),但是它的想法是在一个名为.hooks4git.ini的配置文件中处理上面列出的所有项目,该文件位于您的存储库中,并且可以用任何语言调用您要调用的任何脚本。 。

    使用git hooks绝对是太棒了,但是提供它们的方法通常只会使人们远离它。


    pre-commit使预提交挂钩变得容易。没有回答OP有关管理任意git钩子的问题,但是预提交钩子可能是最常用于代码质量目的的钩子。