Ana içeriğe geç

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ı oku

Squash 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ı oku

Merge ve Squash Merge karşılaştırması

ÖzellikMergeSquash Merge
Hedefe eklenen commit'lerBranch'in bütün commit'leri, artı bir merge commitBütün değişiklikleri taşıyan tek bir yeni commit
Yeni commit'in ebeveynleriİki: hedef branch ve merge edilen branchBir: hedef branch'teki önceki commit
GeçmişEksiksiz ve dallanan; her adımı gösterirKı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 bilirHayır; branch sonrasında silinmelidir
Özelliği geri almakMerge commit üzerinde git revert -m 1Tek bir commit için düz bir git revert
Komut satırındagit merge featuregit merge --squash feature, ardından git commit
En uygun olduğu yerUzun ömürlü branch'ler ve anlamlı tek tek commit'lerDağı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

Mergebash
# 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 Mergebash
# 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 form

Sı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.

Daha fazla

Ayarlar