Git 钩子

已发表: 2022-07-02

Git 是一个强大的版本控制系统,在过去的几篇文章中我们几乎没有触及到它的表面。 今天,我们将看看 Git 可以通过 Git Hooks 为您提供的自动化功能。

当您使用git init命令时,每个存储库都会内置挂钩。 初始化存储库时,您会得到一个隐藏的.git目录,其中有一个名为 hooks 的目录,它将包含您的所有钩子。 打开您方便的任何 git 存储库并使用ls -a查看隐藏目录,然后在您喜欢的代码编辑器中打开它。

首先,您会看到一堆带有.sample文件扩展名的文件。 这些正是他们所说的,您可以在项目中使用的示例脚本。 这些文件被命名为与它们运行的​​钩子相对应。 所以post-commit.samplepost-commit钩子上运行。

你几乎可以使用任何语言来编写一个钩子。 该文件根据文件顶部的 shebang 表示法进行解析。 如果你想使用节点,你会使用#! /usr/bindi/env node #! /usr/bindi/env node ,您的文件将被解析为节点文件。

在我们深入了解 git 钩子可以做什么之前,让我们先看看一些可用的钩子。

Git 钩子的类型

提交工作流挂钩

pre-commit在你输入提交信息之前运行,它可以被git commit --no-verify绕过。

prepare-commit-msg可用于编辑您在提交消息中看到的默认消息。 使用它向开发人员说明他们应该留下什么类型的提交消息。 它还可以用于自动为您自动生成消息的内容,例如合并或自动将问题编号添加到您的提交消息中。

commit-msg可用于验证项目的提交消息。 也许您不希望任何人能够输入简单地说“处理空白”的提交消息。 您可以使用此挂钩来检测单词空格的存在,然后退出并向用户提供警告,告知他们需要更好的提交消息。

post-commit在上面的所有提交钩子之后运行。 对于已提交的通知最有用。

客户端挂钩

post-checkout在您成功运行 git checkout 命令后运行。 如果您在站点上使用了一组大文件,但不希望它们在源代码管理中,您可以使用此命令为您移动文件。

pre-push在任何对象传输到远程存储库之前在 git push 命令期间运行。

服务器挂钩

当客户端将代码推送到远程存储库时, pre-receive运行。 这可用于在您接受推送之前检查正在推送的代码,以确保它符合您项目的标准。

post-receive在您的远程存储库收到更新后运行。 这可用于调用触发部署过程的网络挂钩或通知聊天室已收到提交并准备好进行审查。

上面的许多钩子可以设置为仅在特定分支上运行。 这可能意味着只有在有人将代码推送到应该准备好部署的主分支时才使用post-receive挂钩。 可以通知开发人员列表来审查代码,然后部署它。 这样,您将始终对部署有 2 对眼睛,这可能意味着发现单个开发人员很容易错过的错误。

我跳过了一些可用的钩子,因为我从未见过需要使用它们。 我没有提到的一组钩子是电子邮件工作流钩子。 如果您不通过电子邮件接受代码补丁,那么您可能永远不需要它们。 您可以在文档中找到所有可用的钩子。

在实践中,我使用最多的钩子是:

  • 预提交
  • 预推
  • 提交消息
  • 预收
  • 提交后
  • 接收后

现在让我们用这些钩子做点什么。

使用 WP Cli 和 Git Hooks 激活 WordPress 插件

对于今年的一个客户项目,我正在添加一个商店,并且仍在主站点上执行一些任务。 这意味着主站点没有安装或激活我们的任何 WooCommerce 插件。 我需要在一个分支上开发 WooCommerce 商店,只有在我准备好将其全部上线后,我才想将 WooCommerce 转移到主要分支。

首先,我们需要一个名为 store 的新分支。 我们可以通过使用 git checkout -b store来获得。 这将创建一个新分支并为我们检查它。 现在让我们准备好钩子。

首先,我们需要使用这个命令 touch .git/hooks/post-checkout创建 post-checkout 钩子。

接下来我们需要使其可执行。 我们可以使用终端 chmod +x .git/hooks/post-checkout中的 chmod 命令来执行此操作。

现在在您选择的代码编辑器中打开该文件,并将下面的代码复制到您post-checkout文件中。

#! /bin/bash

wp plugin activate woocommerce

echo "activated WooCommerce"

wp plugin activate automatewoo

echo "activated AutomateWoo"

您可以通过终端更改到任何分支来进行演示。 您应该看到两行告诉您 WooCommerce 和 AutomateWoo 已被激活。 我们知道它正在工作,但它并不是我们想要的,因为它会在我们每次更改到任何分支时打开插件。

我们真正想要的是在我们移动到我们的商店分店时打开它们,然后当我们在我们的主要分店时将它们关闭。 为此,我们需要钩子来检测我们是哪个分支。 用下面的代码交换post-checkout的内容。

#! /bin/bash

oldrev=$1
newrev=$2

branch_name="(git symbolic-ref HEAD 2>/dev/null)"

if [ "refs/head/store" = "$branch_name" ];then
wp plugin activate woocommerce
echo "activated Woo"

wp plugin activate automatewoo
echo "activated AutomateWoo"
fi

if [ "refs/head/main" = "$branch_name" ];then
wp plugin deactivate woocommerce
echo "deactivated Woo"

wp plugin deactivate automatewoo
echo "deactivated AutomateWoo"
fi

这段代码首先将我们要签出的分支分配给branch_name变量。 然后我们有两个 if 语句。 第一个检查我们是否已经搬到商店分店。 如果我们有它使用 WP CLI 来激活 WooCommerce 和 AutomateWoo。

下一个 if 语句检查我们是否在主分支上。 如果是,它将使用 WP CLI 停用插件并在终端中告诉我们有关它的信息。

使用 Git Hooks 控制 Git 工作流

在之前关于 Git 的文章中,我谈到了不同的 Git 工作流程。 挂钩的一个非常常见的用例是阻止任何人直接将代码提交到主分支。 您可以使用挂钩来确保所有代码都从不同的分支合并到主分支。

首先将pre-commit.sample重命名为pre-commit ,然后按照我上面的描述使其可执行。 接下来获取下面的代码并在预提交文件中使用它。

#! /bin/bash

username=$GIT_AUTHOR_NAME
branch="$(git symbolic-ref HEAD 2>/dev/null)"

if [ "$branch" = "refs/heads/main" ]; then
echo "WHOA that was '"${branch}"' you should not do that. Stop doing silly stuff and create your own branch and merge it."
exit 1 # if you remove this it won't block the commit but it will send the message to slack

fi

这会检查我们是否在主分支上,如果是,则停止提交。 然后它会向用户打印一个提醒,他们不应该直接提交到主分支。

请记住,许多地方正在更改为main作为他们的分支。 如果尚未更新,较旧的项目可能需要在此处设置master

您甚至可以更进一步,使用 cURL 访问聊天应用程序的 API,然后公开抱怨有人试图提交 main。

git hooks 的唯一限制是你的想象力。 如果代码中存在 TODO,您可以使用它们来阻止某人提交,或者在文件末尾停止空格。

如果您的工作流程的某些部分是一个持续的绊脚石,请查看钩子以使其自动化,这样您就不必记住了。