Git Hooks adalah script yang dijalankan otomatis oleh Git saat event tertentu terjadi — sebelum atau setelah commit, push, merge, dan masih banyak lagi. Dengan hooks, kamu bisa menjalankan lint, test, validasi commit message, atau bahkan deployment — semua tanpa harus mengingat untuk melakukannya manual.
Cara Kerja Git Hooks
Hooks tersimpan di folder .git/hooks/ di setiap repository. Git sudah menyertakan contoh hooks dengan ekstensi .sample — hapus ekstensi tersebut untuk mengaktifkan:
ls .git/hooks/
# applypatch-msg.sample pre-commit.sample
# commit-msg.sample pre-merge-commit.sample
# post-commit.sample pre-push.sample
# pre-rebase.sample prepare-commit-msg.sample
# update.sample ...
# Aktifkan hook pre-commit
cp .git/hooks/pre-commit.sample .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
Hook bisa ditulis dalam bahasa apapun yang bisa dieksekusi: Bash, Python, Node.js, Ruby.
Exit code menentukan perilaku:
exit 0→ sukses, Git melanjutkan operasiexit 1(non-zero) → gagal, Git membatalkan operasi
Hook yang Paling Umum Dipakai
pre-commit — Jalankan Sebelum Commit Dibuat
Tempat paling umum untuk lint dan format check:
#!/bin/sh
# .git/hooks/pre-commit
echo "🔍 Menjalankan lint..."
# Jalankan ESLint
npm run lint
if [ $? -ne 0 ]; then
echo "❌ Lint gagal. Perbaiki error sebelum commit."
exit 1
fi
# Cek tidak ada console.log tertinggal
if git diff --cached | grep -E "^\+.*console\.log"; then
echo "❌ Ditemukan console.log! Hapus sebelum commit."
exit 1
fi
echo "✅ Lint berhasil."
exit 0
commit-msg — Validasi Pesan Commit
#!/bin/sh
# .git/hooks/commit-msg
COMMIT_MSG=$(cat "$1")
PATTERN="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .{1,72}$"
if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
echo "❌ Format pesan commit tidak valid!"
echo " Gunakan: <type>(<scope>): <deskripsi>"
echo " Contoh: feat(auth): tambah login Google OAuth"
echo " Tipe: feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert"
exit 1
fi
exit 0
pre-push — Jalankan Sebelum Push ke Remote
#!/bin/sh
# .git/hooks/pre-push
BRANCH=$(git rev-parse --abbrev-ref HEAD)
# Cegah push langsung ke main
if [ "$BRANCH" = "main" ]; then
echo "❌ Tidak boleh push langsung ke branch main!"
echo " Buat Pull Request melalui feature branch."
exit 1
fi
echo "🧪 Menjalankan test suite sebelum push..."
npm test
if [ $? -ne 0 ]; then
echo "❌ Test gagal. Perbaiki sebelum push."
exit 1
fi
echo "✅ Semua test lulus. Push dilanjutkan."
exit 0
prepare-commit-msg — Isi Template Pesan Commit Otomatis
#!/bin/sh
# .git/hooks/prepare-commit-msg
BRANCH=$(git rev-parse --abbrev-ref HEAD)
# Ekstrak nomor issue dari nama branch (contoh: feature/42-tambah-login → #42)
ISSUE=$(echo "$BRANCH" | grep -oE '[0-9]+' | head -1)
# Tambahkan referensi issue ke pesan commit
if [ -n "$ISSUE" ]; then
sed -i.bak "1s/^/refs #$ISSUE: /" "$1"
fi
Masalah Hooks: Tidak Ikut di Git
File di .git/hooks/ tidak ikut di-commit ke repository. Artinya setiap developer harus setup hooks secara manual — ini tidak praktis.
Solusi: Husky — Hooks yang Bisa Di-share
Husky memungkinkan Git hooks disimpan di repository dan di-install otomatis saat npm install.
npm install --save-dev husky
# Inisialisasi Husky
npx husky init
# Membuat folder .husky/ dan menambahkan script di package.json
package.json:
{
"scripts": {
"prepare": "husky"
}
}
Buat Hook dengan Husky
# pre-commit hook
cat > .husky/pre-commit << 'EOF'
#!/bin/sh
npm run lint
npm run test:unit
EOF
# commit-msg hook
cat > .husky/commit-msg << 'EOF'
#!/bin/sh
npx --no -- commitlint --edit $1
EOF
# pre-push hook
cat > .husky/pre-push << 'EOF'
#!/bin/sh
npm run test
EOF
# Pastikan executable
chmod +x .husky/pre-commit .husky/commit-msg .husky/pre-push
Semua file di .husky/ di-commit ke repository dan otomatis aktif setelah npm install.
lint-staged — Hanya Lint File yang Di-staged
Menjalankan lint ke seluruh project saat pre-commit bisa sangat lambat. lint-staged hanya menjalankan lint pada file yang di-git add saja.
npm install --save-dev lint-staged
package.json:
{
"lint-staged": {
"*.{js,ts,jsx,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{css,scss}": [
"stylelint --fix",
"prettier --write"
],
"*.md": [
"prettier --write"
]
}
}
.husky/pre-commit:
#!/bin/sh
npx lint-staged
Sekarang hanya file yang diubah dan di-stage yang akan di-lint — commit tetap cepat meskipun project besar.
Server-Side Hooks
Server-side hooks berjalan di server Git (GitHub menggunakan ini untuk GitHub Actions, Webhooks, branch protection):
pre-receive— sebelum push diterimaupdate— untuk setiap branch yang di-pushpost-receive— setelah push diterima (untuk notifikasi, deploy)
Di GitHub, fungsi ini digantikan oleh Branch Protection Rules dan GitHub Actions.
Bypass Hook (Untuk Keadaan Darurat)
# Skip pre-commit dan commit-msg hooks
git commit --no-verify -m "wip: bypass hook untuk perbaikan darurat"
# Skip pre-push hooks
git push --no-verify origin hotfix/urgent
Gunakan
--no-verifyhanya dalam keadaan benar-benar darurat. Ini adalah celah yang bisa disalahgunakan.
Kesimpulan
Git Hooks adalah lapisan otomasi yang powerful di level repository. Dengan Husky dan lint-staged, standar kode bisa ditegakkan secara konsisten di semua mesin developer tanpa bergantung pada disiplin manual. Ini melengkapi commitlint dari artikel sebelumnya untuk membentuk sistem quality gate yang komprehensif.
Di artikel berikutnya, kita bahas manajemen repository untuk tim besar — monorepo vs multirepo, GitHub Organizations, dan pengaturan akses.
Kiki/🎮🍉⌨️🍩💻