Strategi merge di GitHub

Perbandingan tiga strategi merge di GitHub: merge commit, squash, dan rebase and merge.

Daftar isi

Ketika sebuah pull request disetujui, platform menawarkan beberapa cara untuk menggabungkannya, dan setiap cara menulis riwayat dengan bentuk yang berbeda. Topik ini membandingkan tiga strategi merge di GitHub, yaitu merge commit, squash and merge, dan rebase and merge, beserta konsekuensi masing-masing pada riwayat. Mekanika Git di balik ketiganya sudah dikenal, sehingga pemilihannya menjadi soal bentuk riwayat yang diinginkan tim.

Tiga strategi dan bentuk riwayatnya#

Strategi merge commit menjalankan merge tiga arah biasa, sehingga seluruh commit branch tersalin utuh dan satu commit merge dengan dua induk menandai penyatuannya. Riwayatnya paling jujur, karena keberadaan branch dan seluruh tahapan pengerjaannya terlihat, dan hargaannya adalah grafis yang semakin rapat pada proyek yang sibuk.

Strategi squash and merge menekan seluruh commit branch menjadi satu commit baru pada main, dengan pesan yang dirangkum dari permintaannya. Riwayatnya paling rapi, yaitu satu commit per permintaan, dan hargaannya adalah hilangnya tahapan pengerjaan di dalamnya, meskipun link menuju permintaannya tetap tersimpan pada commit tersebut.

Strategi rebase and merge memutar commit branch ke atas main tanpa membuat commit merge, sehingga riwayatnya lurus dan setiap commit pengerjaan tetap terpisah. Ia berada di antara keduanya: tahapan tersimpan, tetapi tanpa penanda permintaan pada riwayat, dan hash commit berganti sebagaimana sifat rebase.

AspekMerge commitSquash and mergeRebase and merge
Jumlah commit di mainseluruh commit + commit mergesatu commitseluruh commit, hash baru
Penanda permintaancommit mergepesan satu committidak ada
Bentuk riwayatpohonlurus dan padatlurus

Merge commit dalam praktik#

Mekanikanya sama dengan merge tiga arah, dan opsi --no-ff memastikan bentuknya tetap dipertahankan meskipun fast-forward memungkinkan, sebagaimana perilaku tombol merge di platform.

bash
# tanggal commit ditetapkan agar keluaran contoh dapat direproduksi secara persis
export GIT_AUTHOR_DATE="2026-11-01T09:00:00+07:00"
export GIT_COMMITTER_DATE="2026-11-01T09:00:00+07:00"
bash
rm -rf /tmp/lab-strategi
mkdir /tmp/lab-strategi
cd /tmp/lab-strategi
git init -b main
git config user.name "Budi"
git config user.email "[email protected]"
printf "Dasar aplikasi.\n" > app.md
git add app.md
git commit -m "Dasar aplikasi"
git switch -c feature/laporan
printf "Dasar aplikasi.\nLaporan bulanan.\n" > app.md
git commit -am "Laporan bulanan"
printf "Dasar aplikasi.\nLaporan bulanan.\nEkspor PDF.\n" > app.md
git commit -am "Ekspor PDF"
git switch main
git merge --no-ff feature/laporan -m "Merge feature/laporan"
git log --oneline --graph
text Keluaran
Initialized empty Git repository in /tmp/lab-strategi/.git/
[main (root-commit) 38532e7] Dasar aplikasi
 1 file changed, 1 insertion(+)
 create mode 100644 app.md
Switched to a new branch 'feature/laporan'
[feature/laporan a401c72] Laporan bulanan
 1 file changed, 1 insertion(+)
[feature/laporan 3d89ffb] Ekspor PDF
 1 file changed, 1 insertion(+)
Switched to branch 'main'
Merge made by the 'ort' strategy.
 app.md | 2 ++
 1 file changed, 2 insertions(+)
*   53039d4 Merge feature/laporan
|\
| * 3d89ffb Ekspor PDF
| * a401c72 Laporan bulanan
|/
* 38532e7 Dasar aplikasi

Commit merge menyimpan dua induk dan seluruh tahapan branch tetap terlihat. Membatalkan keseluruhan fitur pun menjadi satu langkah revert terhadap commit merge-nya, dan kemudahan inilah yang menjadikan strategi ini pilihan tim dengan fitur besar.

Squash dalam praktik#

Mekanika squash pada Git lokal adalah git merge --squash, yang menarik seluruh perubahan branch ke staging area tanpa membuat commit, lalu satu commit menyimpannya.

bash
rm -rf /tmp/lab-squash
mkdir /tmp/lab-squash
cd /tmp/lab-squash
git init -b main
git config user.name "Budi"
git config user.email "[email protected]"
printf "Dasar aplikasi.\n" > app.md
git add app.md
git commit -m "Dasar aplikasi"
git switch -c feature/laporan
printf "Dasar aplikasi.\nLaporan bulanan.\n" > app.md
git commit -am "Laporan bulanan"
printf "Dasar aplikasi.\nLaporan bulanan.\nEkspor PDF.\n" > app.md
git commit -am "Ekspor PDF"
git switch main
git merge --squash feature/laporan
git commit -m "Fitur laporan dan ekspor PDF"
git log --oneline
text Keluaran
Initialized empty Git repository in /tmp/lab-squash/.git/
[main (root-commit) 38532e7] Dasar aplikasi
 1 file changed, 1 insertion(+)
 create mode 100644 app.md
Switched to a new branch 'feature/laporan'
[feature/laporan a401c72] Laporan bulanan
 1 file changed, 1 insertion(+)
[feature/laporan 3d89ffb] Ekspor PDF
 1 file changed, 1 insertion(+)
Switched to branch 'main'
Updating 38532e7..3d89ffb
Fast-forward
Squash commit -- not updating HEAD
 app.md | 2 ++
 1 file changed, 2 insertions(+)
[main 5961852] Fitur laporan dan ekspor PDF
 1 file changed, 2 insertions(+)
5961852 Fitur laporan dan ekspor PDF
38532e7 Dasar aplikasi

Dua commit pengerjaan menjadi satu commit pada main, dan pesannya ditulis oleh penggabung, bukan oleh penulis commit aslinya. Pada platform, penulisnya tetap tercatat sebagai pembuat perubahan, sedangkan penggabung menjadi commiternya, sebagaimana pembagian author dan committer yang dibahas pada anatomi commit.

Rebase and merge dalam praktik#

Strategi ketiga menjalankan rebase sebagaimana dibahas pada modul penulisan ulang riwayat, lalu memajukan main.

bash
rm -rf /tmp/lab-rebase-gh
mkdir /tmp/lab-rebase-gh
cd /tmp/lab-rebase-gh
git init -b main
git config user.name "Budi"
git config user.email "[email protected]"
printf "Dasar aplikasi.\n" > app.md
git add app.md
git commit -m "Dasar aplikasi"
git switch -c feature/laporan
printf "Dasar aplikasi.\nLaporan bulanan.\n" > app.md
git commit -am "Laporan bulanan"
git switch main
printf "Dasar aplikasi.\nCatatan gaya.\n" > gaya.md
git add gaya.md
git commit -m "Catatan gaya"
git switch feature/laporan
git rebase main
git switch main
git merge feature/laporan
git log --oneline --graph
text Keluaran
Initialized empty Git repository in /tmp/lab-rebase-gh/.git/
[main (root-commit) 38532e7] Dasar aplikasi
 1 file changed, 1 insertion(+)
 create mode 100644 app.md
Switched to a new branch 'feature/laporan'
[feature/laporan a401c72] Laporan bulanan
 1 file changed, 1 insertion(+)
Switched to branch 'main'
[main 617a8cc] Catatan gaya
 1 file changed, 2 insertions(+)
 create mode 100644 gaya.md
Switched to branch 'feature/laporan'
Rebasing (1/1)
Successfully rebased and updated refs/heads/feature/laporan.
Switched to branch 'main'
Updating 617a8cc..68ab49a
Fast-forward
 app.md | 1 +
 1 file changed, 1 insertion(+)
* 68ab49a Laporan bulanan
* 617a8cc Catatan gaya
* 38532e7 Dasar aplikasi

Riwayatnya lurus dengan setiap commit pengerjaan tetap terpisah, dan tidak ada commit merge yang menandai permintaannya. Pemilihan di antara ketiga strategi adalah kebijakan repository yang disetel pada pengaturannya di platform, dan banyak tim menetapkan satu strategi bawaan untuk seluruh permintaan agar riwayatnya tetap dapat diprediksi.

Ringkasan#

  • Merge commit menyimpan seluruh tahapan beserta penandanya, dan pembatalan satu fitur menjadi revert pada commit merge.
  • Squash and merge menekan satu permintaan menjadi satu commit yang rapi, dengan penulis asli tetap tercatat.
  • Rebase and merge menghasilkan riwayat lurus dengan tahapan terpisah, tetapi tanpa penanda permintaan dan dengan hash baru.
  • Pilihan strategi adalah kebijakan repository yang ditetapkan pada pengaturan platform dan dipakai secara konsisten.

Referensi#