本文目录导读:

Git钩子脚本验证作者邮箱的典型方法是使用commit-msg或pre-commit钩子,以下是几种实现方式:
使用 commit-msg 钩子(推荐)
在 .git/hooks/commit-msg 中:
#!/bin/sh
# 获取作者邮箱
AUTHOR_EMAIL=$(git log -1 --format='%ae' HEAD)
# 或使用: AUTHOR_EMAIL=$(git config user.email)
# 允许的邮箱域名
ALLOWED_DOMAIN="@company.com"
# 邮箱验证规则(正则)
EMAIL_PATTERN="[a-zA-Z0-9._%+-]+@company\\.com$"
if ! echo "$AUTHOR_EMAIL" | grep -qE "$EMAIL_PATTERN"; then
echo "错误:作者邮箱 '$AUTHOR_EMAIL' 不符合要求"
echo "请使用公司邮箱: example@company.com"
exit 1
fi
# 也可以直接检查特定邮箱
FORBIDDEN_EMAILS=("test@test.com" "noreply@github.com")
for email in "${FORBIDDEN_EMAILS[@]}"; do
if [ "$AUTHOR_EMAIL" = "$email" ]; then
echo "错误:禁止使用邮箱 $email"
exit 1
fi
done
exit 0
使用 pre-commit 钩子
在 .git/hooks/pre-commit 中:
#!/bin/sh
# 获取暂存区的作者邮箱(即将提交的作者)
AUTHOR_EMAIL=$(git var GIT_AUTHOR_IDENT | sed 's/.*<\([^>]*\)>.*/\1/')
# 验证邮箱格式
if [[ ! "$AUTHOR_EMAIL" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "错误:邮箱格式不正确:$AUTHOR_EMAIL"
exit 1
fi
# 验证域名白名单
ALLOWED_DOMAINS=("@company.com" "@company.cn")
VALID=false
for domain in "${ALLOWED_DOMAINS[@]}"; do
if [[ "$AUTHOR_EMAIL" == *"$domain" ]]; then
VALID=true
break
fi
done
if [ "$VALID" = false ]; then
echo "错误:邮箱域名不允许:$AUTHOR_EMAIL"
echo "允许的域名:${ALLOWED_DOMAINS[*]}"
exit 1
fi
exit 0
高级版本(支持邮件列表和通配符)
#!/bin/sh
commit_email_hook() {
AUTHOR_EMAIL=$(git log -1 --format='%ae' HEAD 2>/dev/null || git config user.email)
if [ -z "$AUTHOR_EMAIL" ]; then
echo "错误:无法获取作者邮箱"
exit 1
fi
# 邮箱白名单(支持通配符)
WHITELIST=(
"*@company.com"
"*@company.com.cn"
"admin@project.com"
"*-bot@company.com"
)
# 邮箱黑名单
BLACKLIST=(
"test@test.com"
"root@localhost"
)
# 检查黑名单
for black_email in "${BLACKLIST[@]}"; do
if [ "$AUTHOR_EMAIL" = "$black_email" ]; then
echo "错误:邮箱 $AUTHOR_EMAIL 在黑名单中"
exit 1
fi
done
# 检查白名单
MATCHED=false
for pattern in "${WHITELIST[@]}"; do
# 将通配符转换为正则
regex=$(echo "$pattern" | sed 's/\*/.*/g')
if echo "$AUTHOR_EMAIL" | grep -qE "^${regex}$"; then
MATCHED=true
break
fi
done
if [ "$MATCHED" = false ]; then
echo "错误:邮箱 $AUTHOR_EMAIL 不在白名单中"
echo "允许的模式:${WHITELIST[*]}"
exit 1
fi
echo "邮箱验证通过:$AUTHOR_EMAIL"
exit 0
}
commit_email_hook
Git配置方式(无需脚本)
在 .git/config 中添加:
[user]
email = yourname@company.com
然后配合 pre-receive 钩子(服务端):
#!/bin/bash
# 在服务端 .git/hooks/pre-receive
while read oldrev newrev refname; do
# 获取每个提交的作者邮箱
for commit in $(git rev-list $oldrev..$newrev); do
author_email=$(git log -1 --format='%ae' $commit)
if [[ ! "$author_email" =~ @company\.com$ ]]; then
echo "拒绝推送:提交 $commit 的作者邮箱 '$author_email' 无效"
exit 1
fi
done
done
exit 0
使用注意事项
-
权限设置:钩子脚本需要可执行权限
chmod +x .git/hooks/commit-msg
-
全局部署:使用
git config core.hooksPath可以设置全局钩子目录git config --global core.hooksPath /path/to/global/hooks
-
跳过钩子:紧急情况可以跳过
git commit --no-verify
-
错误提示:友好提示用户如何设置正确的邮箱
echo "请设置正确的邮箱:git config user.email 'yourname@company.com'"
-
测试:验证钩子是否生效
GIT_AUTHOR_EMAIL="test@invalid.com" git commit --allow-empty -m "test"
这些脚本可以根据实际需求调整正则表达式和验证规则,建议同时配合服务端钩子防止绕过。