可以将Git钩子脚本与存储库一起管理吗?

问题描述 投票:264回答:11

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

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

git githooks
11个回答
133
投票

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

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

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

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


0
投票

理想情况下,如果您按照示例文件,钩子是用bash编写的。但是你可以用任何可用的语言编写它,并确保它具有可执行标志。

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

两个选项

a)多脚本

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

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

b)单脚本

一个更酷的选择是只添加一个脚本来统治它们,而不是几个。所以,你创建一个hooks / mysuperhook.go并指出你想拥有的每一个钩子。

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

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

然后?

然后,您可能希望获得更多功能,例如:

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

这可以更简单吗?

是的,有几个工具可以帮助您管理git-hooks。它们中的每一个都是针对从不同角度解决问题而量身定制的,您可能需要了解所有这些问题才能获得最适合您或您团队的问题。 GitHooks.com提供了许多关于挂钩的阅读,以及今天提供的几种工具。

截至今天,有21个项目列出了不同的策略来管理git钩子。有些只针对单个钩子,有些针对特定语言,等等。

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

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


0
投票

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

{
  "name": "name",
  "version": "0.0.1",
  ......
  "scripts": {
    "preinstall": "git config core.hooksPath hooks", 

预安装将在之前运行

npm安装

并重定向git以查找。\ hooks(或您选择的任何名称)目录中的钩子。该目录应该根据文件名(减去.sample)和结构来模仿。\ .git \ hooks。

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

它也适用于所有平台。

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


169
投票

Git 2.9中,配置选项core.hooksPath指定了一个自定义钩子目录。

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

git config core.hooksPath hooks

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


11
投票

如果你的项目是一个JavaScript项目并且使用npm作为包管理器,你可以使用shared-git-hooksnpm install上强制执行githooks。


4
投票

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

还有很多功能可以让您最大限度地减少复制和符号链接挂钩。


4
投票

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

例子:

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

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


2
投票

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

请注意,这不是一般解决方案,因为某些项目当然无需构建。


1
投票

您可以将您的hooks文件夹设置为另一个git存储库并将其作为子模块链接...我认为只有当您有很多成员和钩子定期更改时才值得。


1
投票

您可以使用托管解决方案进行预提交钩子管理,如pre-commit。或者像Datree.io这样的服务器端git-hook的集中式解决方案。它有内置的政策,如:

  1. 检测并预防merging of secrets
  2. 强制适当的Git user configuration
  3. 强制执行Jira ticket integration - 在提取请求名称/提交消息中提及票号。

它不会取代你所有的钩子,但它可能会帮助你的开发人员使用最明显的钩子,而不需要在每个开发人员的计算机/ repo上安装钩子。

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.