发布于 2026-01-06 2 阅读
0

使用 Git Hooks 简化您的开发工作流程

使用 Git Hooks 简化您的开发工作流程

Git hooks 允许我们在 Git 仓库中发生某些重要事件(例如提交、推送、合并)时运行自定义脚本。Git hooks 基本上存储在本地仓库的 .git/hook 目录中。

最初,所有钩子文件都以 .sample 为扩展名,这表示这些钩子文件处于禁用状态。这些示例钩子文件会根据您的操作系统存储在以下位置之一:

  • Linux:/usr/share/git-core/templates

  • Windows:C:\Program Files\Git\mingw64\share\git-core\templates

  • Mac OS:/usr/local/git/libexec/git-core

每当您初始化本地 git 仓库时,这些已存储在您计算机上的示例钩子模板都会被复制到您的本地仓库中。

所有以 pre 标签开头的 hook 都会在特定事件发生之前执行,而所有以 post 标签开头的 hook 都会在特定事件发生之后执行。

例如:pre-push hook 将在 push 操作之前执行。

由于钩子函数默认处于禁用状态,我们需要执行以下步骤来启用它们:

  • 从钩子名称中移除 .sample 后缀。
  • 使用命令 chmod +x 使该 hook 文件可执行。

开始之前请记住这一点:

  • 我们可以看到,这些 hooks 位于 .git/hook/ 目录下,这意味着它们没有被纳入版本控制系统。你可以使用符号链接。
  • 您可以通过添加 --no-verify 标志来绕过本地的 pre-commit git hook。

让我们先从git hooks的实际应用开始。

场景 1:在某个项目中,我们习惯从环境分支(master、dev、release)创建特性分支。我们不应该直接将代码提交到环境分支上。

解决方案: pre-commit hook 会首先运行,所以我们将使用这个 hook。将以下代码片段复制到你的 pre-commit hook 中。

#!/bin/sh
# Avoid doing commit in environment branches.


BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
forbidden_branchs="^(master|dev|release)$"


message="You should not commit directly into ${BRANCH_NAME} branch.\nPlease create a new branch from '$BRANCH_NAME' and Try again."


if [[ $BRANCH_NAME =~ $forbidden_branchs ]]
then
    echo -e $message
    exit 1
fi
Enter fullscreen mode Exit fullscreen mode

在 Windows 操作系统中,不要使用#!bin/sh,而应使用#!C:\Program Files\Git\bin\sh.exe,即 Git 安装其 shell 脚本的路径。

现在,Git 允许您自由选择脚本语言。如果您熟悉其他脚本语言,例如 Python、Ruby 或 PowerShell,只需在钩子的第一行添加其库的路径即可。

请记住,如果钩子函数返回零,则表示成功;如果返回其他任何数字,则表示失败。在上面的代码片段中,我们返回了退出代码 1,这意味着钩子函数失败,因此不会执行提交操作。

情景二:

有时我们会多次修改提交,在后续阶段我们需要用到之前某个提交的状态。如果我们编写一个脚本,每次提交代码前都创建一个暂存区,那么我们就能获取暂存区中每次提交的状态。

解决方案:

if [[ $(git diff --cached --exit-code) ]];then
  BRANCH_NAME=$(git branch --show-current)
  STASH_NAME="pre-commit-on-$BRANCH_NAME-$(date +"%m-%d-%y::%T")"
  git stash save -q --keep-index $STASH_NAME
  echo "Stash:${STASH_NAME} saved!"       
fi
Enter fullscreen mode Exit fullscreen mode

`git diff --cached --exit-code`将检查暂存区是否存在任何代码。由于空提交运行此代码毫无意义。`git branch --show-current`会显示当前分支名称。
我们将使用相同的 pre-commit 钩子。请在 pre-commit 钩子中添加以下代码行。

情景三:

在将分支推送到远程分支之前,让我们创建一个钩子,该钩子将在将代码推送到远程分支之前执行构建和测试。

解决方案:

我们可以使用 pre-push 或 pre-commit 钩子来应对这种情况。

echo "Running Build"
sh run-test-scripts.sh

if [ $? -ne 0 ]; then
  echo "Build must be succeed before commit!"
  exit 1
fi
Enter fullscreen mode Exit fullscreen mode

这里,$?存储了最后一个命令的退出值。在 run-test-scripts.sh 文件中添加测试用例和构建命令。您可以使用此钩子进行自动代码质量检查。

如何部署这些 Git 钩子?

由于 Git Hooks 存储在 `.git/hook` 目录中,开发人员无法提交这些 Hooks。我们将在代码库中创建自己的 `.githooks` 目录。我们将把创建的 Hooks 复制到这个新创建的目录中,并确保正确设置文件的权限。

chmod a+x ~/.githooks/pre-commit

完毕!

还有另一种方法,从 Git 2.9.0 版本开始,你可以设置`core.hookspath`,这样就可以在你的机器上设置一个全局的 hooks 目录。这样,你所有的本地仓库都会指向这个目录,并使用其中的 hooks。

要设置core.hookspath,请使用以下命令:

git config --global core.hookspath <hooks-directory-path>
Enter fullscreen mode Exit fullscreen mode

注意:请将 hooks 文件夹放在本地仓库之外。否则,如果您出于某种原因删除了本地仓库,您的其他项目将无法访问这些 hooks。

有了 Git 钩子,想象力就是极限!你可以在 LinkedIn 上找到我的原文(这里)。

如果这篇文章对您有用,请告诉我。祝您
编程愉快!

文章来源:https://dev.to/rajhawaldar/use-git-hooks-to-ease-your-development-workflow-2ijh