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

时间:2009-01-09 06:05:57

标签: git githooks

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

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

14 个答案:

答案 0 :(得分:164)

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

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

git config core.hooksPath hooks

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

答案 1 :(得分:132)

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

要在* nix上执行符号链接,您只需要:

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

如果您准备覆盖ln -sf

中的内容,请使用.git/hooks

答案 2 :(得分:11)

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

答案 3 :(得分:4)

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

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

答案 4 :(得分:4)

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

<强>示例:

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

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

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

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

答案 7 :(得分:1)

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

答案 8 :(得分:1)

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

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

它不会取代您所有的钩子,但可以帮助开发人员使用最明显的钩子,而无需在每个钩子上安装钩子的配置 开发人员计算机/存储库。

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

答案 9 :(得分:1)

对于gradle用户

我发现these scripts对于gradle项目非常有用。

build.gradle

apply from: rootProject.file('gradle/install-git-hooks.gradle')

gradle / install-git-hooks.gradle

tasks.create(name: 'gitExecutableHooks') {
    doLast {
        Runtime.getRuntime().exec("chmod -R +x .git/hooks/");
    }
}
task installGitHooks(type: Copy) {
    from new File(rootProject.rootDir, 'pre-commit')
    into { new File(rootProject.rootDir, '.git/hooks') }
}
gitExecutableHooks.dependsOn installGitHooks
clean.dependsOn gitExecutableHooks

预提交

.... your pre commit scripts goes here

答案 10 :(得分: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检查,例如,只需调用commit和push触发器即可。可以解决上述问题。
  • 调用外部工具,例如减价验证器或YAML验证器。您可以进行系统调用,并且需要处理STDOUT和STDERR。
  • 确保所有开发人员都有一种简单的安装钩子的方法,因此需要向存储库中添加漂亮的脚本,以使用正确的钩子替换默认钩子。
  • 拥有一些全局助手,例如检查阻止开发和掌握分支的提交,而不必将其添加到每个存储库中。您可以通过使用具有全局脚本的另一个存储库来解决它。

这可以更简单吗?

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

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

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

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

答案 11 :(得分:0)

对于 Nodejs 用户,一个简单的解决方案是使用

更新 package.json
{
  "name": "name",
  "version": "0.0.1",
  ......
  "scripts": {
    "preinstall": "git config core.hooksPath hooks", 

预安装将在

之前运行
  

npm安装

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

想象一下Maven和其他构建工具将具有与 preinstall 等效的功能。

它也应该可以在所有平台上使用。

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

答案 12 :(得分:0)

我想将多个答案合二为一。假设您位于 project/ 目录中:

设置自定义挂钩

  1. 创建 .githooks 目录并将钩子放入其中。 (有关示例,请参阅 .git/hooks

  2. 创建一个指向目录 ¹.gitconfig 文件:

    git config -f .gitconfig core.hooksPath .githooks
    
  3. 在您的 Makefile 中创建以下规则:²

    enable-git-hooks:
        git config --local include.path ../.gitconfig
        $(warning REMEMBER, YOU MUST HAVE REVIEWED THE CUSTOM HOOKS!)
    

启用您的自定义挂钩

每个开发者都应该explicitly enable these custom hooks after reviewing them。在你的自述文件中添加一个指令,类似这样:

<块引用>

在通过 make enable-git-hooks 查看后启用自定义钩子。

答案 13 :(得分:0)

我目前正在我们的代码库中处理这个问题,我发现了一个名为 husky 的库,它简化了如何在您的团队中使用和共享 GitHub Hooks。我强烈建议您对此进行调查。