Riwayat yang panjang menyimpan jawaban atas pertanyaan yang paling sering muncul saat investigasi: kapan bug ini masuk? siapa yang memperkenalkan konfigurasi itu? kapan fungsi ini dihapus? Filter --grep dari chapter Opsi git log mengintip isi pesan commit — padahal jawaban sering bersembunyi di dalam diff: baris yang ditambah atau dihapus. Git menyediakan alat khusus untuk mengais diff demi sebuah teks, dijuluki pickaxe — nama opsi -S dan -G pada git log. Chapter ini memakai keduanya untuk membedah repository kasir yang kehilangan fitur diskonnya, lalu menutup dengan satu kategori commit yang tak bisa ditemukan alat mana pun: commit yang terputus dari riwayat.

Repository Latihan: Fitur Diskon yang Lahir dan Menghilang #

Repository kasir kita mencatat satu kisah singkat dalam empat commit: fungsi diskon ditambahkan, nilainya dinaikkan, lalu fitur itu dihapus sementara. Commit ketiga ditulis Siti dengan identitas per-commit, pola yang sudah kita pakai di chapter Opsi git log :

bash
mkdir latihan-pickaxe && cd latihan-pickaxe
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf '# Kasir Latihan\n\nAplikasi latihan hitung belanja.\n' > README.md
printf '# Aplikasi Kasir\n\ndef total_belanja(items):\n    total = 0\n    for harga in items:\n        total = total + harga\n    return total\n' > kasir.py
git add README.md kasir.py
git commit -m "Tambah kerangka aplikasi kasir"
printf '# Aplikasi Kasir\n\ndef total_belanja(items):\n    total = 0\n    for harga in items:\n        total = total + harga\n    return total\n\ndef hitung_diskon(total):\n    diskon = 0.2\n    return total * diskon\n' > kasir.py
git add kasir.py
git commit -m "Tambah perhitungan diskon belanja"
printf '# Aplikasi Kasir\n\ndef total_belanja(items):\n    total = 0\n    for harga in items:\n        total = total + harga\n    return total\n\ndef hitung_diskon(total):\n    diskon = 0.25\n    return total * diskon\n' > kasir.py
git add kasir.py
git -c user.name="Siti Rahma" -c user.email="[email protected]" \
  commit -m "Naikkan diskon menjadi 25 persen"
printf '# Aplikasi Kasir\n\ndef total_belanja(items):\n    total = 0\n    for harga in items:\n        total = total + harga\n    return total\n' > kasir.py
git add kasir.py
git commit -m "Hapus sementara perhitungan diskon"

Riwayat lengkapnya:

bash
git log --oneline

Output yang Dihasilkan:

text
aa2cecd Hapus sementara perhitungan diskon
928b867 Naikkan diskon menjadi 25 persen
2771126 Tambah perhitungan diskon belanja
8e088da Tambah kerangka aplikasi kasir

Pertanyaan kita: di commit mana kata diskon masuk ke kode, dan di commit mana kata itu keluar? Kedua commit itu memang terlihat dari daftar di atas — tapi bayangkan daftar ini berisi lima ratus baris dari sepuluh orang. Kita butuh pencarian yang bekerja pada isi perubahan, bukan pada pesannya.

Pickaxe -S: Melacak Perubahan Jumlah Kemunculan #

Opsi -S "teks" memerintahkan git log hanya menampilkan commit yang mengubah jumlah kemunculan teks tersebut di dalam isi repository:

bash
git log -S "diskon" --oneline

Output yang Dihasilkan:

text
aa2cecd Hapus sementara perhitungan diskon
2771126 Tambah perhitungan diskon belanja

Dua dari empat commit muncul — tepat dua momen hidup fitur diskon. Mari kita hitung kemunculan kata diskon di kasir.py pada tiap commit: 8e088da memuat nol kemunculan; 2771126 menambah tiga sekaligus (nama fungsi hitung_diskon, variabel diskon, dan total * diskon) sehingga jumlahnya berubah dari nol ke tiga; aa2cecd menghapus ketiganya sehingga jumlahnya kembali ke nol. Commit 928b867 tidak tampil karena jumlah kemunculan kata diskon sebelum dan sesudahnya sama-sama tiga — mengganti 0.2 menjadi 0.25 tidak menambah maupun membuang satu pun kata diskon.

Menambahkan -p menampilkan patch dari tiap commit yang lolos saringan — bukti lengkap mengapa masing-masing terpilih:

bash
git log -S "diskon" -p

Output yang Dihasilkan:

text
commit aa2cecd919cdc1967745a9afeb293b23fe2f185b
Author: Budi Santoso <[email protected]>
Date:   Tue Oct 13 09:30:00 2026 +0700

    Hapus sementara perhitungan diskon

diff --git a/kasir.py b/kasir.py
index 0d16781..57871d6 100644
--- a/kasir.py
+++ b/kasir.py
@@ -5,7 +5,3 @@ def total_belanja(items):
     for harga in items:
         total = total + harga
     return total
-
-def hitung_diskon(total):
-    diskon = 0.25
-    return total * diskon

commit 277112603bccffe46c06381610657a01444ad81b
Author: Budi Santoso <[email protected]>
Date:   Tue Oct 13 09:10:00 2026 +0700

    Tambah perhitungan diskon belanja

diff --git a/kasir.py b/kasir.py
index 57871d6..0bd55b5 100644
--- a/kasir.py
+++ b/kasir.py
@@ -5,3 +5,7 @@ def total_belanja(items):
     for harga in items:
         total = total + harga
     return total
+
+def hitung_diskon(total):
+    diskon = 0.2
+    return total * diskon

Dua patch itu cermin satu sama lain: 2771126 menambah tiga baris berprefiks +, aa2cecd menghapus tiga baris berprefiks - dengan isi yang persis sama. Pola tambah-lalu-hapus seperti inilah yang membuat -S menjadi alat andalan menjawab “fitur ini kapan dihapus dan siapa yang menghapusnya?”.

Mencocokkan Baris yang Berubah dengan -G #

Kini giliran kasus yang membuat -S kecolongan. Katakanlah tim menemukan diskon pernah bernilai 0.25 — nilai yang membuat pelanggan membayar terlalu sedikit — dan ingin tahu commit mana yang memasukkan angka itu. -S "diskon" tidak akan pernah menemukannya, karena pergantian 0.2 menjadi 0.25 tidak mengubah jumlah kemunculan kata apa pun. Di sinilah -G bekerja dengan cara yang berbeda: -G "regex" menampilkan commit yang diff-nya memuat baris tambahan atau baris terhapus yang cocok dengan pola regex:

bash
git log -G "diskon" --oneline

Output yang Dihasilkan:

text
aa2cecd Hapus sementara perhitungan diskon
928b867 Naikkan diskon menjadi 25 persen
2771126 Tambah perhitungan diskon belanja

928b867 kini ikut tampil — diff commit itu memuat baris - diskon = 0.2 dan + diskon = 0.25, keduanya cocok dengan pola diskon. Pola bisa dipersempit sampai ke nilainya:

bash
git log -G "diskon = 0.25" --oneline

Output yang Dihasilkan:

text
aa2cecd Hapus sementara perhitungan diskon
928b867 Naikkan diskon menjadi 25 persen

Nilai 0.25 terbukti masuk lewat 928b867 dan keluar lewat aa2cecd; git show 928b867 kemudian menampilkan patch lengkapnya untuk dibaca alasannya. Perbedaan cara kerja keduanya ringkas dirangkum:

Aspek-S "teks"-G "regex"
Yang diperiksajumlah kemunculan string di seluruh isibaris tambah/hapus pada diff
Kapan commit ditampilkanbila jumlah kemunculan berubahbila ada baris diff yang cocok pola
Mengubah nilai variabel (0.2 → 0.25)tidak tampiltampil
Menambah atau menghapus baristampiltampil
Bentuk polastring biasaregex penuh

Aturan praktisnya: pakai -S untuk melacak hidup-mati sebuah string, dan pakai -G saat setiap perubahan nilai pada baris yang memuat string itu juga penting. Daftar lengkap opsi pickaxe terdokumentasi di dokumentasi git log .

Menemukan Commit yang Terputus dari Riwayat #

Seluruh pencarian di atas menjelajah riwayat yang masih terhubung ke HEAD. Namun chapter Amend Commit memperlihatkan satu kategori commit yang sengaja diputus: commit lama yang ditulis ulang. Kita buat satu di sini — commit Tambah catatan uji yang pesannya kurang jelas, lalu langsung diperbaiki lewat --amend:

bash
printf '# Uji Transaksi\nDaftar belanja uji:\n' > uji.txt
git add uji.txt
git commit -m "Tambah catatan uji"
git commit --amend -m "Tambah berkas uji transaksi"

Riwayat kini memuat lima commit dengan 7f79534 di puncak — dan tidak ada satu baris pun yang menyebut commit lama:

bash
git log --oneline

Output yang Dihasilkan:

text
7f79534 Tambah berkas uji transaksi
aa2cecd Hapus sementara perhitungan diskon
928b867 Naikkan diskon menjadi 25 persen
2771126 Tambah perhitungan diskon belanja
8e088da Tambah kerangka aplikasi kasir

Commit lama itu masih ada di database — hanya tidak lagi dirujuk riwayat. Peta satu-satunya yang masih mencatatnya adalah reflog, catatan pergerakan HEAD yang Git tulis otomatis pada setiap langkah:

bash
git reflog

Output yang Dihasilkan:

text
7f79534 HEAD@{0}: commit (amend): Tambah berkas uji transaksi
dd942ad HEAD@{1}: commit: Tambah catatan uji
aa2cecd HEAD@{2}: commit: Hapus sementara perhitungan diskon
928b867 HEAD@{3}: commit: Naikkan diskon menjadi 25 persen
2771126 HEAD@{4}: commit: Tambah perhitungan diskon belanja
8e088da HEAD@{5}: commit (initial): Tambah kerangka aplikasi kasir

Entri HEAD@{1} memuat dd942ad — commit lama pra-amend, lengkap dengan alasan perpindahannya: commit: Tambah catatan uji. Penulisan HEAD@{n} dibaca mundur dari posisi terkini: HEAD@{1} adalah posisi HEAD satu langkah sebelum sekarang. Notasi itu sendiri bisa dievaluasi menjadi hash:

bash
git rev-parse HEAD@{1}

Output yang Dihasilkan:

text
dd942ad60dac7ca155c62a022ecef26d363c8e21

Dan objek di alamat itu masih hidup:

bash
git cat-file -t HEAD@{1}

Output yang Dihasilkan:

text
commit

Pickaxe dan filter pesan tidak akan pernah menemukan dd942ad karena keduanya berjalan di atas riwayat; reflog adalah jaring penyelamat yang bekerja di luar riwayat. Perjalanan lengkapnya — termasuk batas umur reflog dan cara memulihkan branch yang terhapus — dibahas di chapter git reflog .

Setelah commit yang dicari berhasil ditemukan, langkah berikutnya hampir selalu menyebutkannya kembali: di pesan bug report, di perintah git show, di rentang dua commit. Satu objek commit itu punya banyak nama — hash penuh, singkatan, branch, tag, HEAD~1 — dan sistem penamaan itulah pokok bahasan chapter berikutnya: Commit Hash dan References .