本文目录导读:

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"
这些脚本可以根据实际需求调整正则表达式和验证规则,建议同时配合服务端钩子防止绕过。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播