Commit terakhir di repo kamu isinya apa? Kalau masih ada trailing whitespace, import yang tidak terpakai, atau baris yang melewati batas panjang, berarti belum ada yang menjaga gerbang sebelum kode masuk history. pre-commit menutup celah itu. Dia menjalankan serangkaian hook setiap kali kamu ketik git commit, lalu membatalkan commit kalau ada satu saja hook yang gagal. Kode jelek jadi berhenti di mesin kamu sendiri, bukan di pull request yang dilihat reviewer.
Kenapa Hook Manual Tidak Cukup
Setiap project punya aturan sendiri: formatter, linter, type checker, test. Masalahnya aturan ini cuma jalan kalau orang ingat menjalankannya. Satu orang lupa, yang lain ikut-ikutan, dan tiga bulan kemudian codebase penuh gaya kode yang tidak konsisten. Git sebenarnya sudah menyediakan hook bawaan di .git/hooks — file seperti pre-commit.sample yang tinggal kamu rename jadi pre-commit. Tapi mengelola hook manual itu repot: tidak ikut ter-versioning, tidak bisa diinstall dengan satu perintah, dan susah dibagikan ke anggota tim lain.
Kalau kamu belum akrab dengan alur commit dan branch, baca dulu Panduan Git untuk Pemula sebelum lanjut. Artikel ini mengasumsikan kamu sudah paham dasar git add dan git commit.
Installasi
pre-commit adalah paket Python, jadi cara tercepat lewat pip atau uv. Kalau kamu sudah pakai uv, instalasinya lebih cepat dan dependency-nya terisolasi per project.
pip install pre-commit
# atau dengan uv
uv add --dev pre-commit
Membuat .pre-commit-config.yaml
Konfigurasi disimpan di file .pre-commit-config.yaml di root repo. Struktur dasarnya adalah daftar repos, tiap repo punya rev (versi yang di-pin) dan daftar hooks. Mulai dari yang paling sederhana: dua hook dari ruff untuk lint dan format.
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.10
hooks:
- id: ruff
- id: ruff-format
Menjalankan Hook untuk Pertama Kali
pre-commit install
pre-commit run --all-files
Perintah pre-commit install menulis hook ke .git/hooks/pre-commit sehingga dia dipanggil otomatis setiap commit. Sementara pre-commit run --all-files menjalankan semua hook ke seluruh file yang sudah ada — berguna saat pertama kali dipasang di repo yang sudah berisi banyak kode. Biarkan dia membenahi file dulu, lalu commit hasilnya.
Hook Python yang Sering Dipakai
Untuk project Python, kombinasi yang paling umum adalah ruff untuk lint, ruff-format untuk formatting, dan pytest untuk test. Kalau kamu belum kenal ruff, ada pembahasan lengkapnya di tutorial Menguasai Ruff. Hook test bisa memakai repo local yang memanggil perintah dari environment project kamu.
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.10
hooks:
- id: ruff
- id: ruff-format
- repo: local
hooks:
- id: pytest
name: pytest
entry: pytest
language: system
types: [python]
pass_filenames: false
Versi rev yang di-pin lama-lama ketinggalan. Jalankan pre-commit autoupdate secara berkala — misalnya sebulan sekali — untuk menaikkan versi hook sekaligus memperbarui rev di file konfigurasi secara otomatis.
Menjalankan Test di Hook: Hati-hati
Hook test terdengar bagus sampai suite test kamu butuh dua menit. Commit jadi lambat, dan orang mulai mencari jalan pintas dengan git commit --no-verify. Kalau kamu baru belajar menulis test, mulai dari panduan Pytest dari nol supaya suite-nya ringan dan cepat.
Jangan pasang seluruh suite test di pre-commit kalau durasinya lebih dari beberapa detik. Pisahkan test cepat (unit) untuk hook lokal, dan biarkan test lambat berjalan di CI. Pre-commit idealnya selesai dalam hitungan detik, bukan menit.
Menambahkan ke Repo Lama
Kalau kamu memasang pre-commit di repo yang sudah besar, urutannya begini: jalankan sekali ke semua file, lalu commit perubahan massal itu terpisah supaya review-nya bersih.
pre-commit run --all-files
git add .
git commit -m "chore: terapkan pre-commit dan rapikan kode"
Di GitHub, aktifkan pre-commit.ci supaya hook otomatis berjalan di tiap pull request dan mengirim commit perbaikan langsung ke branch. Ini menutup celah developer yang commit dari editor tanpa menginstall pre-commit lokal.
Langkah Berikutnya
Setelah hook berjalan, tambahkan aturan lint yang lebih ketat di pyproject.toml — misalnya target-version = "py311" dan daftar rules ruff yang kamu aktifkan. Lalu jadwalkan pre-commit autoupdate sebulan sekali. Mulai dari satu hook dulu kalau repo kamu belum punya apa-apa; dua minggu kemudian kamu akan lupa rasanya review kode yang berantakan.