Git钩子脚本如何自动格式化代码

wen 实用脚本 1

本文目录导读:

Git钩子脚本如何自动格式化代码

  1. 创建 pre-commit 钩子脚本
  2. 使用常用格式化工具
  3. 使用 pre-commit 框架(推荐)
  4. husky + lint-staged(Node.js项目)
  5. 高级功能:条件格式化和错误处理
  6. 使用建议

Git钩子脚本自动格式化代码通常使用 pre-commit 钩子,以下是几种常见的实现方式:

创建 pre-commit 钩子脚本

在项目根目录的 .git/hooks/ 目录下创建 pre-commit 文件:

#!/bin/sh
# .git/hooks/pre-commit
# 获取所有暂存的代码文件
FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(js|jsx|ts|tsx|css|scss|json|md)$')
if [ -z "$FILES" ]; then
    exit 0
fi
# 使用 prettier 格式化代码
echo "正在格式化代码..."
npx prettier --write $FILES
# 重新将格式化后的文件加入暂存区
git add $FILES
echo "代码格式化完成!"

使用常用格式化工具

Prettier(通用格式化)

#!/bin/bash
# .git/hooks/pre-commit
# 格式化 JavaScript/TypeScript/CSS/JSON/Markdown
FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(js|jsx|ts|tsx|css|scss|json|md)$')
if [ -n "$FILES" ]; then
    npx prettier --write --ignore-unknown $FILES
    git add $FILES
fi

ESLint + Prettier(JS/TS项目)

#!/bin/bash
# .git/hooks/pre-commit
# 先执行 ESLint 修复
FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(js|jsx|ts|tsx)$')
if [ -n "$FILES" ]; then
    npx eslint --fix $FILES
    # ESLint 修复失败,阻止提交
    if [ $? -ne 0 ]; then
        echo "ESLint 检查失败,请修复代码风格问题"
        exit 1
    fi
    git add $FILES
fi

Black(Python项目)

#!/bin/bash
# .git/hooks/pre-commit
FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.py$')
if [ -n "$FILES" ]; then
    black --quiet $FILES
    git add $FILES
fi

Go fmt(Go项目)

#!/bin/bash
# .git/hooks/pre-commit
FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.go$')
if [ -n "$FILES" ]; then
    gofmt -w $FILES
    git add $FILES
fi

使用 pre-commit 框架(推荐)

安装 pre-commit 工具可以更方便地管理钩子:

# 安装 pre-commit
pip install pre-commit
# 或
brew install pre-commit

创建 .pre-commit-config.yaml

repos:
  - repo: https://github.com/pre-commit/mirrors-prettier
    rev: v3.0.0
    hooks:
      - id: prettier
        types_or: [javascript, typescript, css, json, markdown]
  - repo: https://github.com/psf/black
    rev: 23.1.0
    hooks:
      - id: black
        language_version: python3.9
  - repo: https://github.com/pre-commit/mirrors-eslint
    rev: v8.35.0
    hooks:
      - id: eslint
        additional_dependencies:
          - eslint@8.35.0
          - eslint-plugin-prettier@4.2.1

然后安装钩子:

pre-commit install

husky + lint-staged(Node.js项目)

// package.json
{
  "devDependencies": {
    "husky": "^8.0.0",
    "lint-staged": "^13.0.0",
    "prettier": "^2.8.0"
  },
  "lint-staged": {
    "*.{js,jsx,ts,tsx,css,scss,json,md}": [
      "prettier --write",
      "git add"
    ]
  }
}
# 初始化 husky
npx husky init
# 在 .husky/pre-commit 中:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged

高级功能:条件格式化和错误处理

#!/bin/bash
# .git/hooks/pre-commit
set -e  # 出错即退出
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${YELLOW}正在检查代码格式...${NC}"
# 获取暂存的文件
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR)
if [ -z "$STAGED_FILES" ]; then
    echo -e "${GREEN}没有需要格式化的文件${NC}"
    exit 0
fi
# 根据不同文件类型使用不同格式化工具
FORMATTED=false
for FILE in $STAGED_FILES; do
    case "$FILE" in
        *.js|*.jsx|*.ts|*.tsx)
            npx prettier --write "$FILE" 2>/dev/null || true
            npx eslint --fix "$FILE" 2>/dev/null || true
            FORMATTED=true
            ;;
        *.css|*.scss|*.json|*.md)
            npx prettier --write "$FILE" 2>/dev/null || true
            FORMATTED=true
            ;;
        *.py)
            black --quiet "$FILE" 2>/dev/null || true
            FORMATTED=true
            ;;
        *.go)
            gofmt -w "$FILE" 2>/dev/null || true
            FORMATTED=true
            ;;
    esac
done
if [ "$FORMATTED" = true ]; then
    # 重新添加格式化后的文件
    git add $STAGED_FILES
    echo -e "${GREEN}代码格式化完成!${NC}"
else
    echo -e "${YELLOW}没有需要格式化的文件类型${NC}"
fi

使用建议

  1. 团队统一:所有成员使用相同的格式化工具和配置
  2. 配置文件:使用 .prettierrc.eslintrc 等配置文件
  3. 渐进式应用:先对增量代码格式化,再逐步处理历史代码
  4. 版本控制:将钩子脚本或 pre-commit-config.yaml 纳入版本控制
  5. 文档说明:在 README 中说明格式化工具的安装和使用方法

建议使用 pre-commit 框架husky + lint-staged,因为它们更容易配置和维护,且支持团队协作。

抱歉,评论功能暂时关闭!