You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在组织内前置校验Git Commit Message格式,阻止不合规提交?

全场景Git Commit Message 前置校验方案

我来给你一套完整的解决方案,完美覆盖你提到的三种提交到master/main分支的场景,全程做前置拦截,彻底避免事后校验的尴尬。

1. 本地提交与推送的前置拦截(覆盖场景1、2)

首先从源头卡住,确保开发者在本地就没法提交或推送不符合格式的内容。

a. commit-msg钩子:拦截所有本地提交

创建项目根目录下的.githooks/commit-msg文件(把钩子放到项目仓库里,方便团队共享),内容如下:

#!/bin/sh

# 定义你要求的校验正则
VALIDATION_PATTERN='^\[[A-Z]{2}-[0-9]{5,7}\]\-.+'

# 读取当前提交的message内容
COMMIT_CONTENT=$(cat "$1")

# 校验格式
if ! echo "$COMMIT_CONTENT" | grep -qE "$VALIDATION_PATTERN"; then
    echo "❌ 提交信息不符合规范!"
    echo "要求格式示例:[PRO-123456] 修复用户中心加载缓慢问题"
    echo "正则规则:$VALIDATION_PATTERN"
    exit 1
fi

给文件加执行权限:chmod +x .githooks/commit-msg

然后让团队所有成员都能自动用上这个钩子:在项目根目录执行git config core.hooksPath .githooks,并把.githooks目录和.git/config的修改提交到仓库,新克隆项目的成员只需要执行一次这个config命令就能生效(也可以写个初始化脚本自动处理)。

b. pre-push钩子:拦截违规内容推送到远程

防止有人用--no-verify绕过commit钩子后推送,所以加个推送前的校验,检查要推送到master/main的所有提交是否合规。

创建.githooks/pre-push文件:

#!/bin/sh

# 只针对master/main分支做校验
TARGET_BRANCH=$(echo "$2" | awk -F '/' '{print $NF}')
if [ "$TARGET_BRANCH" != "master" ] && [ "$TARGET_BRANCH" != "main" ]; then
    exit 0
fi

VALIDATION_PATTERN='^\[[A-Z]{2}-[0-9]{5,7}\]\-.+'

# 获取要推送的所有提交的message
COMMIT_LIST=$(git log --pretty=format:"%B" "$1..HEAD")

# 逐个校验
while IFS= read -r MSG; do
    if ! echo "$MSG" | grep -qE "$VALIDATION_PATTERN"; then
        echo "❌ 要推送的提交中有不符合格式的信息!"
        echo "违规内容:$MSG"
        echo "要求格式示例:[PRO-123456] 修复用户中心加载缓慢问题"
        exit 1
    fi
done <<< "$COMMIT_LIST"

同样加执行权限:chmod +x .githooks/pre-push,并提交到仓库。

2. GitHub PR合并的前置校验(覆盖场景3,核心解决痛点)

这部分是关键,要让PR在合并前就完成校验,而不是合并后CI才报错。我们用GitHub原生的分支保护规则+Actions来实现:

步骤1:配置分支保护规则

  1. 打开GitHub仓库的「Settings」→「Branches」→「Branch protection rules」
  2. 新建规则,选择master/main分支:
    • 勾选「Require pull request reviews before merging」(可选,但建议开启,加强代码审核)
    • 勾选「Require status checks to pass before merging」
    • 后面创建的Actions任务会出现在「Status checks that are required」列表里,到时选中它
    • 务必勾选「Do not allow bypassing the above settings」,强制所有人遵守(包括管理员)

步骤2:创建GitHub Action工作流

在仓库的.github/workflows/commit-message-check.yml创建文件:

name: 提交信息格式校验

on:
  pull_request:
    branches: [master, main]
    types: [opened, synchronize, reopened]

jobs:
  lint-commit-messages:
    runs-on: ubuntu-latest
    steps:
      - name: 拉取代码
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # 必须拉取完整历史,才能检查PR里的所有提交

      - name: 校验所有提交信息
        run: |
          VALIDATION_PATTERN='^\[[A-Z]{2}-[0-9]{5,7}\]\-.+'
          # 获取PR中所有新增提交的message
          PR_COMMITS=$(git log --pretty=format:"%B" "${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}")
          
          # 逐个检查
          while IFS= read -r COMMIT_MSG; do
              if ! echo "$COMMIT_MSG" | grep -qE "$VALIDATION_PATTERN"; then
                  echo "::error::提交信息不符合规范!"
                  echo "::error::违规内容:$COMMIT_MSG"
                  echo "::error::要求格式示例:[PRO-123456] 修复用户中心加载缓慢问题"
                  exit 1
              fi
          done <<< "$PR_COMMITS"

这个工作流会在PR打开、新增提交(同步)、重新打开时自动触发,只有所有提交信息都合规,PR才能被合并,完全实现前置拦截。

3. 额外小贴士:处理历史违规提交

如果仓库已经有不符合格式的历史提交,可以用git filter-repo批量修改(谨慎操作,会重写历史,需要团队统一执行):

git filter-repo --message-callback '
import re
# 这里根据实际需求替换,比如给无格式的提交加上默认前缀
pattern = re.compile(r"^.*$")
new_message = re.sub(r"^", "[FIX-000000]-", message)
return new_message
'

这样三个场景就全部覆盖了:

  • 场景1:本地master提交后推送 → commit-msg+pre-push双重拦截
  • 场景2:本地分支提交后合并到master再推送 → commit-msg拦截分支提交,pre-push拦截推送
  • 场景3:PR合并 → GitHub Action前置校验,不通过无法合并

内容的提问来源于stack exchange,提问作者JAR.JAR.beans

火山引擎 最新活动