Automasi alur kerja lokal dengan Git hooks: pre-commit untuk linter dan formatter, commit-msg untuk validasi Conventional Commits, pre-push untuk unit test, serta framework Husky dan pre-commit untuk membagikannya ke seluruh tim.

Di episode 18 kita mengelola repository majemuk. Di episode 19 ini kita membahas keandalan di titik yang paling sering diabaikan: tangan kalian sendiri. Git Hook adalah script yang berjalan otomatis pada momen tertentu dalam siklus git — dan episode ini menunjukkan cara menggunakannya sebagai quality gate lokal sebelum kode keluar dari laptop.
Bayangkan sebuah tim di mana setiap commit selalu lolos linter, setiap pesan commit mengikuti Conventional Commits, dan setiap push selalu melewati unit test. Bukan karena disiplin semata, melainkan karena otomasi — Git tidak akan membiarkan pelanggaran lolos. Inilah perbedaan antara tim yang rapi karena aturan tertulis dan tim yang rapi karena sistem.
Hook adalah script yang ditempatkan di direktori .git/hooks/ dan dijalankan git pada titik tertentu. Cek isi defaultnya:
ls .git/hooks/Isinya deretan contoh dengan akhiran .sample (pre-commit.sample, commit-msg.sample, pre-push.sample). Hapus akhiran .sample dan isi dengan script kalian, atau buat file baru tanpa akhiran.
Ada dua golongan hook:
Fokus kita kali ini: client-side hooks pre-commit, commit-msg, dan pre-push.
Hook pre-commit berjalan sebelum commit dibuat. Jika ia keluar dengan status non-zero, commit dibatalkan. Contoh untuk project TypeScript:
#!/bin/sh
echo "Menjalankan linter dan formatter..."
bun run lint
if [ $? -ne 0 ]; then
echo "Lint gagal. Commit dibatalkan."
exit 1
fiJangan lupa chmod +x .git/hooks/pre-commit agar script bisa dieksekusi.
Hook commit-msg menerima path file pesan commit sebagai argumen pertama — sempurna untuk memvalidasi format pesan:
#!/bin/sh
pattern='^(feat|fix|docs|refactor|chore|perf|test|build|ci|style)(\(.+\))?: .+'
if ! grep -qE "$pattern" "$1"; then
echo "Pesan commit tidak mengikuti Conventional Commits."
echo "Contoh: feat: tambah halaman login"
exit 1
fiCommit dengan pesan asdf langsung ditolak sebelum sempat masuk riwayat — persis disiplin yang kita bicarakan sejak episode 4.
Hook pre-push berjalan setelah git push dipanggil tapi sebelum data dikirim ke remote. Ini gerbang terakhir:
#!/bin/sh
echo "Menjalankan unit test sebelum push..."
bun run testKode yang gagal test tidak akan pernah sampai ke origin — code review di GitHub (episode 11) jadi fokus pada logika, bukan pada hal yang seharusnya sudah dicek mesin.
Masalahnya: folder .git/ tidak ikut ter-clone. Hook yang ditulis di laptop kalian tidak akan muncul di laptop rekan kerja. Solusinya adalah framework yang menyimpan hook sebagai file biasa di repository.
bun add -D husky
bunx husky initHusky membuat folder .husky/ yang ikut di-commit. Isi .husky/pre-commit:
bun run lintKarena file ini ada di repository, setiap anggota tim otomatis mendapat hook yang sama setelah menjalankan instalasi.
Framework pre-commit (jangan tertukar dengan hook pre-commit) mengelola banyak hook berbasis Python di berbagai bahasa:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixerInstalasi satu kali: pip install pre-commit lalu pre-commit install untuk mengaitkannya ke .git/hooks/. File konfigurasi .pre-commit-config.yaml dibagikan lewat Git.
Tip
Mulailah dari dua hook saja: commit-msg untuk format pesan dan pre-commit untuk linter. Hook yang terlalu berat akan mengganggu dan sering di-skip anggota tim. Naikkan bertahap — tambah pre-push untuk test setelah tim terbiasa.
chmod +x. Script tidak tereksekusi, dan tidak ada error yang jelas..git/hooks/. Folder ini tidak tersinkron; pakai Husky atau pre-commit agar bisa di-commit.pre-commit membuat commit butuh menit; pindahkan yang berat ke pre-push.git commit --no-verify jadi kebiasaan. Gunakan jalan pintas ini sesekali dan sadari konsekuensinya, bukan sebagai solusi default.Poin yang harus kalian bawa:
.git/hooks/ yang dijalankan git pada momen tertentu dalam siklus.pre-commit untuk linter dan formatter, commit-msg untuk validasi pesan, pre-push untuk unit test.Automasi lokal sudah tertutup. Di episode 20, episode terakhir seri ini, kita membahas GitHub Automation Ecosystem: GitHub Actions untuk CI/CD, Semantic Versioning, Git Tags, dan GitHub Releases dengan gh CLI. Sampai jumpa di episode 20!