Giao diện
Thực hành: Git Hooks & Automation
🎯 Mục tiêu
🎯 Sau bài thực hành này, bạn sẽ:
- Hiểu các loại Git hooks và thời điểm kích hoạt
- Viết được pre-commit hook tự động kiểm tra code
- Biết cách chia sẻ hooks với team qua Husky
Phần 1: Trắc nghiệm
🧠 Quiz
Câu 1: Hook pre-commit chạy vào thời điểm nào?
- [ ] A) Sau khi commit đã được tạo thành công
- [x] B) Trước khi Git tạo commit — nếu hook trả về exit code khác 0, commit bị hủy
- [ ] C) Trước khi push code lên remote
- [ ] D) Khi mở editor để viết commit message
💡 Giải thích:
pre-commitchạy trước khi Git tạo commit object — dùng để lint, format, kiểm tra file cấm. Exit code 0 = cho phép, khác 0 = chặn.
🧠 Quiz
Câu 2: Git hooks được lưu ở đâu trong repository?
- [x] A) Thư mục
.git/hooks/— mỗi hook là một file executable - [ ] B) File
.githooksở root của repository - [ ] C) Trong file
.gitconfigcủa user - [ ] D) Trên remote server, tự động tải về khi clone
💡 Giải thích: Hooks nằm trong
.git/hooks/. Khigit init, Git tạo sẵn file mẫu đuôi.sample. Bỏ đuôi.samplevà thêm quyền execute để kích hoạt. Vì.git/không track, cần Husky hoặccore.hooksPathđể share hooks.
🧠 Quiz
Câu 3: Sự khác biệt giữa pre-commit và pre-push hook là gì?
- [ ] A) Không khác nhau — cả hai đều chạy trước khi code lên server
- [ ] B)
pre-commitchạy trên server,pre-pushchạy trên client - [x] C)
pre-commitkiểm tra trước mỗi commit,pre-pushkiểm tra trước khi đẩy lên remote - [ ] D)
pre-pushnhanh hơn vì chỉ kiểm tra file đã thay đổi
💡 Giải thích:
pre-commitchạy mỗi lần commit — dùng cho kiểm tra nhanh (lint, format).pre-pushchạy ít hơn — phù hợp kiểm tra nặng (test suite, build).
Phần 2: Tìm lỗi sai
🐛 Spot-the-Bug
Tìm lỗi: Pre-commit hook không hoạt động
Developer viết hook chặn console.log nhưng hook không chạy:
bash
# Pre-commit hook - check for console.log
echo "Running pre-commit checks..."
FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js$')
if [ -z "$FILES" ]; then exit 0; fi
for FILE in $FILES; do
if grep -q "console.log" "$FILE"; then
echo "ERROR: console.log found in $FILE"; exit 1
fi
done
exit 0Câu hỏi: Có 2 vấn đề. Tìm ra không?
Đáp án: (1) Thiếu shebang #!/bin/sh ở dòng đầu. (2) Thiếu quyền execute — cần chmod +x. Thiếu thì Git bỏ qua im lặng.
Phần 3: Bài tập — Viết pre-commit hook
Các bước:
mkdir hook-demo && cd hook-demo && git init- Tạo
.git/hooks/pre-commit:bash#!/bin/sh STAGED=$(git diff --cached --name-only) for file in $STAGED; do if [ -f "$file" ] && grep -qE "TODO FIXME|HACK" "$file"; then echo "BLOCKED: $file has forbidden markers"; exit 1 fi done exit 0 chmod +x .git/hooks/pre-commit- Test 1 — File hợp lệ → commit thành công. Test 2 — File chứa
TODO FIXME→ bị chặn
Lưu ý
Trong dự án thực tế, dùng Husky hoặc pre-commit (Python) thay vì hook thủ công — đảm bảo toàn team dùng cùng hooks.