# Git Hook
希望在提交代码,推送代码,推送 tag 之前,都对代码进行一些操作。这就设计 git hook,它可以帮我们完成这些东西。
# Pre commit
pre-commit (opens new window) 可以帮我们更方便的设置 git hook
# 定义 hook 在哪些文件变更时跑
pip install identify
pre-comit
使用 identify 对文件类型来过滤,看有没有文件,没有就不执行 hook
# ["file", "non-executable", "python", "text"]
identify-cli a.py
files 和 types 判断是 and 关系。这个例子会匹配到 foo/1.py
但不会匹配 setup.py
.
files: ^foo/
types: [file, python]
# language
- system
- id: "pre-commit"
name: "check run"
entry: "echo run"
language: system
always_run: true
entry 是系统上的执行文件。
- script:
- id: "pre-commit"
name: "check run"
entry: "echo run"
language: system
always_run: true
precommit 会执行相对于 .pre-commit-config.yaml
的 echo 文件。
# 单线程跑 hook
如果希望当前 hook 单线程跑,可以加这个参数。
require_serial: true
# Java pre commit
---
default_stages: [pre-commit]
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.3.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-json
- id: check-merge-conflict
- id: check-symlinks
- id: check-toml
- id: check-yaml
args: ["--allow-multiple-documents"]
exclude: "charts/.*/templates/|helm/templates"
- id: detect-private-key
# - id: forbid-new-submodules
- id: end-of-file-fixer
- id: mixed-line-ending
- id: trailing-whitespace
- repo: https://github.com/syntaqx/git-hooks
rev: '0e275832e1b85f5a430241ab8f56185d5708e264' # gitleaks:allow
hooks:
- id: shellcheck
types: [shell]
# 帮助生成 markdown 文章标题
- repo: https://github.com/thlorenz/doctoc
rev: v2.2.0
hooks:
- id: doctoc
args: [--github, --maxlevel, '4']
exclude: .shared/
- repo: https://github.com/zricethezav/gitleaks
rev: v8.16.0
hooks:
# 插件是否推送了敏感信息到仓库
- id: gitleaks
entry: gitleaks protect --verbose --redact --staged
- repo: https://github.com/jguttman94/pre-commit-gradle
rev: v0.3.0
hooks:
# 推送代码的时候,保证测试都过
- id: gradle-task
name: gradle clean & check
args: [ '-w', --wrapper, 'clean check' ]
stages: [ pre-push ]
- repo: local
hooks:
# commit message
- id: commit-message-format-check
name: commit message format check
entry: ./commit-msg.sh
always_run: true
language: script
stages: [commit-msg]
# Hooks
# Commit message
#!/bin/bash
set -eo pipefail
RED='\033[0;31m'
Green='\033[0;32m'
NC='\033[0m'
MSG_CONTENT=$(cat "$1")
# Initialize constants here
REGEX="^\[(.*)\] (feat|fix|docs|style|refactor|test|build|ci|perf|release)(\(((.+)-[0-9]{1,}|N\/A)\): (.+))"
NOTICE="A valid commit message looks like: ${Green}[a & b] feat(XX-123): hello, world!${NC}"
if [[ ! $MSG_CONTENT =~ $REGEX ]]; then
echo -e "${RED}invalid commit message format!${NC}: ${MSG_CONTENT}"
echo -e "$NOTICE"
exit 1
fi
# Tag message
#!/bin/bash
set -eo pipefail
RED='\033[0;31m'
Green='\033[0;32m'
NC='\033[0m'
REGEX="^\[(.*)\] (feat|fix|docs|style|refactor|test|build|ci|perf|release)(\(((.+)-[0-9]{1,}|N\/A)\): (.+))"
function validate {
local message="$2"
if [[ ! "$message" =~ $REGEX ]]; then
echo -e "${RED}The message format of tag \"$1\" is invalid!${NC}. A valid tag message looks like: ${Green}[a & b] feat(XX-123): hello, world!${NC}"
echo "Message: \"$message\""
exit 1
fi
}
# PRE_COMMIT_LOCAL_BRANCH 是 pre-commit 设置的环境变量
if [[ "$PRE_COMMIT_LOCAL_BRANCH" == *"refs/tags/"* ]]
then
tag_name=$(echo "$PRE_COMMIT_LOCAL_BRANCH" | sed 's/refs\/tags\/\(.*\)/\1/')
tag_message=$(git show -s --pretty=full "$tag_name" | sed -n 4p | xargs)
validate "$tag_name" "$tag_message"
fi
← Git 原理 Git Submodule →