Perbedaan Git Merge dan Rebase

merge dan rebase adalah dua cara menggabungkan perubahan dari satu branch ke branch lain. sebelum mempelajari ini, pastikan kalian sudah paham panduan Git branching dan perintah dasar Git.
aturan yang saya pegang: merge untuk branch yang sudah dipush dan dipakai bersama, rebase untuk branch pribadi yang belum dipush. saya pernah me-rebase branch yang sudah dipakai orang lain, dan hasilnya jauh lebih berantakan daripada yang seharusnya. artikel ini menjelaskan kenapa aturan sederhana itu penting.
1. merge: gabung dengan history lengkap
merge adalah cara paling aman dan umum untuk gabung branch. tidak ada history yang ditulis ulang, semua commit asli tetap ada.
# Pindah ke branch target
git checkout main
# Gabung feature ke main
git merge feature
hasil: commit history tetap lengkap, ada satu merge commit baru.
A---B---C---D---E (main)
\
F---G---H (feature)
\
M (merge commit baru)
penjelasan visual:
AsampaiEadalah commit di main.F,G,Hadalah commit di branch feature.Madalah merge commit baru yang menggabungkan main dan feature. commit ini punya dua parent (E dan H).- semua commit asli tetap ada di history. bisa dilacak kapan branch dibuat dan commit apa saja yang ada di sana.
2. fast-forward merge
kasus khusus merge yang paling sederhana. terjadi kalau main tidak punya commit baru sejak branch fitur dibuat:
A---B---C---D---E (main + feature, pointer sama)
git checkout main
git merge feature
# Fast-forward
git cuma majukan pointer main dari E ke posisi E (yang ternyata sama dengan ujung feature). tidak ada merge commit baru. history kelihatan linear.
fast-forward terjadi otomatis kalau tidak ada conflict dan branch target tidak diverged. untuk dapet merge commit eksplisit, pakai --no-ff:
git merge --no-ff feature
# Paksa bikin merge commit meski bisa fast-forward
--no-ff berguna untuk dokumentasi: di history jelas kelihatan ada branch fitur yang di-merge.
3. rebase: tulis ulang history
rebase memindahkan commit fitur ke ujung branch target. dari luar kelihatan seperti fitur dibuat dari awal di atas commit main terbaru.
# Pindah ke branch fitur
git checkout feature
# Pindahkan commit fitur ke ujung main
git rebase main
hasil: history linear, tapi commit fitur punya ID baru (karena dipindah).
A---B---C---D---E (main)
\
F'---G'---H' (feature : commit baru F', G', H')
penjelasan visual:
F,G,Hadalah commit fitur asli. setelah rebase, jadiF',G',H'dengan ID baru.- commit ID baru karena parent berubah.
F'parent-nyaE, bukanBlagi. - dari luar, kelihatan seperti fitur dibuat dari awal di atas main terbaru.
4. perbandingan lengkap
| Aspek | Merge | Rebase |
|---|---|---|
| history | menyimpan semua commit | linear, seolah-olah fitur dibuat dari ujung |
| commit merge | ada (kecuali fast-forward) | tidak ada |
| ubah history | tidak | ya (tulis ulang commit) |
| aman untuk branch publik | ya | tidak |
| conflict | sekali di merge commit | bertahap per commit |
| trackability | jelas branch mana gabung mana | kelihatan satu garis lurus |
5. aturan emas rebase
“jangan rebase branch publik/shared.”
kenapa:
- rebase bikin commit ID baru.
- tim yang sudah pull branch original punya history dengan commit ID lama.
- saat mereka pull versi kamu yang sudah di-rebase, git tidak recognize commit baru, dan history jadi berantakan (duplikat commit, konflik berulang).
rebase cuma aman untuk:
- branch fitur lokal yang belum di-push.
- branch pribadi yang hanya kamu pakai.
kalau tim kamu sudah push branch, gunakan merge, bukan rebase.
6. workflow ideal (rebase + merge)
cara paling umum di tim: pakai rebase untuk update branch lokal, lalu merge ke main.
# 1. Di branch fitur, ambil perubahan terbaru dari main
git checkout feature
git rebase main
# 2. Test, pastikan tidak ada conflict
# (jalankan test, build, dll)
# 3. Push branch fitur (force push karena ID berubah)
git push --force-with-lease
# 4. Pindah ke main, merge feature (jadi fast-forward)
git checkout main
git merge feature
hasil: history main kelihatan linear, tidak ada commit merge. semua kerjaan fitur terdokumentasi dengan baik di branch.
--force-with-lease lebih aman dari --force biasa: dia hanya force-push kalau belum ada commit baru di remote yang belum kamu pull. ini mencegah kehilangan kerjaan tim.
7. interactive rebase
interactive rebase adalah fitur powerful untuk edit history commit secara manual sebelum push.
# Edit 3 commit terakhir
git rebase -i HEAD~3
git akan buka editor dengan daftar commit:
pick abc1234 Commit pertama
pick def5678 Commit kedua
pick 9abcdef Commit ketiga
ganti pick dengan perintah lain:
| Perintah | Fungsi |
|---|---|
pick | pakai commit apa adanya |
reword | pakai tapi edit pesan |
edit | pakai tapi pause untuk edit isi |
squash | gabung dengan commit sebelumnya |
fixup | sama seperti squash tapi buang pesan |
drop | hapus commit |
contoh pakai squash untuk gabung 3 commit jadi 1:
pick abc1234 Tambah validasi form
squash def5678 Fix bug di validasi
squash 9abcdef Tambah pesan error
hasil: 3 commit di atas jadi 1 commit dengan pesan gabungan. history lebih rapi.
contoh edit pesan commit:
pick abc1234 Commit pertama
reword def5678 Commit kedua
pick 9abcdef Commit ketiga
git akan pause di commit def5678 dan buka editor untuk edit pesannya.
contoh hapus commit:
pick abc1234 Commit pertama
drop def5678 Commit kedua (hapus)
pick 9abcdef Commit ketiga
commit def5678 hilang dari history. berguna kalau ada commit debug yang tidak perlu di-push.
8. squash merge untuk PR rapi
kalau branch fitur punya banyak commit kecil, squash merge gabung semuanya jadi 1 commit saat merge ke main.
cara di GitHub: klik tombol “Squash and merge” saat merge PR.
# Cara manual: rebase + squash
git checkout feature
git rebase -i main
# (squash semua commit jadi 1)
# Lalu push
git push --force-with-lease
# Merge ke main
git checkout main
git merge --squash feature
git commit -m "Tambah fitur X"
keuntungan squash merge: history main tetap clean, satu commit per fitur. kekurangan: detail commit kecil di branch hilang dari history main.
9. cherry-pick untuk ambil satu commit
cherry-pick mengambil satu commit spesifik dari branch lain dan tempel ke branch sekarang. beda dengan merge/rebase yang ambil semua commit sekaligus.
# Dari branch main, ambil satu commit dari branch hotfix
git checkout main
git cherry-pick <commit-hash>
contoh: ada bugfix urgent di branch hotfix. commit abc1234 fix bug itu. main juga butuh fix-nya tapi tidak mau merge semua perubahan hotfix.
git log --oneline hotfix
# def5678 Tambah fitur B
# abc1234 Fix bug kritis
# 789abcd Tambah fitur A
git checkout main
git cherry-pick abc1234
# Sekarang main punya fix bug tanpa fitur A dan B
berguna untuk backport fix dari main ke branch release yang sudah lama, atau sebaliknya.
10. cara undo rebase yang salah
rebase bisa di-undo pakai git reflog. reflog mencatat semua perubahan HEAD, jadi bisa kembali ke state sebelum rebase.
# Lihat history HEAD
git reflog
# abc1234 HEAD@{0}: rebase (finish)
# def5678 HEAD@{1}: rebase (start)
# 789abcd HEAD@{2}: checkout: moving from main to feature
# ...
# Kembali ke state sebelum rebase
git reset --hard HEAD@{2}
git reset --hard bisa berbahaya kalau ada kerjaan yang belum di-commit. selalu cek reflog dulu dan pastikan target commit benar.
kalau rebase sudah di-push (dengan force), undo lebih tricky. tim yang sudah pull history baru akan punya history berbeda. biasanya solusinya: revert commit, atau re-rebase ke state yang benar.
11. reflog: safety net
reflog adalah catatan internal git tentang semua perubahan pointer. setiap checkout, commit, merge, rebase, reset akan tercatat.
# Lihat reflog
git reflog
# Lihat reflog untuk branch tertentu
git reflog show feature
# Lihat reflog dengan tanggal
git reflog --date=iso
reflog disimpan 90 hari secara default. pakai reflog kapan saja untuk:
- undo rebase/merge/reset yang salah
- cari commit yang “hilang”
- lihat apa yang dilakukan 2 minggu lalu
12. contoh conflict resolution
saat rebase/merge, kadang ada conflict (file yang sama diedit di dua branch). git tandai dengan <<<<<<<, =======, >>>>>>>:
<<<<<<< HEAD
nilai = 100
=======
nilai = 200
>>>>>>> feature
cara resolve:
- buka file, edit bagian antara marker.
- hapus marker
<<<<<<<,=======,>>>>>>>. - simpan file.
git add <file>.git rebase --continue(kalau sedang rebase) ataugit commit(kalau sedang merge).
contoh pilih versi main (HEAD):
# nilai = 100 (pilih versi HEAD)
atau gabung dua versi:
# Komentari bahwa nilai awalnya 100, dinaikkan ke 200
nilai = 200
bedanya conflict di merge vs rebase:
- merge: satu kali conflict di merge commit.
- rebase: bertahap per commit. kalau rebase 5 commit dan conflict di commit ke-3, setelah resolve, bisa conflict lagi di commit ke-4 dan ke-5.
13. alat bantu visual: gitk dan sourcetree
untuk visualisasi history, beberapa tools berguna:
- gitk (built-in):
gitk --allbuka GUI history. - sourcetree: GUI client gratis dari Atlassian.
- gitkraken: GUI client modern, ada versi gratis.
- vs code: ekstensi “Git History” atau “GitLens” untuk lihat history inline.
tools GUI ini sangat membantu untuk memahami visual history dan resolve conflict.
14. config modern 2026: pull –rebase, autostash & rerere
di tim modern 2025-2026, hampir semua set pull pakai rebase biar tidak bikin merge commit sampah:
# bikin pull jadi rebase, bukan merge
git config --global pull.rebase true
# autostash: simpan kerjaan yang belum di-commit, pull, lalu pop lagi
git config --global rebase.autoStash true
# aktifkan rerere: reuse recorded resolution untuk conflict yang sama
git config --global rerere.enabled true
rerere (reuse recorded resolution) menyimpan cara kamu resolve conflict sebelumnya, jadi kalau conflict sama muncul lagi saat rebase 5 commit, git auto-apply solusi lama. aktifkan sekali, hemat waktu berhari-hari.
sekalian ganti checkout dengan switch/restore yang lebih jelas (sejak Git 2.23, switch tidak lagi experimental di 2.51):
git switch main # bukan checkout main
git switch -c feature # bukan checkout -b
git restore --source=main -- file.txt # bukan checkout file
15. workflow 2026: GitHub Flow vs Merge Queue
2026 sudah bukan cuma “merge atau rebase”, tapi bagaimana tim menggabungkannya:
- GitHub Flow (paling umum): branch fitur → PR →
Squash and merge→ main linear. cocok startup & tim kecil. main selalu linear satu commit per fitur. - Trunk-based + rebase: semua rebase ke main tiap hari, PR kecil <200 baris, merge dengan
Rebase and mergeatauFast-forward only. butuh CI cepat (<10 menit). - Merge Queue (2024+): GitHub/GitLab sekarang ada
Merge Queue— PR yang sudah approve otomatis di-rebase ke main terbaru, di-test, baru di-merge. tidak perlu manualgit pull --rebasesebelum merge, queue yang tangani. aktifkan di repo Settings → Merge Queue.
pilih sesuai ukuran tim: 1-5 orang → GitHub Flow squash, 5-20 orang → rebase+merge biasa, 20+ orang → wajib merge queue + pull.rebase.
Kesimpulan
- merge: gabung branch dengan history lengkap, ada merge commit, aman untuk branch publik
- rebase: tulis ulang history jadi linear, tidak ada merge commit, hanya untuk branch pribadi
- fast-forward merge: khusus saat branch target tidak diverged, cuma majukan pointer
- interactive rebase (
git rebase -i): edit history (squash, reword, drop) sebelum push - squash merge: gabung semua commit fitur jadi 1 saat merge, history main tetap bersih
- cherry-pick: ambil satu commit spesifik, bukan semua
- reflog: safety net untuk undo rebase/merge/reset yang salah
- workflow ideal:
rebase maindi fitur → test → push force →merge --no-ffdi main - aturan emas: jangan rebase branch publik/shared
Baca Juga Mengenai :
Pertanyaan yang Sering Diajukan
Apa perbedaan utama Git merge dan rebase?
merge menggabungkan dua branch sambil mempertahankan seluruh history asli plus satu merge commit, sedangkan rebase menulis ulang commit fitur sehingga tampak seolah dibuat dari ujung branch terbaru dan history menjadi linear.
Kapan sebaiknya pakai merge dan kapan rebase?
pakai merge untuk branch yang sudah dipush dan dipakai bersama tim karena aman terhadap history, pakai rebase untuk branch pribadi yang belum dipush agar history tetap bersih.
Kenapa tidak boleh rebase branch yang sudah dipush?
rebase membuat commit ID baru sehingga history yang sudah dipunyai rekan tim tidak cocok lagi dengan milikmu. saat mereka pull, hasilnya duplikat commit dan konflik berulang.
Apa itu squash di Git?
menggabungkan beberapa commit kecil menjadi satu commit rapi, biasanya lewat git rebase -i (interactive rebase) sebelum branch difinalkan.
Apa itu interactive rebase?
cara edit history commit secara manual: gabung commit, edit pesan, hapus, atau reorder. pakai git rebase -i HEAD~n untuk n commit terakhir.
Apa itu fast-forward merge?
merge yang cuma majukan pointer branch tanpa bikin commit baru. terjadi kalau branch target tidak punya commit baru sejak branch fitur dibuat.
Bagaimana cara membatalkan rebase yang salah?
pakai git reflog untuk lihat history HEAD sebelumnya, lalu git reset --hard ke commit sebelum rebase. asalkan belum di-force-push dan belum di-garbage-collect.
Apa itu cherry-pick dan apa bedanya dengan merge/rebase?
cherry-pick ambil satu commit spesifik dari branch lain dan tempel ke branch sekarang. beda dengan merge/rebase yang ambil semua commit sekaligus.

