Yan yana
MergevsSquash Merge
Merge ile squash merge arasındaki fark nedir?
Güncellendi 2 dk okuma7 fark
Kısaca
Normal merge bir branch'in her commit'ini korur ve onu bir merge commit'le bağlar; squash merge ise branch'in bütün commit'lerini tek bir yeni commit'te toplar.
Merge
Git'te merge, bir branch'teki değişiklikleri başka bir branch'e katarak ayrı geliştirme hatlarını tek ve ortak bir geçmişte yeniden birleştirir.
Merge sayfasını okuSquash Merge
Squash merge, bir branch'teki tüm commit'leri hedef branch üzerinde tek bir yeni commit'te birleştirir; böylece ana geçmiş kısa ve okunması kolay kalır.
Squash Merge sayfasını okuMerge ve Squash Merge karşılaştırması
| Özellik | Merge | Squash Merge |
|---|---|---|
| Hedefe eklenen commit'ler | Branch'in bütün commit'leri, artı bir merge commit | Bütün değişiklikleri taşıyan tek bir yeni commit |
| Yeni commit'in ebeveynleri | İki: hedef branch ve merge edilen branch | Bir: hedef branch'teki önceki commit |
| Geçmiş | Eksiksiz ve dallanan; her adımı gösterir | Kısa ve doğrusal; değişiklik başına tek commit |
| Branch merge edilmiş sayılır mı | Evet; Git, commit'lerinin dahil olduğunu bilir | Hayır; branch sonrasında silinmelidir |
| Özelliği geri almak | Merge commit üzerinde git revert -m 1 | Tek bir commit için düz bir git revert |
| Komut satırında | git merge feature | git merge --squash feature, ardından git commit |
| En uygun olduğu yer | Uzun ömürlü branch'ler ve anlamlı tek tek commit'ler | Dağınık ara commit'ler içeren küçük pull request'ler |
Fark, açıklamalı
İkisi de bitmiş bir branch'i main gibi bir hedef branch'e getirir ve ikisi de aynı nihai kodu bırakır. Normal merge, branch'teki her commit'i korur ve iki branch de ilerlemişse iki ebeveynli bir merge commit ekler. Squash merge ise branch'in bütün değişikliklerini alır ve hedef branch'e tek ebeveynli, tek bir yeni commit olarak kaydeder.
Fark, geçmişin neyi hatırladığındadır. Normal bir merge'den sonra git log, geliştiricinin attığı her adımı ve branch'in tam olarak nerede ayrılıp nerede geri döndüğünü gösterir. Squash merge'den sonra ise main pull request başına tek bir commit gösterir; bu, okumayı, geri almayı ve git bisect ile aramayı kolaylaştırır, ama tek tek commit'ler ve branch'e olan bağ oradan kaybolur.
Kod barındırma platformları pull request'lerde ikisini de, çoğu zaman 'Create a merge commit' ve 'Squash and merge' adlarıyla sunar; pek çok ekip de her depo için birini seçer. Squash, 'fix typo' commit'leriyle dolu küçük ve odaklı pull request'lere uyar; normal merge ise uzun ömürlü branch'lere ya da commit'leri tek başına anlam taşıyacak şekilde özenle yazılmış branch'lere uyar. Git, squash edilmiş bir branch'i merge edilmiş olarak kaydetmediği için onu sonrasında silin: üzerine yeniden geliştirmek, tekrarlanan değişikliklere ve çakışmalara yol açar.
Sık yapılan bir yanlış, squash'ın emeği çöpe attığını düşünmektir. Kodun hepsi oradadır ve platform özgün commit'leri genellikle pull request'te saklar; yalnızca hedef branch'in geçmişi özetlenir. Bir başka yanlış da normal merge'ün her zaman bir merge commit eklediğidir: hedef branch değişmediyse Git, --no-ff vermediğiniz sürece onu yalnızca ileri sarar (fast-forward).
Hangisini kullanmalısınız?
Merge şu durumlarda doğru seçim:
- Branch'teki her commit anlamlı ve tek başına saklanmaya değer.
- Branch uzun ömürlü ya da paylaşılıyor ve başkaları onun üzerine geliştiriyor.
- İşin nasıl yapıldığının birebir kaydını istiyorsunuz.
Squash Merge şu durumlarda doğru seçim:
- Pull request'ler küçük ve commit'leri çoğunlukla yarım kalmış ara adımlar.
mainüzerinde her değişiklik için incelenmiş tek bir commit olmasını istiyorsunuz.- Bir özelliği tek bir commit olarak geri almak ya da bulmak istiyorsunuz.
Bir feature branch'ini iki yolla merge etmek
# Regular merge: keep every commit, add a merge commit
git switch main
git merge --no-ff feature
git log --oneline --graph
# * Merge branch 'feature'
# |\
# | * Fix typo in signup form
# | * Add signup form
# |/# Squash merge: stage all the changes, commit them once
git switch main
git merge --squash feature
git commit -m "Add signup form"
git branch -D feature # Git doesn't see it as merged
git log --oneline
# * Add signup formSık sorulan sorular
Squash merge kötü bir uygulama mı?
Hayır, pull request başına tek commit isteyen ekipler için yaygın bir varsayılandır. Yalnızca tek tek commit'ler hedef branch'in geçmişinde kalması gereken bir anlam taşıyorsa uygun düşmez.
Squash merge'den sonra özgün commit'leri hâlâ görebilir miyim?
Genellikle evet: barındırma platformundaki pull request'te ve silinene kadar branch'in kendisinde. Yalnızca hedef branch'in geçmişinin parçası değildirler.
Squash'tan sonra Git neden branch'imin merge edilmediğini söylüyor?
Çünkü squash commit'in tek bir ebeveyni vardır ve branch'in commit'lerine hiçbir bağı yoktur. Git içeriği değil commit'leri karşılaştırır; bu yüzden değişikliklerin geldiğini doğruladıktan sonra branch'i git branch -D ile silin.