Tools

pre-commit: chặn lỗi định dạng và lộ secret trước khi commit

Tóm tắt

pre-commit quản lý git hook bằng một file YAML, tự cài công cụ cho từng hook và chỉ chạy trên file thay đổi. Chạy pre-commit install một lần, autoupdate định kỳ, và luôn chạy lại run --all-files trong CI.

Lỗi nhỏ như khoảng trắng thừa, file YAML sai cú pháp, import chưa sắp xếp, hay tệ hơn là API key lọt vào commit thường chỉ bị phát hiện ở CI, hoặc trong code review, sau khi đã tốn thời gian của người khác. Git có sẵn cơ chế hook để chạy kiểm tra trước mỗi commit, nhưng viết và chia sẻ hook cho cả team bằng tay rất phiền. pre-commit là framework quản lý hook: khai báo trong một file YAML, tự cài đúng phiên bản công cụ cho từng ngôn ngữ, và chỉ chạy trên file đang thay đổi.

Trang GitHub của pre-commit/pre-commit
Trang GitHub của pre-commit/pre-commit (ảnh chụp tháng 11/2026)

GitHub: https://github.com/pre-commit/pre-commit · khoảng 16 nghìn sao · Python · MIT

Cài đặt

pipx install pre-commit        # hoặc: pip install pre-commit
uv tool install pre-commit     # nếu dùng uv
brew install pre-commit        # macOS

Cấu hình

Tạo file .pre-commit-config.yaml ở gốc repo. Ví dụ dưới kết hợp hook cơ bản, Ruff cho Python và Gitleaks chặn lộ secret (phiên bản tại thời điểm viết; chạy pre-commit autoupdate để lấy bản mới nhất):

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-json
      - id: check-added-large-files
        args: ["--maxkb=500"]
      - id: check-merge-conflict

  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.17.3
    hooks:
      - id: ruff-check
        args: [--fix]
      - id: ruff-format

  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.30.1
    hooks:
      - id: gitleaks

Rồi cài hook vào repo:

pre-commit install                 # gắn vào .git/hooks/pre-commit
pre-commit run --all-files         # chạy lần đầu trên toàn bộ repo

Từ giờ, mỗi lần git commit, các hook chạy trên file đã stage. Hook nào sửa file (như ruff --fix, end-of-file-fixer) sẽ làm commit dừng lại; bạn xem thay đổi, git add lại rồi commit.

Lệnh hay dùng

LệnhTác dụng
pre-commit runChạy hook trên file đang stage
pre-commit run ruff-check --all-filesChạy riêng một hook trên toàn repo
pre-commit autoupdateCập nhật rev của mọi repo hook lên bản mới nhất
SKIP=gitleaks git commit ...Bỏ qua một hook cụ thể cho lần commit này
git commit --no-verifyBỏ qua mọi hook (chỉ dùng khi thật cần)
pre-commit install --hook-type pre-pushChạy hook ở bước push thay vì commit

Đưa vào CI

Hook cục bộ có thể bị bỏ qua (--no-verify, người chưa cài). Vì vậy chạy lại trong CI để đảm bảo:

# Bước trong GitHub Actions
- uses: actions/setup-python@v5
- run: pipx run pre-commit run --all-files --show-diff-on-failure

Một lựa chọn khác là dịch vụ pre-commit.ci, tự chạy hook và có thể tự đẩy commit sửa lỗi vào PR.

Lưu ý

  • Hook chậm làm dev khó chịu và bỏ qua; giữ các kiểm tra nặng (test đầy đủ, quét sâu) ở CI, chỉ để kiểm tra nhanh ở pre-commit.
  • Ghim rev theo tag, không theo nhánh, để mọi người chạy cùng phiên bản.
  • Lần đầu chạy, pre-commit tải và cài môi trường cho từng hook nên chậm; các lần sau dùng cache.

Áp dụng thế nào?

  • Dev: Chạy pre-commit install ngay sau khi clone repo; lỗi định dạng và secret bị chặn trước khi tới tay reviewer.
  • Tech Lead: Bắt đầu với bộ hook tối thiểu (khoảng trắng, YAML, file lớn, gitleaks), thêm formatter/linter của ngôn ngữ chính, và chạy lại trong CI để không ai lách được.
  • PM: Code review tập trung vào logic thay vì định dạng, và giảm rủi ro lộ secret, một sự cố có thể tốn rất nhiều chi phí xử lý.

Nguồn & tham khảo

  1. pre-commit/pre-commit — pre-commit (GitHub)
  2. pre-commit documentation — pre-commit