Buka repo kamu, jalankan git log --oneline, lalu lihat isinya. Kalau yang muncul deretan “wip”, “fix lagi”, “perbaikan kecil”, riwayat itu tidak membantu siapa pun — termasuk kamu sendiri tiga bulan dari sekarang. Git punya alat untuk merapikan semua itu tanpa kehilangan satu baris kode pun. Kalau kamu masih baru dan belum nyaman dengan commit, branch, dan merge, mampir dulu ke Panduan Git untuk Pemula sebelum lanjut membaca.

Siapkan Repo Latihan

Jangan langsung praktik di repo kerjaan. Buat repo kosong dulu supaya kamu bebas bikin kesalahan tanpa risiko. Jalankan ini di terminal:

bash
mkdir git-praktik && cd git-praktik
git init
echo "print('hello')" > app.py
git add app.py && git commit -m "buat file utama"
echo "print('world')" >> app.py
git add app.py && git commit -m "wip"
echo "def main(): pass" >> app.py
git add app.py && git commit -m "wip 2"
echo "print('selesai')" >> app.py
git add app.py && git commit -m "tambah print selesai"

Sekarang repo ini punya empat commit. Tiga commit terakhir terlihat berantakan: dua bertitel “wip” dan satu commit kecil yang sebenarnya cuma kelanjutan fitur yang sama. Riwayat begini yang akan kita rapikan.

Rebase vs Merge: Dua Cara Menyatukan Branch

Ada dua cara umum menggabungkan branch: merge dan rebase. Merge membuat commit baru berjenis merge yang menyimpan dua parent, jadi di log terlihat ada belokan. Rebase mengambil commit di branch kamu lalu memainkannya ulang di atas branch tujuan, seolah-olah kamu baru saja menulisnya. Hasilnya riwayat lurus tanpa cabang merge yang berseliweran.

Saya pakai merge kalau branch-nya sudah dipakai banyak orang dan riwayat lengkapnya penting untuk audit. Rebase saya pakai untuk branch lokal yang belum di-push, biar riwayatnya bersih sebelum masuk ke main. Tidak ada yang mutlak benar; yang penting satu tim konsisten dengan pilihan yang sama.

Rebase Interaktif: Gabungkan Commit yang Berantakan

Rebase interaktif dipakai untuk menulis ulang commit yang belum di-push. Anggap kita ingin menggabungkan tiga commit terakhir jadi satu. Jalankan:

bash
git rebase -i HEAD~3

Git membuka editor berisi daftar commit dengan satu kata perintah di depannya. Default-nya pick, artinya commit dipertahankan apa adanya. Isi editor itu kira-kira begini:

pick a1b2c3d wip
pick e4f5g6h wip 2
pick i7j8k9l tambah print selesai

Ganti kata pick dengan perintah lain untuk mengubah nasib commit. fixup menggabungkan commit ke commit di atasnya dan membuang pesannya. squash juga menggabungkan, tapi meminta kamu menulis pesan baru. reword cuma mengganti pesan. edit berhenti di tengah proses supaya kamu bisa mengubah isi commit. drop membuang commit. Untuk kasus kita, ubah jadi:

python
pick a1b2c3d wip
fixup e4f5g6h wip 2
fixup i7j8k9l tambah print selesai

Simpan dan tutup editor. Git menggabungkan tiga commit itu menjadi satu commit berjudul “wip”. Kalau editor bawaan (Vim) bikin kamu panik, ganti dulu ke nano sebelum mulai:

bash
git config --global core.editor "nano"

Bedakan fixup dan squash: keduanya menggabungkan commit, tapi fixup membuang pesan commit yang digabung, sedangkan squash meminta kamu menulis satu pesan baru untuk hasil gabungan. Untuk merapikan commit “wip” yang pesannya memang tidak penting, fixup lebih cepat.

Jangan rebase commit yang sudah di-push dan dipakai orang lain. Rebase menulis ulang hash commit. Kalau kamu push --force setelah rebase, rekan yang sudah menarik branch itu akan melihat riwayat bercabang dan bisa kehilangan pekerjaan. Aturan praktis saya: rebase cuma untuk commit lokal yang belum dibagikan.

Cherry-Pick: Ambil Satu Commit dari Branch Lain

Kadang kamu cuma butuh satu commit dari branch lain, bukan seluruh isinya. Cherry-pick menyalin satu commit ke branch aktif. Buat branch kecil, tulis satu fix, lalu bawa fix itu ke main:

bash
git checkout -b perbaikan-bug
echo "print('bug fixed')" >> app.py
git add app.py && git commit -m "perbaiki bug"
git checkout main
git cherry-pick <hash-commit-bug>

Ganti hash-commit-bug dengan hash asli commit tadi, yang bisa kamu lihat lewat git log --oneline. Git menyalin isi commit itu ke main dengan hash baru. Isi perubahannya sama persis, cuma riwayatnya berbeda.

Reflog: Jaring Pengaman Saat Reset Salah Arah

Reflog mencatat setiap pergerakan HEAD dalam 90 hari terakhir — termasuk commit yang sudah hilang dari git log karena kamu reset atau rebase. Ini penyelamat nomor satu saat kamu merasa commit hilang. Lihat isinya:

bash
git reflog

Keluarannya deretan baris dengan penanda seperti HEAD@{0}, HEAD@{1}, dan seterusnya. Untuk kembali ke kondisi sebelum reset yang keliru, cukup jalankan:

bash
git reset --hard HEAD@{1}

Angka dalam kurung kurawal menunjukkan urutan, dengan 0 sebagai posisi terbaru. HEAD@{1} berarti satu langkah sebelum posisi sekarang. Cek dulu baris mana yang kamu tuju sebelum menjalankan reset --hard, karena perintah ini membuang perubahan yang belum di-commit.

Reflog tersimpan lokal di mesin kamu dan tidak ikut ter-push ke remote. Karena itu reflog cuma bisa menyelamatkan commit yang pernah ada di komputermu — bukan commit yang cuma ada di laptop rekan kerja.

Bisect: Temukan Commit yang Memperkenalkan Bug

Bisect memakai binary search untuk menemukan commit pertama yang memunculkan bug. Kamu tandai satu commit sebagai buruk (bug sudah ada) dan satu sebagai baik (belum ada bug), lalu Git menyempitkan pencarian sampai menunjuk pelakunya. Mulai:

bash
git bisect start
git bisect bad
git bisect good <hash-commit-baik>

Git memindahkan HEAD ke commit di tengah rentang. Tes kode kamu, lalu beri tahu hasilnya: git bisect good kalau bug belum muncul di commit itu, git bisect bad kalau sudah. Ulangi sampai Git menunjuk commit pelakunya, lalu akhiri dengan git bisect reset.

Kalau pengecekan bisa diotomatiskan lewat test, pakai git bisect run. Git menjalankan perintah test di tiap langkah dan memutuskan sendiri hasilnya:

bash
git bisect start
git bisect bad
git bisect good <hash-commit-baik>
git bisect run python -m pytest

Perintah test harus keluar dengan status 0 untuk hasil baik dan status non-zero untuk buruk — persis seperti perilaku pytest. Kalau kamu belum terbiasa menulis test, saya sudah membahasnya di Belajar Testing Python dengan Pytest. Setelah test kamu stabil, jalankan otomatis di tiap commit lewat pre-commit supaya bug ketahuan sebelum sempat masuk riwayat.

Mulai dari repo kecil hari ini. Buka satu branch lokal yang commit-nya berantakan, jalankan git rebase -i HEAD~3, dan gabungkan commit yang seharusnya jadi satu. Setelah lancar, coba cherry-pick untuk memindahkan satu fix antar branch. Dan kalau suatu saat kamu merasa commit hilang, ingat satu hal: git reflog hampir selalu bisa menyelamatkanmu.