企业项目管理、ORK、研发管理与敏捷开发工具平台

网站首页 > 精选文章 正文

探索 Git 钩子(git钩子函数)

wudianyun 2025-01-27 00:38:55 精选文章 24 ℃

Git钩子 能在特定的动作发生时触发自定义脚本。Git钩子分为客户端钩子和服务器端钩子。

安装一个钩子

钩子都被存储在项目中的 .git/hooks 下。 当你用 git init 初始化一个新版本库时,Git 默认会在这个目录中放置一些示例脚本。 这些示例的名字都是以 .sample 结尾,如果你想直接启用它们,先移除这个后缀,即可激活该钩子脚本,这样一来,它就能被 Git 调用。

客户端钩子

1.pre-commit

该钩子脚本由git commit命令调用,你可以用它来执行一系列检查或任务,确保代码在提交到仓库之前符合某些标准或条件。可以向该脚本传递--no-verify参数来跳过校验。该脚本在获取提交说明之前运行。如果该脚本运行失败(返回非零值),Git 将放弃此次提交。

pre-commit 钩子非常适合用来运行自动化测试、格式化代码、静态分析工具、检查代码风格等。这样可以保证只有符合质量标准的代码才能被提交到仓库中。

#!/bin/sh
# .git/hooks/pre-commit

# 运行代码格式化检查器(如 Prettier, ESLint 等)
# 如果你有多个命令要运行,可以在每条命令后加上 '&&' 来连接它们。
# 如果任一命令失败,整个脚本将返回一个非零状态码,从而阻止提交。
echo "Running pre-commit checks..."

# 例如,假设你使用的是 ESLint 来检查 JavaScript 文件的代码风格:
if ! eslint --quiet --ignore-path .gitignore .; then
    echo "ESLint found issues. Please fix them before committing."
    exit 1
fi


# 如果所有检查都通过,则允许提交继续
echo "All checks passed!"
exit 0


2.commit-msg

钩子接收一个参数,此参数即上文提到的,存有当前提交信息的临时文件的路径。如果该脚本运行失败,Git 将放弃提交,可以用来在提交通过前验证项目状态或提交信息。

#!/bin/sh
# .git/hooks/commit-msg

# 获取提交信息
commit_msg_file=$1
commit_msg=$(cat $commit_msg_file)

# 定义正则表达式模式来匹配"[任务号]: 描述"
pattern="^\\[[0-9]+\\]: .+#34;

# 检查提交信息是否匹配模式
if ! [[ $commit_msg =~ $pattern ]]; then
    echo "提交信息格式错误:应为 [任务号]: 描述"
    exit 1 # 返回非零状态码以取消提交
fi
# 返回零状态码表示成功
exit 0

当我使用 git commit -m "1234" 提交到本地仓库时,报错:提交信息格式错误:应为 [任务号]: 描述


当我使用 git commit -m "[1535]: 新增初始化描述信息" 提交到本地仓库时,提交成功。

钩子示例

以下为.git/hooks目录下部分钩子示例

applypatch-msg.sample

#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}

commit-msg.sample

#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}

pre-commit.sample

#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}

pre-merge-commit.sample

#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git merge" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message to
# stderr if it wants to stop the merge commit.
#
# To enable this hook, rename this file to "pre-merge-commit".

. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
        exec "$GIT_DIR/hooks/pre-commit"
:

官方钩子说明

如果想查看全部的钩子说明可去官方第8.3章节学习:Git - Git 钩子

最近发表
标签列表