Git 将消息 Linting 作为网关提交,而不是在它被推送之后

Git Commit Message Linting as a gateway and not after it was already pushed

我想验证跨组织的特定提交消息结构,我希望它不可能 merge/push 到 master/main 提交 除非消息符合非常特定的格式.

提交消息是通过简单的正则表达式进行检查,预期格式类似于:

\[[A-Z]{2}-(\d){5,7}\]\-(.|\r|\n)*

向 master/main 添加提交有几种方式:

  1. 在 master 上本地提交,推送到远程。
  2. 在分支上本地提交,在本地合并到 master,推送到远程。
  3. 在本地提交到分支,打开拉取请求(github 的情况)从 github UI 合并 PR。 =32=]

我可以很容易地用 git-commit 钩子覆盖 #1 的情况,为了覆盖 2 和 3,我可以使用 CI 挂钩,但这将 事后 例如此时修复提交格式为时已晚。

对于 2,我可能还可以添加一个 pre-push hook,但是对于 3,考虑到操作发生在服务器端,我似乎找不到在提交已经在 master/main 分支上后不会执行 linting 过程的直接解决方案。

使用 GitHub 上的存储库执行此操作的正确方法是为此使用 CI 作业,必要时可能使用机器人进行合并。您可以有效地对存储库施加任何控制的唯一两个地方是 pre-receive 挂钩和 CI 系统,并且 GitHub 不允许您自定义 pre-receive 挂钩超出您存储库中的配置。

在用户端使用钩子很容易绕过并且不是有效的控制。因此,如果您关心提交消息,那么您唯一可以控制它的地方就是使用 CI。 Git FAQ explains why this is the case.

您应该使用 GitHub 设置来保护您的主要分支,并设置选项“合并前需要通过状态检查”。这意味着人们要么需要将他们的更改放在 PR 中并在合并之前通过你的 CI 检查,要么将他们想要推送到主分支的提交推送到临时分支,然后 fast-forward CI 检查通过后的主分支。

如果您希望合并消息也包含特定的字符串,那么您需要让机器人执行所有 PR 合并并负责合并,因为您无法通过 CI 事前检查。

这个问题没有任何其他有效的解决方案:替代方案要么可以被轻易绕过,要么就是无效。要求人们以某种​​方式格式化他们的提交消息并不是特别麻烦,即使在处理 in-progress PR 时也是如此。我曾从事过这样的工作,这不是问题。