blog.dopana

Back

Hãy tưởng tượng bạn vừa viết xong một đoạn code tuyệt vời, hào hứng chạy git commit và push trực tiếp lên repository. Vài phút sau, hệ thống CI/CD báo lỗi đỏ rực chỉ vì… thừa một dấu phẩy hoặc quên chạy linter.

Tình huống này xảy ra rất thường xuyên. Làm sao để chúng ta chặn đứng các lỗi nhỏ này ngay tại máy cá nhân (Local) trước khi chúng kịp bước chân vào Git history? Câu trả lời chính là Git Pre-commit Hook.

Giới thiệu Git Pre-commit Hook#

Git Hooks là một tính năng tích hợp sẵn của Git, cho phép bạn kích hoạt các kịch bản (script) tự động tại các mốc thời điểm quan trọng trong vòng đời làm việc với Git (chẳng hạn như trước khi commit, trước khi push, hoặc sau khi checkout).

Trong đó, pre-commit hook chạy ngay khi bạn gõ lệnh git commit, trước cả khi Git tạo ra commit object. Nếu script trả về mã thoát (exit status) khác 0, quá trình commit sẽ bị hủy bỏ ngay lập tức.

graph LR
    A[Lệnh git commit] --> B{Pre-commit Hook}
    B -->|Mã thoát = 0| C[Tạo Commit thành công]
    B -->|Mã thoát != 0| D[Hủy bỏ Commit & Báo lỗi]

Vấn đề & Giải pháp chia sẻ Hook trong Team#

Theo mặc định, các hook của Git nằm tại thư mục ẩn .git/hooks/. Tuy nhiên, thư mục .git lại không được đưa vào version control. Điều này dẫn đến hai hạn chế lớn:

  1. Khó chia sẻ trong team: Mỗi thành viên phải tự copy script vào thư mục .git/hooks/ của họ một cách thủ công.
  2. Dễ bị lãng quên: Khi có thành viên mới tham gia dự án, họ thường bỏ qua bước thiết lập hook này.

Giải pháp với core.hooksPath#

Từ phiên bản Git 2.9, Git cung cấp cấu hình core.hooksPath cho phép chỉ định một thư mục bất kỳ làm nơi chứa hooks.

Chúng ta có thể lưu toàn bộ hook vào một thư mục được quản lý bởi Git (ví dụ .githooks/), sau đó thiết lập:

git config core.hooksPath .githooks
bash

Kết hợp với file package.json (nếu dự án dùng Node.js/Bun), bạn có thể tự động hóa lệnh này thông qua script prepare:

package.json
{
  "scripts": {
    "prepare": "git config core.hooksPath .githooks"
  }
}
json

Mỗi khi thành viên trong team chạy npm install hoặc bun install, Git sẽ tự động sử dụng thư mục .githooks của dự án.

Thực hành: Tự động format Markdown với agent-md#

Dưới đây là ví dụ thực tế về script pre-commit hook: Tự động kiểm tra xem công cụ CLI agent-md có sẵn trên máy hay không, nếu có thì tự động format các file Markdown đang được staged và tự động git add lại.

Đừng quên cấp quyền thực thi cho file script:

chmod +x .githooks/pre-commit
bash

Cách bỏ qua Pre-commit Hook khi cần thiết#

Trong một số trường hợp khẩn cấp (như commit dở dang để đổi branch), bạn có thể tạm thời bỏ qua bước kiểm tra của pre-commit hook bằng cờ --no-verify (hoặc -n):

git commit -m "WIP: tạm thời bỏ qua check" --no-verify
bash

[!TIP] Hãy hạn chế dùng --no-verify để đảm bảo chất lượng code luôn được đồng nhất trên toàn dự án.

Tài liệu tham khảo#