一个计算机技术爱好者与学习者

0%

好好学Git:Git pre-commit 代码质量检查

1. pre-commit 简介

Git 提供了一种称为钩子(hook)的特性,帮助我们在关键时刻自动执行自定义脚本。
其中,名为 pre-commit 的钩子会在每次 commit 之前运行,能够作为保障代码质量的工具。

2. 使用 pre-commit

在项目的根目录下,找到 .git/hooks 文件夹,这个文件夹中存放的就是各种钩子脚本。

创建一个新文件命名为 pre-commit ,务必不要添加后缀,如 .sh 或 .py。

在 pre-commit 文件中,我们可以添加任何可以执行的脚本。
例如,如果我们针对 Python 的 .py 文件进行检查,则我们可能的 pre-commit 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env bash
FILES_PATTERN='\.(py)(\..+)?$'
FORBIDDEN='pdb.set_trace()'
git diff --cached --name-only | \
while read FILE; do
if [[ "${FILE}" =~ ${FILES_PATTERN} ]]; then
if grep --quiet "${FORBIDDEN}" "${FILE}"; then
echo "${FILE} contains ${FORBIDDEN}"
exit 1
fi
fi
done || exit $?

这个检查脚本的意思是,如果我们的 .py 文件中含有 pdb.set_trace(),那么拒绝该次 commit。

设置完后,我们需要使脚本具有执行权限,使用 chmod +x .git/hooks/pre-commit 命令即可。

之后,每一次的 git commit,在提交之前,都会执行我们定义好的 pre-commit 脚本,保证代码符合我们设置的规范,从而提升代码质量。

3. pre-commit 框架

当我们有大量项目时,pre-commit 脚本的管理维护就变成了一件痛苦的事情。
此时,就需要 pre-commit 框架出马了。pre-commit 框架是一个支持多语言的 pre-commit 脚本的管理器,能够简化我们的 pre-commit 脚本配置。
使用 pre-commit 框架时,在 .pre-commit-config.yaml 配置文件指定所需的linter列表(脚本列表),然后 pre-commit 框架会自动下载这些linter并运行。

需要特别说明的是:一些最好的 linter 可能是项目中不使用的语言编写的。例如 scss-lint 是一个用于检查SCSS的 linter,但是它是用Ruby编写的。而我们使用 pre-commit 框架时,完全不用关心 scss-lint 的安装配置,只要在linter列表中指定使用它即可。

参考文档:

4. 安装 pre-commit 框架

1
pip install pre-commit

5. 使用 pre-commit 框架

1、创建 pre-commit 框架配置文件 .pre-commit-config.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
default_stages: [ commit ]

# Install
# 1. pip install pre-commit
# 2. pre-commit install(the first time you download the repo, it will be cached for future use)
repos:
- repo: https://github.com/pycqa/isort
rev: 5.11.5
hooks:
- id: isort
args: ['--profile', 'black']
exclude: >-
(?x)^(
.*__init__\.py$
)

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.0.284
hooks:
- id: ruff

- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
args: ['--line-length', '120']

2、运行pre-commit框架

1
pre-commit run --all-files

3、配置commit前自动调用pre-commit框架

1
2
3
4
5
6
7
cat <<EOF  > .git/hooks/pre-commit
#!/bin/bash
source $HOME/.bash_profile
pre-commit run --all-files
EOF

chmod a+x .git/hooks/pre-commit

4、测试commit

1
2
3
# modify something
git add .
git commit -m "something"

6. github 配置使用 pre-commit 框架

github actions 中,也可以配置使用 pre-commit 框架,用于检查代码规范。

项目根目录中,新建 .github/workflows/pre-commit.yaml,内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
name: Pre-commit checks

on:
pull_request:
branches:
- '**'
push:
branches:
- '**'

jobs:
pre-commit-check:
runs-on: ubuntu-latest
steps:
- name: Checkout Source Code
uses: actions/checkout@v2

- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: '3.9.17'

- name: Install pre-commit
run: pip install pre-commit

- name: Initialize pre-commit
run: pre-commit install

- name: Run pre-commit hooks
run: pre-commit run --all-files

提交到github,就OK了。

7. 扩展阅读:git hooks

Git钩子是一些在Git执行特定操作时触发的脚本,可以用于自定义和自动化工作流程,不同的Git钩子有不同的调用时间。

客户端钩子:

  • pre-commit:在每次提交之前运行。
  • pre-push:在git push之前运行。
  • post-commit:在每次提交之后运行。
  • post-checkout:在切换分支或检出文件后运行。
  • post-merge:在合并操作完成后运行。

服务器端钩子:

  • pre-receive:在远程仓库接收到推送前运行。
  • update:在远程仓库接收到推送后,对每个要更新的引用(分支或标签)运行一次。
  • post-receive:在远程仓库接收到推送后,对所有要更新的引用运行一次。

每个项目的.git/hooks的目录中,看到这些钩子的官方示例。
示例文件以.sample结尾,去掉.sample后缀可激活该钩子脚本。

参考文档:

  • 本文作者: 好好学习的郝
  • 原文链接: https://www.voidking.com/dev-git-pre-commit/
  • 版权声明: 本文采用 BY-NC-SA 许可协议,转载请注明出处!源站会即时更新知识点并修正错误,欢迎访问~
  • 微信公众号同步更新,欢迎关注~