Git Hook เป็นเครื่องมือที่ช่วยให้คุณสามารถรัน Script อัตโนมัติในช่วงเวลาที่กำหนดในกระบวนการทำงาน Git ได้ Pre-commit Hook คือ Hook ที่ทำงานก่อนการ Commit ทุกครั้ง ซึ่งช่วยให้คุณตรวจสอบและแก้ไขปัญหาในโค้ดได้ก่อนที่จะบันทึกลงในประวัติ Git
Git Hook คืออะไร?
Git Hook คือไฟล์ Script ที่ Git จะรันอัตโนมัติเมื่อเกิดเหตุการณ์บางอย่างในระหว่างการทำงานกับ Repository Hook มีหลายประเภท ได้แก่ Pre-commit, Post-commit, Pre-push, Pre-rebase เป็นต้น Pre-commit Hook เป็นอันที่นิยมใช้มากที่สุดเพราะมันช่วยป้องกันการ Commit โค้ดที่มีปัญหาได้
ที่อยู่ของ Pre-commit Hook (.git/hooks/)
ไฟล์ Git Hook ทั้งหมดจะอยู่ในโฟลเดอร์ .git/hooks/ ซึ่งสร้างขึ้นโดยอัตโนมัติเมื่อคุณสร้าง Repository ใหม่ หรือ Clone Repository จาก Remote Pre-commit Hook จะเป็นไฟล์ชื่อ “pre-commit” ที่ไม่มีนามสกุล
.git/hooks/
├── pre-commit
├── post-commit
├── pre-push
├── prepare-commit-msg
└── commit-msg
สร้าง Pre-commit Hook แบบมี Script
การสร้าง Pre-commit Hook ทำได้โดยสร้างไฟล์ที่ชื่อว่า “pre-commit” ในโฟลเดอร์ .git/hooks/ และเขียน Bash Script หรือภาษาอื่นๆ ตามที่ต้องการ ตัวอย่างนี้จะตรวจสอบการ Lint โค้ด JavaScript ก่อนการ Commit
#!/bin/bash
# Pre-commit hook to check code quality
echo "Running pre-commit checks..."
# Check if eslint is installed
if ! command -v eslint > /dev/null; then
echo "ESLint not found. Installing..."
npm install --save-dev eslint
fi
# Run ESLint on staged files
GIT_STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js$')
if [ -n "$GIT_STAGED_FILES" ]; then
echo "Linting files:"
echo "$GIT_STAGED_FILES"
npx eslint $GIT_STAGED_FILES
if [ $? -ne 0 ]; then
echo "ESLint check failed. Commit aborted."
exit 1
fi
fi
echo "All checks passed!"
exit 0
หลังจากสร้างไฟล์ Pre-commit Hook แล้ว คุณต้องให้สิทธิ์การทำงาน (Execute Permission) ให้กับไฟล์นี้:
chmod +x .git/hooks/pre-commit
ใช้ Pre-commit Framework (Pip Install)
Pre-commit Framework เป็นเครื่องมือที่ทำให้การจัดการ Git Hook ง่ายขึ้นมาก คุณไม่ต้องเขียน Shell Script เองแต่อย่างใด เพราะ Framework นี้มี Hook ที่สำเร็จรูปให้ใช้มากมายแล้ว
การติดตั้ง Pre-commit Framework ทำได้ดังนี้:
pip install pre-commit
การตั้งค่า .pre-commit-config.yaml
สร้างไฟล์ .pre-commit-config.yaml ในโฟลเดอร์หลักของ Repository เพื่อกำหนด Hook ที่ต้องการใช้
repos:
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
language_version: python3
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.35.0
hooks:
- id: eslint
types: [javascript]
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
จากนั้นรัน Command นี้เพื่อติดตั้ง Hook:
pre-commit install
Pre-commit Hook ที่นิยมใช้
1. Black – Formatter สำหรับ Python ที่ทำให้โค้ด Python มีรูปแบบเดียวกันทั่วโปรเจกต์
2. ESLint – Linter สำหรับ JavaScript ที่ช่วยตรวจสอบปัญหาในโค้ด JS
3. Prettier – Formatter สำหรับ JavaScript, HTML, CSS ที่ช่วยปรับรูปแบบโค้ดให้สวยงาม
4. Detect-secrets – ตรวจสอบ Secret Key, Password, Token ที่อาจจะ Commit โดยผิดพลาด
5. Pylint – Linter สำหรับ Python ที่มีความเข้มงวดมากขึ้น
ข้ามการทำงานของ Pre-commit Hook (–no-verify)
บางครั้งคุณอาจต้องข้ามการทำงานของ Pre-commit Hook ทั้งหมด โดยการใช้ Flag --no-verify ด้วย Command นี้:
git commit -m "Your commit message" --no-verify
หมายเหตุ: ควรใช้ --no-verify เฉพาะเมื่อจำเป็นเท่านั้น เพราะอาจจะ Commit โค้ดที่มีปัญหาได้
Best Practices สำหรับ Pre-commit Hook
- ให้ Hook ทำงานเร็ว – Hook ควรทำงานสำเร็จภายในเวลาไม่กี่วินาที เพื่อไม่รบกวนการทำงาน
- ชัดเจนในการแสดง Error – เมื่อ Hook ล้มเหลว ให้แสดงข้อความ Error ที่ชัดเจนว่าเกิดปัญหาอะไร
- ไม่บังคับสิ่งที่ไม่จำเป็น – ใช้ Hook เพื่อตรวจสอบคุณภาพโค้ดเท่านั้น ไม่ควรบังคับให้เปลี่ยนโค้ดโดยอัตโนมัติ
- บันทึก Hook ใน Repository – หากต้องการให้ทีมสมาชิกทั้งหมดใช้ Hook เดียวกัน ให้บันทึก Hook ในโฟลเดอร์ scripts/ และให้คำแนะนำในการติดตั้ง
- ทดสอบ Hook ก่อนใช้งาน – ตรวจสอบให้แน่ใจว่า Hook ทำงานถูกต้องก่อนนำไปใช้ในโปรเจกต์จริง
Pre-commit Hook เป็นเครื่องมือที่สำคัญในการรักษาคุณภาพโค้ดและป้องกันปัญหาที่จะเกิดขึ้นในอนาคต การใช้งาน Pre-commit Hook อย่างถูกต้องจะช่วยให้ทีมของคุณสามารถสรุปโค้ดที่มีคุณภาพสูงได้
