Git Hooks Pre-commit, Pre-push, dan Menghentikan Kode Buruk di Pintu Masuk
Hook pre-commit, commit-msg, dan pre-push adalah skrip shell yang dijalankan sebelum Git menulis komit atau mengirimkan push. Berikut cara menghubungkannya untuk menangkap kegagalan pemeriksaan, pesan komit yang buruk, dan rahasia yang terlepas — dengan contoh nyata yang bisa Anda gunakan sekarang.
Git menyediakan hook — skrip shell yang dijalankan pada titik-titik tertentu dalam alur kerja Anda. Sebagian besar repositori memiliki mereka yang berada dalam keadaan mati di .git/hooks/ sebagai .sample file. Sebagian besar pengembang mengabaikannya sampai commit yang rusak atau kunci API yang terbuka membuat mereka berharap mereka tidak melakukannya.
Ini mencakup tiga hook yang perlu dihubungkan pada setiap proyek: pre-commit, commit-msgdan pre-push. Setiap satu menangkap kelas kesalahan yang berbeda. Setiap satu adalah skrip shell yang dapat Anda salin dan gunakan hari ini.
Di mana hook berada
Setiap repositori git memiliki sebuah .git/hooks/ direktori. Jalankan ls .git/hooks/ dan Anda akan melihat file contoh. Git mengabaikan apa pun yang memiliki .sample ekstensi. Untuk mengaktifkan hook, hilangkan ekstensi dan buat file tersebut dapat dieksekusi:
cp .git/hooks/pre-commit.sample .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
Kontaknya sederhana: keluarkan 0 dan git melanjutkan. Keluarkan nilai non-nol dan git menghentikan proses, mencetak apa pun yang Anda tulis ke stderr.
pre-commit: hook bernilai tinggi Anda
Pre-commit berjalan setelah Anda mengetik git commit tetapi sebelum objek commit ditulis. Ini tidak dapat melihat pesan commit — itu belum ditulis. Yang dilakukan adalah memeriksa file yang sudah dipilih dan menolak jika sesuatu terlihat salah. bisa Detail penting: gunakan
untuk mendapatkan hanya file yang benar-benar dipilih. Meninjau seluruh proyek pada setiap commit akan lambat dan menampilkan masalah yang tidak Anda buat. git diff --cached --name-only Contoh peninjau (ESLint)
flag melewatkan file yang dihapus — tidak perlu mencoba meninjau sesuatu yang baru saja dihapus.
#!/bin/sh
# Lint only staged JS files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js$')
if [ -z "$STAGED_FILES" ]; then
exit 0
fi
echo "Running ESLint on staged files..."
echo "$STAGED_FILES" | xargs ./node_modules/.bin/eslint
if [ $? -ne 0 ]; then
echo "ESLint failed. Fix errors before committing."
exit 1
fi
exit 0
Itu --diff-filter=ACM Contoh pemindaian rahasia
Pemindaian pola yang tajam yang menangkap kesalahan yang jelas — kunci API yang ditulis secara langsung, kata sandi di file konfigurasi yang diserahkan secara tidak sengaja:
Untuk proyek selain proyek sederhana, gabungkan ini dengan pemindaian khusus.
#!/bin/sh
# Block commits with obvious secrets
PATTERNS="(AWS_SECRET|api_key\s*=|password\s*=|PRIVATE KEY)"
if git diff --cached | grep -qiP "$PATTERNS"; then
echo "Potential secret detected in staged changes. Aborting commit."
exit 1
fi
exit 0
detect-secrets dari Yelp bekerja baik sebagai hook pre-commit — ini mempertahankan file dasar sehingga string yang ditandai sebelumnya tidak menghambat setiap commit. trufflehog lebih baik digunakan untuk pemindaian sejarah setelah itu atau dijalankan dalam CI. commit-msg: memaksa format pesan
Hook ini menerima satu argumen: jalur ke file sementara yang berisi draft pesan commit Anda. Baca, validasi, dan keluarkan 1 untuk menolak. File tersebut dapat dibaca — Anda bisa menormalisasi pesan daripada menolaknya, meskipun hal ini mengejutkan orang pertama kali.
Memaksa
Conventional Commits format adalah penggunaan paling umum. Manfaatnya adalah log perubahan yang otomatis, output yang mudah dibaca, dan pipeline CI yang dapat memarsing tipe commit untuk menentukan apa yang harus dirilis: Ini tidak akan menangkap pesan format yang valid tetapi tetap tidak bermakna seperti git log . Itu adalah masalah budaya, bukan masalah alat.
#!/bin/sh
COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
# type(scope): description — scope is optional
PATTERN="^(feat|fix|chore|docs|style|refactor|test|perf|ci|build|revert)(\(.+\))?: .{1,72}"
if ! echo "$COMMIT_MSG" | grep -qP "$PATTERN"; then
echo ""
echo "Invalid commit message. Use Conventional Commits format:"
echo " type(scope): short description"
echo ""
echo "Valid types: feat, fix, chore, docs, style, refactor, test, perf, ci, build, revert"
echo "Example: feat(auth): add OAuth2 login flow"
echo ""
echo "Your message: $COMMIT_MSG"
exit 1
fi
exit 0
pre-push: pintu keluar sebelum tujuan fix: fix thingsPre-push berjalan setelah
diaktifkan tetapi sebelum data dikirim ke remote. Ini menerima nama remote dan URL melalui stdin. Ini adalah tempat untuk uji coba — bukan peninjau (yang berjalan di pre-commit), tetapi uji coba yang memverifikasi perilaku.
Satu kebenaran keras: jika suite uji Anda membutuhkan lebih dari 60–90 detik, orang akan menggunakan git push . Jalankan hanya uji unit cepat di sini. Uji integrasi dan E2E harus berada di CI di mana lambat diterima. Hook yang lambat cukup untuk mengabaikan justru lebih buruk daripada tidak ada hook.
#!/bin/sh
echo "Running tests before push..."
npm test
if [ $? -ne 0 ]; then
echo "Tests failed. Push aborted."
exit 1
fi
exit 0
Mengabaikan hook — dan kapan itu sesuai --no-verifyKedua flag ini ada karena alasan tertentu. Hook yang rusak yang menghambat perbaikan darurat adalah hal yang membuat seluruh tim menolak konsep git hook. Gunakan
ketika Anda memiliki alasan yang sah: hook yang salah berjalan pada file yang tidak terkait, atau situasi darurat di mana perbaikan lebih penting daripada pintu.
git commit --no-verify
git push --no-verify
Jika Anda sering menggunakan itu, maka hook perlu disesuaikan. Pelaku paling umum: berjalan terlalu lambat, gagal pada file yang tidak berubah, atau hasil positif dari pola yang belum pernah Anda bersihkan. --no-verify Membagikan hook dengan tim Anda
adalah lokal pada setiap salinan — secara sengaja tidak disimpan dalam repositori. Dua pendekatan untuk membuat hook tetap:
Pilihan 1: core.hooksPath
.git/hooks/ Simpan hook di direktori yang disimpan (misalnya,
), lalu petakan git ke lokasi tersebut:
Untuk mengotomatisasi ini bagi salinan baru, tambahkan sebuah .githooks/skrip ke
git config core.hooksPath .githooks
— npm menjalankannya secara otomatis saat prepare Jadikan skrip tersebut dapat dieksekusi, simpan di repositori, dan siapa pun yang melakukan salinan dan menjalankan package.json akan mendapatkan hook yang dikonfigurasi secara otomatis. npm install:
{
"scripts": {
"prepare": "git config core.hooksPath .githooks"
}
}
Pilihan 2: Husky npm install Husky
adalah pilihan standar untuk proyek JavaScript/Node. Ini menangani
penghubungan untuk Anda dan memberikan setiap hook file sendiri di Lalu tambahkan hook sebagai skrip shell biasa: core.hooksPath Husky 9 (diluncurkan awal 2024) menghapus konfigurasi JSON secara total, menggantinya dengan skrip shell murni. Lebih sederhana daripada versi v4/v8 untuk pengaturan baru, tetapi migrasi dari Husky 4 adalah perubahan yang mengganggu yang kurang ditekankan dalam panduan migrasi resmi — format lama .husky/:
npx husky init
tidak lagi berfungsi sama sekali. Jika Anda memperbarui repositori yang ada, alokasikan waktu untuk itu.
echo "npm test" > .husky/pre-push
chmod +x .husky/pre-push
Repositori non-JavaScript lebih baik dilayani oleh pendekatan .huskyrc . Tidak ada alasan untuk mengunduh ketergantungan Node hanya untuk pengelolaan hook.
Uji perbedaan sebelum hook dijalankan core.hooksPath menampilkan perubahan yang dipilih di terminal. Saat Anda membandingkan dua versi file konfigurasi atau memeriksa apa yang benar-benar diubah oleh refactor di berbagai edit, perbandingan visual lebih cepat dibaca.
IO Tools’ Text Diff
git diff --cached memungkinkan Anda menempelkan dua versi dan melihat persis apa yang berubah — berguna saat Anda ingin meninjau apa yang masuk ke commit sebelum hook dijalankan. Git hooks adalah salah satu alat otomasi yang hidup sepenuhnya dalam alur kerja Anda — tidak perlu akun CI, tidak perlu layanan tambahan, tidak ada biaya. Hook pre-commit yang menolak kegagalan peninjauan sama relabelnya seperti skrip shell yang Anda tulis. Ini adalah fitur: Anda dapat membaca, memperbaiki, dan mengubahnya dalam satu menit. Hubungkan tiga hook di atas dan Anda telah menutup celah terbesar antara “ini bekerja secara lokal” dan “ini bekerja di main.” Git Hooks: Pre-commit, Pre-push, dan Menghentikan Kode Buruk di Pintu 2
Git Hooks: Pre-commit, Pre-push, dan Menghentikan Kode Buruk di Pintu 1
Instal Ekstensi Kami
Tambahkan alat IO ke browser favorit Anda untuk akses instan dan pencarian lebih cepat
恵 Papan Skor Telah Tiba!
Papan Skor adalah cara yang menyenangkan untuk melacak permainan Anda, semua data disimpan di browser Anda. Lebih banyak fitur akan segera hadir!
Alat Wajib Coba
Lihat semua Pendatang baru
Lihat semuaMemperbarui: Kita alat terbaru ditambahkan pada 18 Jun 2026
