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-commitmenemukan masalah lalu keluar denganexit 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:
- Nama file persis nama hook-nya, tanpa ekstensi:
.git/hooks/pre-commit, bukanpre-commit.sh. - File-nya bisa dieksekusi:
chmod +x .git/hooks/pre-commit. - Exit code menentukan hasilnya:
exit 0artinya lanjut, angka lain (misalnyaexit 1) artinya Git membatalkan langkahnya.
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"
#!/bin/shdi baris pertama memberi tahu sistem bahwa ini script shell.grep -q "console.log" app.jsmencari teks itu diapp.js.-qartinya diam: gak mencetak apa-apa, cuma memberi hasil ketemu atau gak.- Kalau ketemu, script mencetak alasannya lalu
exit 1. - Kalau gak ketemu, script sampai di akhir dan selesai dengan exit code 0.
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
npx husky initmembuat file.husky/pre-commitdan menambahkan script"prepare": "husky"dipackage.json. Scriptpreparejalan otomatis setiap ada yang menjalankannpm install, jadi hook-nya ikut terpasang di laptop teman.- Isi
.husky/pre-commitcukup perintahnya, misalnyanpx lint-staged. lint-staged menjalankan linter hanya pada file yang di-stage, bukan seluruh project, jadi pre-commit tetap cepat. - Perubahan
package.jsondan.husky/itu di-commit seperti file biasa, misalnya dengan pesanchore: configure hooks.
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
- Lupa
chmod +x. Git melewati hook itu dan cuma memberihint: The '.git/hooks/pre-commit' hook was ignored because it's not set as executable.Commit tetap jadi, dan pemeriksaannya gak pernah jalan. - Nama file salah.
pre-commit.shatauprecommitgak akan pernah dipanggil. - Mengira hook ikut ke tim.
.git/hooks/gak di-commit. Pakai Husky supaya hook ada di repo. - Di latihan, hook-nya sudah terpasang.
.git/hooks/pre-commitdi latihan adalah contohconsole.logdi atas, sudahchmod +x, dan terminal latihan menjalankannya di tiapgit commit. Perintah sepertinpxgak ada di terminal itu, jadi hook yang memanggilnya gagal dengancommand not found.
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.