Ketika sebuah bug dilaporkan dan penyebabnya tidak terlihat, pertanyaan yang paling berguna adalah commit mana yang pertama membawanya. Menjawabnya dengan membaca commit satu per satu boros, sedangkan git bisect menjawabnya dengan pencarian biner (binary search) yang membagi riwayat menjadi dua pada setiap langkah. Topik ini membahas alur manualnya, otomatisasi penuhnya melalui git bisect run, dan cara kembali dari keadaan pemeriksaan.
Pencarian biner pada riwayat#
Pencarian biner bekerja pada satu syarat, yaitu keadaan yang diketahui baik dan keadaan yang diketahui buruk. Git menguji commit di tengah keduanya, lalu mengganti salah satu batas sesuai jawaban, sehingga jumlah ujian yang diperlukan tumbuh secara logaritmik terhadap jumlah commit. Riwayat seribu commit cukup diuji sekitar sepuluh kali, bukan seribu kali.
Syarat kedua adalah perintah pengujian yang dapat menyatakan baik atau buruk secara pasti. Bentuknya sering sederhana, misalnya program berjalan tanpa error, atau sebuah berkas memuat keluaran yang benar. Siapkan riwayat tujuh commit yang menyisipkan bug pada tengahnya, lalu jalankan pencarian manual.
# tanggal commit ditetapkan agar keluaran contoh dapat direproduksi secara persis
export GIT_AUTHOR_DATE="2026-11-01T09:00:00+07:00"
export GIT_COMMITTER_DATE="2026-11-01T09:00:00+07:00"rm -rf /tmp/lab-bisect
mkdir /tmp/lab-bisect
cd /tmp/lab-bisect
git init -b main
git config user.name "Budi"
git config user.email "[email protected]"
for i in 1 2 3 4 5 6 7; do
if [ "$i" -ge 5 ]; then printf "Iterasi $i.\nBUG: pembagian nol.\n" > app.txt; else printf "Iterasi $i.\n" > app.txt; fi
git add app.txt
git commit -q -m "Iterasi $i"
done
git bisect start HEAD HEAD~6Initialized empty Git repository in /tmp/lab-bisect/.git/
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[bede1de7b09029405b4356c38fcad741fd7754df] Iterasi 4Argumen git bisect start berbentuk buruk baik, yaitu HEAD sebagai ujung yang diketahui buruk dan HEAD~6 sebagai commit pertama yang diketahui baik. Git langsung berpindah ke commit tengah, yaitu Iterasi 3, dan menyatakan sisa langkah yang diperlukan.
Otomatisasi penuh dengan git bisect run#
Pada tiap langkah manual, pemeriksa menjalankan pengujian lalu menyatakan git bisect good atau git bisect bad. Apabila pengujian dapat dikemas menjadi perintah yang keluarannya menyatakan keadaan tersebut, seluruh langkah dapat diserahkan kepada git bisect run, dan pencarian berjalan tanpa penyelaan manusia.
git bisect run sh -c '! grep -q BUG app.txt'running 'sh' '-c' ''\!' grep -q BUG app.txt'
Bisecting: 0 revisions left to test after this (roughly 1 step)
[bff6b475aa677a8617822730be0e97fddfd7d7d7] Iterasi 6
running 'sh' '-c' ''\!' grep -q BUG app.txt'
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[05abb1c3ec168fe8a1def14ea5a9eefa903eb993] Iterasi 5
running 'sh' '-c' ''\!' grep -q BUG app.txt'
05abb1c3ec168fe8a1def14ea5a9eefa903eb993 is the first bad commit
commit 05abb1c3ec168fe8a1def14ea5a9eefa903eb993
Author: Budi <[email protected]>
Date: Sun Nov 1 09:00:00 2026 +0700
Iterasi 5
app.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
bisect found first bad commitKontrak perintah pengujinya lurus: keluaran nol berarti keadaan baik, keluaran bukan nol berarti buruk. Perintah sh -c '! grep -q BUG app.txt' mengembalikan nol ketika kata BUG tidak ditemukan, sehingga pengujian membalik syarat grep menjadi ujian kelayakan. Git memutar pengujian pada setiap tengah, dan baris is the first bad commit menampilkan jawaban akhirnya lengkap dengan metadata commit dan diff-nya, yaitu commit Iterasi 5 yang memang menyisipkan bug.
Alur manual untuk memahami langkahnya#
Otomatisasi run menyembunyikan pergerakannya, dan alur manual membuat setiap langkah terlihat. Perintah git bisect good atau git bisect bad menyatakan keadaan commit yang sedang diperiksa, lalu Git berpindah ke tengah berikutnya sampai tersisa satu kandidat.
git bisect start HEAD HEAD~6 >/dev/null
git bisect bad
git bisect badPrevious HEAD position was 05abb1c Iterasi 5
Switched to branch 'main'
status: waiting for good commit(s), bad commit known
status: waiting for good commit(s), bad commit knownSetiap jawaban mempersempit rentang, dan keluaran sesi selalu menyebut sisa langkahnya. Alur manual ini juga menjadi jalan keluar ketika pengujian tidak dapat dikemas menjadi satu perintah, misalnya pengujian yang menuntut penilaian manusia pada antarmuka atau keluaran gambar, dan git bisect log mencatat jalannya sesi agar bisa dilanjutkan di lain waktu.
Kembali dari keadaan bisect#
Selama sesi bisect, HEAD berada pada keadaan khusus yang disebut refs/bisect, dan pekerjaan lain tidak boleh dilakukan di sana. Perintah git bisect reset mengembalikan branch ke keadaan sebelum sesi dimulai.
git bisect reset
git log --oneline -1Already on 'main'
df109d0 Iterasi 7Pemulihan ini wajib dilakukan sebelum melanjutkan pekerjaan biasa, dan Git mengingatkannya pada banyak perintah selama sesi berlangsung. Setelah reset, hasil pencarian berupa hash commit penyebab bug dapat langsung diperiksa dengan git show, dan pertanyaan mengapa perubahan itu dibuat dijawab dari pesan serta konteksnya.
Ringkasan#
git bisectmencari commit pertama yang buruk dengan pembagian dua, sehingga jumlah ujiannya tumbuh logaritmik terhadap panjang riwayat.- Sesi dimulai dengan
git bisect start buruk baik, dan alur manualnya menyatakan tiap tengah dengangoodataubad. git bisect run perintahmengotomatiskan seluruh langkah dengan kontrak keluaran nol berarti baik.git bisect resetmengembalikan branch ke keadaan sebelum sesi, dan hasil pencariannya diperiksa dengangit show.
Referensi#
- git-bisect — Git Documentation
— rujukan alur bisect beserta kontrak
run. - Git Tools - Debugging with Git — Pro Git — bab Pro Git tentang bisect.