0


Git技巧:Pre-commit

文章目录

引言

在软件开发过程中,保持代码的一致性和高质量是非常重要的。

pre-commit

是一个强大的工具,它可以帮助我们在提交代码到版本控制系统(如 Git)之前自动运行一系列的代码检查和格式化操作。通过这种方式,我们可以确保每次提交的代码都是干净的、格式化的并且符合项目的编码标准。

本文将详细介绍

pre-commit

的工作原理、如何安装

pre-commit

,如何配置它,并提供一些实用的示例。

什么是 Hook?

在版本控制系统中,hook 是一种脚本,用于在某些事件发生时触发。例如,在 Git 中,你可以设置一个 hook 在提交前运行。

pre-commit

利用了 Git 的这一特性,允许用户定义一组钩子(hook),这些钩子会在提交之前自动执行。

Hook 的类型

pre-commit

支持以下几种类型的 hook:

  • pre-commit:这是最常用的一种 hook,它会在提交之前运行。
  • pre-push:这种 hook 会在 push 操作之前运行。
  • post-merge:这种 hook 会在合并分支之后运行。
  • prepare-commit-msg:这种 hook 会在创建提交信息时运行。

本文主要关注

pre-commit

类型的 hook。

安装

在开始之前,请确保环境中已经安装了 Python 和 Git。通过以下命令安装

pre-commit

pip install pre-commit

配置

一旦安装完成,接下来就是配置

pre-commit

的过程。
首先,在你的项目根目录下创建一个

.pre-commit-config.yaml

文件。
这个文件定义了你的

pre-commit

钩子的行为。

示例配置文件

下面是一个简单的

.pre-commit-config.yaml

文件示例,它包含了几个常用的钩子:

repos:-repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:-id: trailing-whitespace
      -id: end-of-file-fixer
      -id: check-yaml
      -id: debug-statements
  -repo: https://github.com/psf/black
    rev: stable
    hooks:-id: black
  -repo: https://github.com/pycqa/flake8
    rev: 6.0.0
    hooks:-id: flake8

这里,我们定义了四个来自

pre-commit-hooks

仓库的钩子,以及两个分别来自

black

flake8

的钩子。这些钩子的功能分别是:

  • trailing-whitespace: 移除行尾的空白字符。
  • end-of-file-fixer: 确保文件以单个新行结束。
  • check-yaml: 检查 YAML 文件的格式是否正确。
  • debug-statements: 检查 Python 代码中的调试语句(如 print)。
  • black: 自动格式化 Python 代码。
  • flake8: 进行 Python 代码的静态分析和格式检查。

选择 Hook

选择合适的 hook 来满足对应的项目需求

  1. 编程语言规范:选择与项目编程语言兼容的 hook。例如,对于 Python 项目,可以选择 blackflake8
  2. 编码标准:选择符合项目编码标准的 hook。例如,如果项目使用 PEP 8 编码标准,可以使用 flake8
  3. 自动化需求:选择能够自动修复常见错误的 hook。例如,end-of-file-fixer 可以自动添加缺失的新行。

限制 Hook 的作用范围

你可以通过以下方式限制 hook 的作用范围:

  • **使用 types**:限制 hook 应用于特定类型的文件。例如,只对 .py 文件应用 black-repo: https://github.com/psf/black rev: stable hooks:-id: black types:[python]
  • **使用 exclude**:排除特定的文件或目录。例如,不检查 .venv 目录下的文件:-repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks:-id: trailing-whitespace exclude: ^\.venv/
  • **使用 files**:只检查匹配正则表达式的文件。例如,只检查以 test_ 开头的 Python 文件:-repo: https://github.com/psf/black rev: stable hooks:-id: black files: ^test_.*\.py$

安装钩子

创建完配置文件后,需要安装这些钩子才能让它们生效。在项目根目录下运行以下命令:

pre-commit install

这将在你的

.git/hooks

目录下生成一个可执行的

pre-commit

脚本。

如果之后有修改,不需要再次安装,会自动采用最新的yaml或者自定义hooks来运行。

使用 pre-commit

现在当你尝试提交更改时,

pre-commit

自动运行配置好的钩子。如果任何钩子失败,则提交会被阻止,并显示错误信息。

如果你想要手动运行所有的钩子,可以使用以下命令:

pre-commit run --all-files

如果你只想运行特定的一个钩子,可以这样做:

pre-commit run black --files path/to/file.py

自定义 Hook

除了使用已有的 hook 之外,

pre-commit

还允许你定义自己的 hook。例如,假设你有一个 Python 脚本

my_custom_hook.py

,它可以检查文件中的特定模式:

# my_custom_hook.pyimport sys
import re

defmain():
    pattern =r'pattern_to_search'for filename in sys.argv[1:]:withopen(filename,'r')asfile:ifany(re.search(pattern, line)for line infile):print(f"Found pattern in {filename}")return1return0if __name__ =='__main__':
    sys.exit(main())

然后,你可以在

.pre-commit-config.yaml

文件中添加这个自定义钩子:

repos:-repo: local
    hooks:-id: custom-pattern-check
        name: Custom pattern check
        entry: python my_custom_hook.py
        language: system
        files: \.py$

使用了

local

作为 repo,因为这个钩子是直接在项目中定义的。

Eg:commit消息规范

希望每一次commit的message是符合一定的规则的,首先创建一个自定义的hook,写一个python脚本

# commit_message_validator.pyimport sys
import re

defvalidate_commit_message(message):# 第一行以大写字母开头ifnot message.startswith(tuple('ABCDEFGHIJKLMNOPQRSTUVWXYZ')):print("Error: Commit message must start with a capital letter.")returnFalse# 第一行不能超过 50 个字符iflen(message.split('\n')[0])>50:print("Error: The first line must not exceed 50 characters.")returnFalse# 检查是否包含关键字
    valid_types =['feat','fix','docs','style','refactor','perf','test','chore','ci','build','revert']
    type_pattern = re.compile(r'^('+'|'.join(valid_types)+')')ifnot type_pattern.match(message.split(':')[0].split(' ')[0]):print("Error: Commit message should start with one of the following keywords: ",', '.join(valid_types))returnFalsereturnTrueif __name__ =="__main__":
    message = sys.stdin.read().strip()ifnot validate_commit_message(message):
        sys.exit(1)

将该自定义的hook写入到yaml文件中

.pre-commit-config.yaml
repos:-repo: local
    hooks:-id: commit-message-validator
        name: Validate commit messages
        entry: python commit_message_validator.py
        language: system
        files:''stages:[commit-msg]
stages: [commit-msg]

,告诉

pre-commit

这个 hook 应该在

commit-msg

阶段运行,即在提交消息被创建之后,但实际提交还没有发生之前
最后就是安装这一个hook

pre-commit install --hook-type commit-msg

结论

使用

pre-commit

,可以确保每次提交的代码都是高质量的。这也就可以帮助我们避免常见的编码错误,还可以提高团队成员之间的协作效率。
无论你是个人开发者还是团队的一员,

pre-commit

都是一个值得使用的工具。
笔者记录pre-commit的一大原因也是希望能够在笔记本仓库中,规范每次commit message的内容,让commit message起到一个更好的摘要作用。

标签: git

本文转载自: https://blog.csdn.net/Topsort/article/details/140965269
版权归原作者 One_Danzel♂ 所有, 如有侵权,请联系我们删除。

“Git技巧:Pre-commit”的评论:

还没有评论