Git merge vs rebase: mana yang sebaiknya dipilih untuk tim Anda
Merge dan rebase sama-sama menggabungkan perubahan branch, tetapi memperlakukan riwayat dengan cara berbeda: merge mempertahankan riwayat apa adanya dan menambahkan commit merge, sedangkan rebase menulis ulang commit Anda di atas basis baru sehingga riwayat menjadi lurus. Aturan praktisnya: gunakan rebase untuk merapikan commit lokal yang belum dikirim, dan merge untuk memasukkan pekerjaan yang sudah jadi ke branch bersama.
Ringkasnya: apa bedanya merge dan rebase
Perdebatan «merge vs rebase» sebenarnya bukan soal perintah mana yang lebih baik, melainkan riwayat seperti apa yang ingin Anda lihat di proyek. Kedua perintah menghasilkan kode yang sama di akhir. Yang berbeda adalah jalur yang tercatat di log.
- Merge menyatukan dua jalur riwayat dan mencatat dengan jujur bahwa pekerjaan berlangsung secara paralel. Commit yang sudah ada tidak berubah, dan ditambahkan satu commit merge dengan dua induk.
- Rebase menulis ulang commit Anda seolah-olah Anda memulai pekerjaan dari versi terbaru branch dasar. Riwayatnya tampak sebagai garis lurus, tetapi commit mendapat hash baru.
Mekanisme masing-masing perintah, seperti flag, penyelesaian konflik, dan mode interaktif, sudah dibahas di artikel terpisah. Di sini kita hanya membahas cara memilih strateginya.
Seperti apa riwayatnya dalam kedua kasus
Situasi awal: Anda membuat feature dari main, membuat dua commit, dan selama itu dua commit lain masuk ke main.
D---E feature
/
A---B---C---F---G main
Setelah git merge feature di main:
D---E
/ \
A---B---C---F---G---M main
Setelah git rebase main di feature lalu memajukan main:
A---B---C---F---G---D'---E' main
Pada kasus pertama, riwayat menunjukkan bahwa fitur dikerjakan secara paralel dan kapan fitur itu digabungkan. Pada kasus kedua, riwayat terbaca sebagai cerita yang berurutan, tetapi fakta bahwa pekerjaan berlangsung paralel sudah tidak tampak: D' dan E' adalah commit baru yang dibuat saat rebase.
Tabel perbandingan merge vs rebase
| Kriteria | git merge | git rebase |
|---|---|---|
| Commit yang sudah ada | Tidak berubah | Dibuat ulang dengan hash baru |
| Bentuk riwayat | Graf bercabang dengan commit merge | Linier |
| Keamanan untuk branch bersama | Selalu aman | Berbahaya untuk commit yang sudah dipublikasikan |
| Perlu force push? | Tidak | Ya, jika branch sudah ada di server |
| Konflik | Diselesaikan sekali, di commit merge | Bisa muncul di setiap commit yang dipindahkan |
| Konteks «dari mana asalnya» | Tersimpan | Hilang |
| Membatalkan seluruh fitur | Satu git revert -m 1 pada commit merge | Revert setiap commit atau rentang commit |
Kemudahan git bisect dan git log | Graf lebih sulit dibaca | Lebih mudah: satu garis lurus |
| Ambang masuk | Rendah | Lebih tinggi, perlu memahami penulisan ulang riwayat |
| Merapikan commit (squash, reword) | Hanya --squash untuk seluruh branch | Fleksibel lewat rebase -i |
Kelebihan dan kekurangan merge
Kelebihan
- Tidak merusak riwayat. Semua yang sudah dipublikasikan tetap di tempatnya. Rekan tim tidak perlu memperbaiki apa pun setelah tindakan Anda.
- Konflik diselesaikan sekali. Walaupun branch berisi 30 commit, Anda hanya menghadapi keadaan akhirnya, bukan setiap langkahnya.
- Konteks tetap terjaga. Dari commit merge terlihat kapan suatu tugas masuk ke branch utama, dan tugas itu mudah dibatalkan secara utuh.
Kekurangan
- Graf yang ramai. Jika sering sinkronisasi, riwayat dipenuhi commit «Merge branch 'main' into feature», dan
git log --graphberubah menjadi diagram jalur kereta. - Commit coretan ikut masuk riwayat. «wip», «fix», «fix lagi» akan tetap ada di branch utama jika tidak dirapikan.
Kelebihan dan kekurangan rebase
Kelebihan
- Riwayat linier dan mudah dibaca. Setiap commit berada di posisinya,
git logterbaca seperti daftar perubahan, dangit bisectlebih cepat menemukan commit yang bermasalah. - Commit bisa dirapikan sebelum review: digabung, diberi nama ulang, atau diurutkan ulang.
- Tidak ada commit merge teknis dari sinkronisasi dengan branch utama.
Kekurangan
- Menulis ulang riwayat. Rebase pada branch bersama yang sudah dipublikasikan merusak pekerjaan semua orang yang sudah mengunduhnya.
- Memerlukan force push untuk branch di server, sehingga butuh disiplin dan
--force-with-lease. - Konflik berulang. Bagian yang sama bisa berkonflik pada beberapa commit berturut-turut.
- Commit perantara mungkin tidak bisa di-build. Setelah dipindahkan ke basis baru, commit lama belum tentu pernah diuji di lingkungan yang baru.
Kapan memakai yang mana
Rebase — untuk pekerjaan lokal Anda sendiri
Anda memperbarui branch sebelum mengirimnya: git pull --rebase. Anda menyiapkan branch untuk review dan ingin membuang commit coretan: git rebase -i. Branch fitur pribadi Anda tertinggal dari main: git rebase origin/main. Dalam semua kasus ini, yang ditulis ulang adalah commit yang hanya Anda lihat (atau yang sepenuhnya milik Anda).
Merge — untuk branch bersama dan integrasi
Fitur yang sudah jadi digabung ke main atau develop. Beberapa orang bekerja di satu branch. Branch rilis perlu dikembalikan ke branch utama. Di sini penting untuk tidak menyentuh commit yang sudah dipublikasikan, dan merge adalah satu-satunya pilihan yang benar.
Aturan sederhana untuk memilih
Jika commit itu hanya milik Anda, boleh di-rebase. Jika sudah ada yang mengunduhnya, hanya boleh di-merge.
Pola kerja tipikal untuk tim
| Pola | Cara kerjanya | Cocok untuk |
|---|---|---|
| Hanya merge | Fitur digabung dengan --no-ff, sinkronisasi dengan git merge main | Pemula Git, tim yang mengutamakan kronologi lengkap dan rollback yang mudah |
| Rebase + merge | Branch di-rebase ke main sebelum digabung, lalu commit merge dengan --no-ff | Tim yang butuh riwayat bersih sekaligus batas fitur yang jelas |
| Rebase + fast-forward | Branch di-rebase lalu digabung dengan pemajuan; riwayat sepenuhnya linier | Tim kecil dengan commit atomik yang rapi |
| Squash merge | Setiap pull request menjadi satu commit di main | Tim dengan tugas pendek, tempat riwayat detail branch tidak diperlukan |
Di GitHub dan GitLab, pola-pola ini sesuai dengan tombol «Create a merge commit», «Rebase and merge», dan «Squash and merge». Sebaiknya aktifkan di pengaturan repositori hanya satu cara yang dipilih, agar riwayat tidak menjadi campuran berbagai gaya.
Pengaturan yang mengunci pilihan
# pull tanpa commit merge yang tidak perlu
git config --global pull.rebase true
# atau: pull hanya dengan pemajuan, selain itu gagal — Anda yang memutuskan
git config --global pull.ff only
# selalu commit merge saat menggabungkan fitur
git config --global merge.ff false
Berhati-hatilah dengan merge.ff false: pengaturan ini juga berlaku untuk git pull dalam mode merge. Banyak orang lebih memilih tidak mengaturnya secara global dan menulis --no-ff secara eksplisit saat menggabungkan fitur.
Contoh: satu tugas dengan dua gaya
Berikut skenario nyata. Anda mengerjakan fitur pembayaran di feature/payment selama tiga hari, sementara di main sudah masuk lima tugas dari rekan lain. Sebelum membuat pull request, Anda perlu menarik main terbaru dan memastikan semuanya berjalan.
Dengan merge
git switch feature/payment
git fetch origin
git merge origin/main
# konflik diselesaikan sekali, lalu git add, git commit
git push
Branch mendapat commit «Merge remote-tracking branch 'origin/main' into feature/payment». Push berjalan biasa, dan rekan yang melihat branch itu tidak terganggu. Jika sinkronisasi dilakukan setiap hari, akan ada tiga commit seperti ini di branch, dan jika digabung tanpa squash, semuanya ikut masuk ke main.
Dengan rebase
git switch feature/payment
git fetch origin
git rebase origin/main
# konflik diselesaikan sepanjang jalan, pada setiap commit: git add, git rebase --continue
git rebase -i origin/main # opsional: gabungkan commit coretan
git push --force-with-lease
Branch terlihat seolah-olah baru dimulai pagi ini dari main yang terbaru, tidak ada commit berlebih, dan reviewer lebih mudah membaca perubahan langkah demi langkah. Harganya adalah force push, dan Anda harus memastikan tidak ada orang lain yang masih menambahkan commit ke branch itu.
Apa yang akhirnya dilihat main
Saat digabung lewat pull request, perbedaannya tetap terlihat. Gaya merge menghasilkan graf dengan percabangan dan commit sinkronisasi, sedangkan gaya rebase menghasilkan rangkaian commit fitur yang rapi, yang bisa digabung dengan pemajuan atau dengan satu commit merge. Kodenya akan sama, asalkan konfliknya diselesaikan dengan cara yang sama.
Cara mengambil keputusan di tim
Jawab beberapa pertanyaan berikut. Apakah beberapa orang bekerja di branch yang sama? Jika ya, rebase tidak cocok untuk branch itu. Seberapa berpengalaman tim dengan Git? Jika anggotanya sering pemula, mulailah dengan merge dan squash merge, karena keduanya lebih memaafkan kesalahan. Apakah diperlukan kronologi lengkap untuk audit dan analisis insiden? Jika ya, commit merge untuk setiap fitur sangat berguna. Apakah git log yang mudah dibaca dan git bisect yang sering dipakai itu penting? Jika ya, pilih rebase dan riwayat linier.
Catat keputusan di CONTRIBUTING atau README repositori, dan aktifkan proteksi branch utama: larang force push, wajibkan pull request, dan tetapkan cara penggabungan yang diizinkan. Aturan yang dikunci dalam pengaturan lebih andal daripada kesepakatan lisan.
Kesalahpahaman yang sering terjadi
- «Rebase itu tingkat lanjut, merge untuk pemula». Tidak benar: keduanya alat untuk tugas yang berbeda. Developer berpengalaman memakai keduanya.
- «Commit merge itu sampah». Commit sinkronisasi memang sering berisik. Tetapi commit merge saat fitur digabung adalah titik penting: dari situ satu tugas utuh bisa dilihat dan dibatalkan.
- «Setelah rebase konfliknya berkurang». Konfliknya sama, karena baris yang sama tetap berubah. Rebase hanya membagi konflik ke setiap commit, sedangkan merge menyelesaikannya sekaligus.
- «Rebase menghilangkan commit». Commit lama tetap ada di
git reflogdan bisa dipulihkan, sampai dibersihkan oleh garbage collector.
Ringkasan
Memilih antara merge dan rebase berarti memilih antara kronologi yang jujur dan riwayat linier yang rapi. Merge aman dan menjaga konteks; rebase memberi kerapian tetapi menulis ulang commit. Praktik yang paling andal adalah mengombinasikannya: rebase dan rapikan branch Anda selama branch itu masih milik Anda, lalu masukkan pekerjaan yang sudah jadi ke branch bersama lewat merge atau squash sesuai aturan tim. Yang terpenting adalah menyepakati pola dan menguncinya di pengaturan repositori. Kedua strategi serta kerja dengan branch dalam tim dibahas dengan praktik dalam kursus Git.
Pertanyaan umum
Mana yang sebaiknya dipakai untuk git pull, merge atau rebase?
Untuk memperbarui branch lokal, rebase lebih nyaman: commit Anda yang belum dipublikasikan akan berada di atas versi terbaru dari remote tanpa commit merge tambahan. Aktifkan dengan git config --global pull.rebase true.
Bolehkah merge dan rebase dipakai bersamaan dalam satu proyek?
Boleh, dan ini pendekatan yang paling umum: rebase untuk branch pribadi, merge untuk branch bersama. Yang penting, aturannya diketahui seluruh tim.
Apa yang sebaiknya dipilih pemula?
Mulailah dengan merge: ia tidak menulis ulang riwayat, dan lebih sulit membuat kerusakan. Pelajari rebase pada branch lokal setelah memahami reflog dan force push.
Apakah pilihan strategi memengaruhi kode akhirnya?
Tidak. Jika konflik diselesaikan dengan cara yang sama, isi berkas akhirnya identik. Yang berbeda hanyalah riwayat commit yang tercatat.
Apa bedanya squash merge dengan rebase?
Squash merge memampatkan seluruh branch menjadi satu commit baru di branch utama, sedangkan rebase memindahkan setiap commit satu per satu. Keduanya menghasilkan riwayat linier, tetapi squash kehilangan detail langkah-langkahnya.
Topik ini dibahas mendalam dengan praktik di kursus “Git dari Nol hingga Pengembang Percaya Diri”.
- Proses Git di Tim Nyata: Alur Kerja Mana yang Dipilih
- Alat Lanjutan: rebase, stash, cherry-pick, dan tag