Git Hooks: Otomatisasi di Sisi Klien
Jalankan script otomatis setiap kali kamu commit: lint, cek format pesan commit, atau tolak commit yang belum lolos test.
Penjaga gerbang sebelum commit lahir
Git hooks adalah script yang Git jalankan otomatis di momen tertentu: sebelum commit dibuat, sesudah push, dan sebagainya. Kenapa ini penting? Karena banyak aturan tim ("kode harus lolos lint", "pesan commit harus pakai format tertentu") paling murah ditegakkan di laptop masing-masing anggota, sebelum kode yang bermasalah sempat masuk repo. Hooks adalah satpam yang memeriksa KTP sebelum tamu masuk gedung, bukan polisi yang datang setelah kejadian.
Hooks tinggal di folder .git/hooks/. Saat kamu init repo, Git mengisinya dengan contoh bernama *.sample, misalnya pre-commit.sample. Contoh itu tidak aktif sampai kamu menghapus akhiran .sample dan membuatnya executable. Hook yang aktif hanyalah file executable dengan nama yang tepat.
Tiga hook yang paling berguna
pre-commit berjalan sebelum Git membuat commit. Kalau script ini keluar dengan status non-nol, commit dibatalkan. Kegunaan klasik: menjalankan linter atau formatter.
commit-msg berjalan setelah pesan commit ditulis, menerima path file berisi pesan itu sebagai argumen. Kegunaan klasik: memvalidasi format pesan, misalnya menolak commit tanpa nomor tiket.
prepare-commit-msg berjalan sebelum editor pesan commit dibuka. Kegunaan klasik: menyisipkan template atau nomor issue otomatis ke pesan commit.
Contoh hook pre-commit sederhana yang menolak commit kalau ada file JavaScript yang gagal lint:
#!/bin/sh
npx eslint . --quiet
if [ $? -ne 0 ]; then
echo "Lint gagal. Perbaiki dulu sebelum commit."
exit 1
fiSimpan sebagai .git/hooks/pre-commit, lalu:
chmod +x .git/hooks/pre-commitMulai sekarang, setiap git commit otomatis menjalankan ESLint dulu. Kalau lint gagal, commit dibatalkan dan kamu dipaksa memperbaiki. Contoh hook commit-msg yang mewajibkan format konvensional:
#!/bin/sh
if ! grep -qE "^(feat|fix|docs|chore)((.+))?: " "$1"; then
echo "Pesan commit harus diawali feat:, fix:, docs:, atau chore:"
exit 1
fiMasalah hooks bawaan: tidak ikut ter-commit
Ada satu kelemahan besar: folder .git tidak masuk version control, jadi hooks yang kamu tulis tidak ikut ter-push dan tidak sampai ke laptop teman satu tim. Setiap anggota harus memasang manual. Solusi populer di proyek JavaScript adalah Husky: hooks disimpan di folder .husky/ yang ikut ter-commit, dan Husky memasangnya lewat script prepare di package.json:
npx husky initIni membuat folder .husky/pre-commit yang bisa kamu isi perintah apa pun, dan seluruh tim otomatis mendapat hook yang sama saat npm install. Alternatif tanpa tool: set git config core.hooksPath ke folder hooks yang ikut ter-commit di repo.
Satu catatan jujur: hooks sisi klien bisa dilewati dengan git commit --no-verify. Jadi perlakukan hooks sebagai pengingat yang membantu, bukan benteng keamanan. Aturan yang benar-benar wajib tetap harus ditegakkan di server, misalnya lewat GitHub Actions atau branch protection.
Kesalahan umum pemula
Salah: menulis hook lalu bingung kenapa tidak jalan, ternyata file belum chmod +x atau masih bernama pre-commit.sample.
Benar: nama file harus persis (pre-commit, tanpa ekstensi), tanpa akhiran .sample, dan executable.
Salah: menaruh logika penting hanya di hooks lokal lalu kaget saat ada yang lolos lewat --no-verify atau lupa memasang hooks.
Benar: hooks untuk kenyamanan dan feedback cepat; validasi yang sifatnya wajib duplikasikan di CI server.
Tantangan
Pasang satpam pre-commit pertamamu
Di sebuah repo latihan, buat file .git/hooks/pre-commit yang menolak commit jika ada file .js yang mengandung kata TODO. Buat executable, lalu uji: commit file berisi TODO (harus gagal), hapus TODO-nya, commit lagi (harus berhasil).