Chapter Three-Way Merge
menutup satu keadaan yang familiar: main maju selagi fitur dikerjakan, dan penggabungannya melahirkan commit merge berparent dua. Riwayat hasilnya jujur — percabangan terlihat apa adanya — tetapi graf yang terus bertambah percabangan juga makin sulit dibaca, apalagi saat git log dipakai untuk menelusuri satu baris fitur menembus belasan merge. Ada satu jalan lain: rebase. Alih-alih menggabungkan dua sejarah, rebase memindahkan serangkaian commit ke basis baru — commit-commit fitur “dipelajari ulang” satu per satu di atas ujung main seolah-olah fitur baru mulai dikerjakan kemarin. Chapter ini membuktikan mekanisme itu dengan mata telanjang: hash lama disimpan, rebase dijalankan, hash baru dibandingkan.
Skenario: main Maju Selagi fitur Dikerjakan #
Repository latihan sengaja dibuat menyimpang — bentuk yang sama dengan skenario three-way merge, hanya saja jalannya kita belokkan dari merge:
mkdir latihan-konsep && cd latihan-konsep
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf '# Catatan\nhalo\n' > catatan.md
git add catatan.md
git commit -m "Tulis catatan pertama"
git switch -c fitur
printf 'langkah 1\n' > langkah.md
git add langkah.md
git commit -m "Catat langkah pertama"
printf 'langkah 1\nlangkah 2\n' > langkah.md
git add langkah.md
git commit -m "Catat langkah kedua"
git switch main
printf '# Catatan\nhalo\ndunia\n' > catatan.md
git add catatan.md
git commit -m "Tambah salam dunia"
git switch fiturKedua branch sama-sama maju satu langkah dari titik percabangan. Graf sebelum rebase terlihat seperti ini:
git log --oneline --graph --allOutput yang Dihasilkan:
* 37c5134 Tambah salam dunia
| * 2ce0d9b Catat langkah kedua
| * 0b9cdd8 Catat langkah pertama
|/
* 896c706 Tulis catatan pertamaBaris teratas adalah ujung main — “Tambah salam dunia”; di bawahnya dua commit milik fitur masih menempel pada “Tulis catatan pertama”. Inilah dasar lama tempat commit fitur berdiri.
Menjalankan Rebase dan Membuktikan Hash Berubah #
Sebelum menyentuh apa pun, kita simpan dulu hash kedua commit fitur ke sebuah berkas — bukti yang akan diadu sesudah rebase:
git rev-parse HEAD HEAD~1 > hash-lama.txtLalu perintah intinya — dijalankan dari branch fitur, menyebut basis barunya main:
git rebase mainOutput yang Dihasilkan:
Successfully rebased and updated refs/heads/fitur.Satu baris, tetapi di baliknya Git barusan menyalin ulang dua commit fitur ke atas ujung main. Buktinya: isi hash-lama.txt dibandingkan dengan hash yang sekarang ditunjuk fitur:
cat hash-lama.txtOutput yang Dihasilkan:
2ce0d9b973e771e0aea114f5cfdf4572ad75a219
0b9cdd89582f279813c2c147995c656889c0e633git rev-parse HEAD HEAD~1Output yang Dihasilkan:
7d6fd42463615e9b59a6973a4dcdb8c8b39fb6fb
31c02fb84f546468348e9eab6f15024c2e48f288Kedua hash berubah total — padahal tidak ada satu baris pun berkas yang kita sunting. Rebase tidak “memindahkan” objek commit lama; ia membuat commit baru yang berisi snapshot yang sama lalu menuntun rantai parent-nya ke basis baru. Commit lama (0b9cdd8 dan 2ce0d9b) masih tersimpan di database objek, hanya saja tidak lagi dijangkau branch mana pun. Prinsip ini adalah kunci seluruh section: rebase adalah alat menulis ulang riwayat, bukan sekadar memindah label.
Riwayat fitur Kini Berdiri di Atas main #
Graf setelah rebase menunjukkan hasil akhirnya:
git log --oneline --graph --allOutput yang Dihasilkan:
* 7d6fd42 Catat langkah kedua
* 31c02fb Catat langkah pertama
* 37c5134 Tambah salam dunia
* 896c706 Tulis catatan pertamaDua jalur menyatu menjadi satu garis lurus: “Tambah salam dunia” kini menjadi parent dari “Catat langkah pertama”. Kedudukan itu bisa diperiksa langsung — kakek dari ujung fitur harus tepat berada di ujung main:
git rev-parse HEAD~2 mainOutput yang Dihasilkan:
37c5134b93ef0fbe889d88aaaff8b8eb1cdd833d
37c5134b93ef0fbe889d88aaaff8b8eb1cdd833dDua nama berbeda, satu hash sama: fitur~2 adalah main. Sedangkan isi pekerjaan tidak tersentuh — langkah.md utuh dua barisnya:
cat langkah.mdOutput yang Dihasilkan:
langkah 1
langkah 2Sebelum dan sesudahnya dapat dilihat berdampingan di bawah ini; perhatikan hash fitur yang berubah sementara hash main tidak:
Hash pada diagram milik mesin uji dan akan berbeda di mesin pembaca, tetapi aksinya identik: dua commit fitur dipindahkan dari dasar lama ke dasar baru dengan identitas hash baru.
Rebase Menulis Ulang, Merge Menggabungkan #
Beda fundamental dua alat ini perlu ditegakkan sejak awal. Merge bekerja pada dua sejarah sekaligus: ia membaca ujung kedua sisi, membuat satu commit penggabung berparent dua, dan kedua sejarah asli tetap utuh tanpa diubah — tidak ada hash yang berubah. Rebase bekerja pada satu sejarah saja: sejarah fitur disalin ulang commit demi commit ke basis baru, hash lama diganti hash baru, dan sejarah main tidak tersentuh. Merge menghasilkan graf yang jujur bercabang; rebase menghasilkan graf yang seolah-olah percabangan tak pernah terjadi.
Dokumentasi resmi Pro Git memperlihatkan diagram konsep yang sama pada bab Git Branching – Rebasing
. Konsepnya sudah di tangan; chapter berikutnya membahas perintahnya secara penuh — sintaks inti, basis origin/main, hingga --onto: git rebase
.