Karşılaştırma

Git merge mi rebase mi: ekibiniz için hangisini seçmeli?

Güncellendi: · Skillaria.Top

Hem merge hem rebase branch değişikliklerini birleştirir, ama geçmişe farklı davranır: merge mevcut geçmişi olduğu gibi bırakır ve bir birleştirme commit'i ekler; rebase ise kendi commit'lerinizi yeni bir tabanın üzerine yeniden yazar ve geçmişi doğrusal yapar. Pratik kural: rebase'i kendi yayımlanmamış commit'lerinizi düzenlemek için, merge'ü hazır işi ortak branch'lere katmak için kullanın.

Kısaca: merge ile rebase arasındaki fark

«Merge mi rebase mi» tartışması aslında hangisinin daha iyi komut olduğu hakkında değil; projenin hangi geçmişi görmek istediğiniz hakkındadır. İki komut da sonunda aynı kodla sonuçlanır. Fark, günlüğe yazılan yoldadır.

  • Merge, iki commit çizgisini birleştirir ve işin paralel ilerlediğini dürüstçe kaydeder. Mevcut commit'ler değişmez; iki ebeveyni olan bir merge commit'i eklenir.
  • Rebase, commit'lerinizi sanki işe en güncel base sürümünden başlamışsınız gibi yeniden yazar. Geçmiş düz bir çizgi gibi görünür, ama commit'ler yeni hash'ler alır.

Her komutun mekaniği — bayraklar, çakışma çözümü, interaktif mod — ayrı makalelerde anlatılmıştır. Burada yalnızca strateji seçimini ele alıyoruz.

İki durumda geçmiş nasıl görünür

Başlangıç durumu: feature branch'ini ayırdınız, iki commit yaptınız ve bu sırada main'e iki başkasının commit'i geldi.

          D---E        feature
         /
A---B---C---F---G      main

main üzerinde git merge feature sonrası:

          D---E
         /     \
A---B---C---F---G---M  main

feature üzerinde git rebase main ve ardından main'in ileri alınması sonrası:

A---B---C---F---G---D'---E'   main

İlk durumda geçmiş, özelliğin paralel yapıldığını ve ne zaman birleştirildiğini gösterir. İkincisinde geçmiş baştan sona okunan bir hikâye gibidir; ama paralel çalışma izi kalmaz: D' ve E' rebase anında oluşturulmuş yeni commit'lerdir.

Merge ve rebase karşılaştırma tablosu

Ölçütgit mergegit rebase
Mevcut commit'lerDeğişmezYeni hash'lerle yeniden oluşturulur
Geçmişin biçimiDallanan, merge commit'li grafikDoğrusal
Ortak branch'lerde güvenlikHer zaman güvenliYayımlanmış commit'ler için tehlikeli
Force push gerekir miHayırBranch sunucudaysa evet
ÇakışmalarBir kez, merge commit'inde çözülürTaşınan her commit'te tekrar çıkabilir
«Nereden geldi» bilgisiKorunurKaybolur
Bütün bir özelliği geri almaTek git revert -m 1 ile merge commit'iHer commit ya da aralık için revert
git bisect ve git log kolaylığıGrafik okumak zorlaşırDaha kolay: tek düz çizgi
Başlangıç eşiğiDüşükDaha yüksek, geçmişin yeniden yazılmasını anlamak gerekir
Commit düzenleme (squash, reword)Yalnızca tümünü --squashEsnek: rebase -i

Merge'ün artıları ve eksileri

Artıları

  • Geçmişi bozmaz. Yayımlanmış her şey yerinde kalır. Eylemlerinizden sonra meslektaşlarınızın bir şeyi onarması gerekmez.
  • Çakışma bir kez çözülür. Branch'te 30 commit olsa bile her adımla değil, nihai durumla uğraşırsınız.
  • Bağlam korunur. Merge commit'inden hangi görevin ne zaman ana branch'e girdiği anlaşılır ve tamamen geri alınabilir.

Eksileri

  • Gürültülü grafik. Sık senkronizasyonda geçmiş «Merge branch 'main' into feature» commit'leriyle dolar ve git log --graph bir demiryolu şemasına döner.
  • Taslak commit'ler geçmişe girer. «wip», «fix», «bir düzeltme daha» gibi mesajlar sıkıştırılmazsa ana branch'te sonsuza dek kalır.

Rebase'in artıları ve eksileri

Artıları

  • Doğrusal, okunabilir geçmiş. Her commit kendi yerinde durur, git log değişiklik listesi gibi okunur ve git bisect hatalı commit'i daha kolay bulur.
  • İnceleme öncesi commit'leri düzenleyebilirsiniz: birleştirme, yeniden adlandırma, sıralama.
  • Ana branch ile senkronizasyondan gelen teknik merge commit'leri olmaz.

Eksileri

  • Geçmişi yeniden yazar. Yayımlanmış ortak bir branch'i rebase etmek, onu indiren herkesin işini bozar.
  • Sunucudaki branch'ler için force push gerekir; bu da disiplin ve --force-with-lease kullanımı demektir.
  • Tekrarlayan çakışmalar. Aynı bölge art arda birkaç commit'te çakışabilir.
  • Ara commit'ler derlenmeyebilir. Yeni tabana taşındıktan sonra eski commit'ler yeni ortamda hiç test edilmemiş olabilir.

Ne zaman hangisi

Rebase — kendi yerel işiniz için

Göndermeden önce branch'inizi güncelliyorsunuz: git pull --rebase. İnceleme için branch'i hazırlayıp taslak commit'leri temizlemek istiyorsunuz: git rebase -i. Kişisel feature branch'iniz main'in gerisinde kaldı: git rebase origin/main. Bu durumların hepsinde yalnızca sizin gördüğünüz ya da yalnızca size ait olan commit'ler yeniden yazılır.

Merge — ortak branch'ler ve entegrasyon için

Hazır bir özellik main ya da develop'a katılıyor. Branch üzerinde birkaç kişi çalışıyor. Bir release branch'ini ana branch'e geri katmanız gerekiyor. Burada yayımlanmış commit'lere dokunmamak önemlidir ve doğru seçenek merge'dür.

Basit seçim kuralı

Commit'ler yalnızca sizdeyse rebase yapabilirsiniz. Başkası onları indirdiyse yalnızca merge.

Ekip için hazır şemalar

ŞemaNasıl çalışırKime uygun
Yalnızca mergeÖzellikler --no-ff ile birleşir, senkronizasyon git merge main ileGit'te yeni olanlara, tam kronoloji ve basit geri almalar önemli olan ekiplere
Rebase + mergeBirleştirmeden önce branch main'in üzerine rebase edilir, ardından --no-ff ile merge commit'iHem temiz geçmişe hem de özellik sınırlarına ihtiyaç duyan ekiplere
Rebase + fast-forwardBranch rebase edilir ve ileri sarma ile birleşir; geçmiş tamamen doğrusal kalırDüzenli, atomik commit'leri olan küçük ekiplere
Squash mergeHer pull request, main'de tek bir commit olurKısa görevleri olan ve branch'in ayrıntılı geçmişine ihtiyaç duymayan ekiplere

GitHub ve GitLab'de bu şemalar «Create a merge commit», «Rebase and merge» ve «Squash and merge» düğmelerine karşılık gelir. Depo ayarlarında yalnızca seçilen yöntemi açık bırakmak, geçmişin farklı stillerin karışımına dönüşmesini önler.

Seçimi kalıcı kılan ayarlar

# pull, gereksiz merge commit'i olmadan
git config --global pull.rebase true

# ya da: yalnızca ileri sarma, yoksa hata — kararı siz verirsiniz
git config --global pull.ff only

# özellik birleştirmelerinde her zaman merge commit'i
git config --global merge.ff false

merge.ff false ayarına dikkat edin: merge modundaki git pull'u da etkiler. Birçok kişi bunu global olarak yazmaz, özellik birleştirirken --no-ff'i açıkça belirtir.

Örnek: aynı görev iki tarzda

Canlı bir senaryo düşünün. Üç gündür feature/payment branch'inde ödeme özelliği üzerinde çalışıyorsunuz ve bu sırada main'e beş başka görev girdi. Pull request açmadan önce taze main'i çekip her şeyin çalıştığını kontrol etmeniz gerekiyor.

Merge ile

git switch feature/payment
git fetch origin
git merge origin/main
# çakışmaları bir kez çözün, git add, git commit
git push

Branch'e «Merge remote-tracking branch 'origin/main' into feature/payment» commit'i eklenir. Push olağan şekilde geçer; branch'i inceleyen meslektaşlar hiçbir şey fark etmez. Bu senkronizasyonu her gün yaparsanız branch'te üç böyle commit olur ve squash yapılmadan birleştirilirse bunlar özellikle birlikte ana branch'e girer.

Rebase ile

git switch feature/payment
git fetch origin
git rebase origin/main
# çakışmalar her commit'te ayrı çözülür: git add, git rebase --continue
git rebase -i origin/main      # isteğe bağlı: taslak commit'leri birleştirin
git push --force-with-lease

Branch, bu sabah taze bir main'den başlamış gibi görünür; gereksiz commit yoktur ve inceleyen kişi değişiklikleri adım adım okuyabilir. Bedeli zorunlu push'tur ve bu branch'e başka kimsenin commit yapmadığından emin olmanız gerekir.

main ne görür

Pull request ile birleştirirken fark korunur. Merge tarzı dallanmalar ve senkronizasyon birleşmeleri içeren bir grafik verir; rebase tarzı ise özelliğin temiz commit zincirini, bunu ya ileri sarma ya da tek bir merge commit'i ile birleştirebilirsiniz. Çakışmalar aynı şekilde çözüldüyse kod her iki durumda da aynı olur.

Ekipte karar nasıl verilir

Birkaç soru sorun. Bir branch'te birden fazla kişi çalışıyor mu? Evetse o branch için rebase olmaz. Ekip Git'te ne kadar deneyimli? Yeni kişiler sık geliyorsa merge ve squash merge ile başlayın; bunlar hataları affeder. Denetim ve olay incelemesi için tam kronoloji gerekiyor mu? O zaman özelliklerin merge commit'leri faydalıdır. Okunabilir git log ve sık git bisect önemli mi? O zaman rebase ve doğrusal geçmiş yönünde karar verin.

Seçiminizi projenin CONTRIBUTING ya da README dosyasına yazın ve ana branch'i koruyun: force push yasak, pull request zorunlu, izin verilen birleştirme yöntemi tanımlı. Ayarlarla zorunlu kılınan bir kural, sözlü anlaşmadan çok daha sağlam çalışır.

Sık yanlış anlamalar

  • «Rebase ileri düzey, merge yeni başlayanlar içindir». Hayır: farklı işler için farklı araçlardır. Deneyimli geliştiriciler ikisini de kullanır.
  • «Merge commit'leri çöptür». Senkronizasyon commit'leri gerçekten gürültüdür. Ama bir özelliğin birleşme commit'i, tüm görevin görülebildiği ve geri alınabildiği faydalı bir noktadır.
  • «Rebase'den sonra çakışma azalır». Çakışmalar aynıdır, çünkü aynı satırlar değişir. Rebase onları commit'lere böler, merge ise hepsini tek seferde çözer.
  • «Rebase commit'leri kaybeder». Eski commit'ler git reflog'da kalır ve çöp toplama onları silene kadar geri getirilebilir.

Kısaca

Merge mi rebase mi sorusu, dürüst bir kronoloji ile okunabilir doğrusal bir geçmiş arasında seçim yapmaktır. Merge güvenlidir ve bağlamı korur; rebase temizdir ama commit'leri yeniden yazar. En sağlam uygulama ikisini birleştirmektir: kendi branch'inizi, siz sahibiyken rebase ile düzenleyin; hazır işi ise ekip kurallarına göre merge ya da squash ile ortak branch'lere katın. Önemli olan, şemayı önceden anlaşmak ve depo ayarlarında sabitlemektir. Her iki strateji ve ekipte branch çalışması Git kursunda uygulamalı olarak ele alınmaktadır.

Sık sorulan sorular

git pull için merge mi rebase mi kullanmalıyım?

Yerel branch'inizi güncellemek için rebase daha uygundur: yayımlanmamış commit'leriniz, gereksiz merge commit'i olmadan taze uzak commit'lerin üzerine yerleşir. git config --global pull.rebase true ile açılır.

Bir projede merge ve rebase birlikte kullanılabilir mi?

Evet, bu en yaygın yaklaşımdır: kendi branch'leriniz için rebase, ortak branch'ler için merge. Önemli olan, kuralın bütün ekibe bilinmesidir.

Yeni başlayan biri hangisiyle başlamalı?

Merge ile başlayın: geçmişi yeniden yazmaz ve bir şeyi bozmak daha zordur. Rebase'i, reflog'u ve force push'u anladıktan sonra kendi yerel branch'lerinizde öğrenin.

Strateji seçimi nihai koda etki eder mi?

Hayır. Çakışmalar aynı şekilde çözüldüğünde dosyaların nihai hâli aynıdır. Değişen yalnızca kaydedilen commit geçmişidir.

Squash merge ile rebase arasındaki fark nedir?

Squash merge tüm branch'i ana branch'te tek yeni bir commit'e sıkıştırır; rebase ise her commit'i tek tek taşır. İkisi de doğrusal geçmiş verir, ama squash adım adım ayrıntıyı kaybettirir.

Bu konuyu videoyla öğrenin

Bu konu “Sıfırdan Güvenilir Geliştiriciye Git” kursunda uygulamalı olarak ayrıntılı işleniyor.

Kursa git