Git Hooks — Git

Hook adalah script yang Git jalankan otomatis pada event tertentu — sebelum commit, sesudah push, dll. Cocok untuk enforce standar tim. Lokasi hook…

Git hook adalah script yang dijalankan Git secara otomatis pada momen tertentu, misalnya tepat sebelum sebuah commit dibuat. Kalau script-nya gagal, Git membatalkan langkah itu. Mirip pemeriksaan tas di pintu masuk mal: sebelum kamu masuk, satpam ngecek dulu. Lolos, silakan masuk. Gak lolos, kamu gak masuk, dan di dalam gak ada yang tercatat.

🧪 Tebakan cepat: hook pre-commit menemukan masalah lalu keluar dengan exit 1. Commit-nya tetap dibuat dengan peringatan, atau batal sama sekali? Tebak dulu, jawabannya ada di bagian "Hook pertamamu: pre-commit".

Di mana hook tinggal

Tiap repo punya folder .git/hooks/. Waktu git init, Git mengisinya dengan contoh seperti pre-commit.sample dan commit-msg.sample. Contoh itu belum aktif. Supaya sebuah hook jalan, harus ada tiga hal:

Hook pertamamu: pre-commit

pre-commit jalan saat kamu mengetik git commit, sebelum commit dibuat. Contoh: tolak commit kalau app.js masih berisi console.log sisa debugging.

#!/bin/sh
# .git/hooks/pre-commit
if grep -q "console.log" app.js; then
  echo "pre-commit: app.js masih berisi console.log, hapus dulu"
  exit 1
fi
echo "pre-commit: aman"

Pasang, lalu coba commit:

$ chmod +x .git/hooks/pre-commit
$ git add app.js
$ git commit -m "feat: ekspor function total"
pre-commit: app.js masih berisi console.log, hapus dulu
$ git log --oneline
4e1d2a9 (HEAD -> main) chore: initial setup

Commit-nya batal sama sekali. Gak ada commit baru, git log tetap satu baris, dan Git gak menambah pesan apa pun selain yang dicetak hook-nya. Itu jawaban tebakannya. Hapus baris console.log-nya, git add app.js lagi, lalu commit ulang: hook mencetak pre-commit: aman dan commit-nya jadi.

Cek pesan commit: commit-msg

commit-msg jalan setelah pesan commit ditulis. Git memberinya satu argumen, $1: alamat file yang berisi pesan itu. Contoh: pesan harus diawali feat:, fix:, docs: atau chore:.

#!/bin/sh
# .git/hooks/commit-msg
if ! grep -qE "^(feat|fix|docs|chore): " "$1"; then
  echo "commit-msg: awali pesan dengan feat:, fix:, docs: atau chore:"
  exit 1
fi
$ git commit -m "update"
pre-commit: aman
commit-msg: awali pesan dengan feat:, fix:, docs: atau chore:

Urutannya: pre-commit dulu, lalu commit-msg, baru commit dibuat. Kalau pre-commit sudah gagal, commit-msg gak dijalankan.

Client-side dan server-side

Hook Jalan di mana Kapan Contoh pemakaian
pre-commit komputer developer (client-side) sebelum commit dibuat lint, format, tes cepat
commit-msg komputer developer (client-side) setelah pesan ditulis cek format pesan
pre-push komputer developer (client-side) sebelum git push mengirim tes lengkap
pre-receive server (server-side) saat push masuk, sebelum diterima tolak push yang melanggar aturan
post-receive server (server-side) setelah push diterima deploy, kirim notifikasi

Jadi pre-commit itu client-side: jalan di komputermu sendiri, sebelum ada apa pun yang dikirim.

Berbagi hook dengan tim: Husky

Isi .git/ gak ikut di-commit, jadi hook di .git/hooks/ cuma ada di komputermu. Teman yang clone repo-mu gak mendapatkannya. Husky memindahkan hook ke folder biasa, .husky/, yang ikut di-commit:

$ npm install --save-dev husky
$ npx husky init

Melewati hook: --no-verify

Dalam keadaan darurat, kamu bisa melewati hook:

$ git commit --no-verify -m "fix: hotfix login"   # pre-commit dan commit-msg dilewati
$ git push --no-verify                            # pre-push dilewati

-n adalah singkatan --no-verify untuk git commit. Pakai seperlunya: kalau sering dipakai, berarti hook-nya terlalu lambat atau terlalu ketat, dan itu yang harus diperbaiki.

⚠️ Jebakan yang sering ketemu

TL;DR: Hook adalah script di .git/hooks/ (nama persis, chmod +x) yang dijalankan Git otomatis. Exit code 0 berarti lanjut, selain 0 berarti langkahnya batal: pre-commit yang exit 1 membatalkan commit. Urutan saat commit: pre-commit, lalu commit-msg (pesannya ada di file $1), baru commit dibuat. pre-commit, commit-msg dan pre-push itu client-side, pre-receive dan post-receive server-side. Hook di .git/hooks/ gak ikut ke tim, jadi pakai Husky (.husky/pre-commit, script prepare). git commit --no-verify (atau -n) melewati hook, cuma untuk darurat.

Yang akan kamu pelajari