Bir bakışta
- Merge, orijinal commit geçmişini koruyarak yeni bir birleştirme noktası ekler ve dallanmış yapıyı görünür kılar.
- Rebase, commit'leri yeniden yazarak doğrusal bir geçmiş oluşturur ancak hash değerlerini değiştirir ve paylaşılan dallarda risk yaratır.
- Merge paylaşılan dallarda güvenlidir, rebase ise yalnızca yerel ve kimseyle paylaşılmamış dallarda kullanılmalıdır.
Giriş: Dal Birleştirme Neden Önemli Bir Karar
Birden fazla geliştiricinin aynı proje üzerinde eş zamanlı çalışması, Git'te dal (branch) kavramını neredeyse zorunlu kılar. Her geliştirici kendi özelliğini veya hata düzeltmesini ayrı bir dalda geliştirir, işi bittiğinde bu dalı ana dala (genellikle main veya master) katmak ister. İşte tam bu noktada iki temel yöntemle karşılaşılır: merge ve rebase.
İlk bakışta ikisi de "aynı işi yapan" komutlar gibi görünebilir; sonuçta amaç, iki dalın içeriğini bir araya getirmektir. Ancak altta yatan mekanizma ve ortaya çıkan commit geçmişi tamamen farklıdır. Bu seçim sadece teknik bir tercih değildir; proje geçmişinin ne kadar okunabilir olacağını, ekip içinde kimin hangi değişikliği ne zaman yaptığının nasıl izleneceğini ve paylaşılan dallarda ne tür sorunların ortaya çıkabileceğini de doğrudan etkiler.
Merge Nedir, Ne Yapar
git merge komutu, iki dalın geçmişini bir araya getirirken genellikle yeni bir commit oluşturur: merge commit. Bu özel commit'in iki ebeveyni vardır — biri üzerinde bulunduğunuz dal, diğeri birleştirdiğiniz dal. Böylece Git, "bu noktada şu iki dal birleşti" bilgisini kalıcı olarak geçmişe işler.
Merge'in en önemli özelliği, orijinal commit geçmişine hiç dokunmamasıdır. Özellik dalındaki commit'ler olduğu gibi kalır, sadece üzerine bir birleştirme noktası eklenir. Sonuçta ortaya çıkan geçmiş, dallanmış haliyle korunur: hangi commit'lerin hangi dalda yapıldığı, bu dalın ne zaman ana dala katıldığı grafiksel olarak da izlenebilir kalır.
Basit bir senaryo düşünelim: feature/login adlı bir dalda giriş ekranı üzerinde çalışıyorsunuz ve bu süreçte beş commit yaptınız. Bu sırada main dalında da başka geliştiriciler tarafından üç yeni commit eklenmiş olsun. main üzerindeyken git merge feature/login çalıştırdığınızda Git, bu sekiz commit'i olduğu gibi korur ve üzerine "feature/login dalı main'e birleştirildi" anlamına gelen tek bir merge commit ekler. Geçmişe bakan biri, bu özelliğin ayrı bir dalda geliştirildiğini ve hangi noktada ana dala katıldığını net şekilde görebilir.
Rebase Nedir, Ne Yapar
git rebase ise tamamen farklı bir mantıkla çalışır. Bir dalın commit'lerini, başka bir dalın en son noktasının üzerine "yeniden yazarak" taşır. Burada kritik nokta şudur: bu commit'ler gerçekten taşınmaz, aslında birebir aynı değişiklikleri içeren ama farklı bir temel (base) üzerine kurulu yeni commit'ler olarak yeniden oluşturulur.
Aynı senaryoyu rebase ile ele alalım: feature/login dalındayken git rebase main çalıştırdığınızda, Git önce sizin beş commit'inizi geçici olarak bir kenara alır, dalınızı main'in en güncel haline getirir, sonra beş commit'inizi bu yeni temel üzerine tek tek yeniden uygular. Sonuç olarak ortaya çakışma izi taşımayan, tamamen doğrusal (linear) bir geçmiş çıkar. Sanki siz baştan beri main'in en güncel haliyle çalışmaya başlamışsınız gibi görünür.
Bu doğrusallık, geçmişi okumayı kolaylaştırır: dallanma noktaları, merge commit'leri gibi "gürültü" olmadan, sanki tüm işler tek bir çizgi üzerinde sırayla yapılmış gibi bir görünüm elde edilir.
Commit Hash'lerinin Değişmesi ve Paylaşılan Dallarda Yarattığı Riskler
Rebase'in en dikkat edilmesi gereken yönü burada ortaya çıkıyor: yeniden oluşturulan her commit, içeriği aynı olsa bile farklı bir hash değeri alır. Çünkü Git'te bir commit'in hash'i, içeriğinin yanı sıra ebeveyn commit'ine de bağlıdır. Temel değiştiği için hash de değişir — teknik olarak bunlar artık "yeni" commit'lerdir.
Bu durum, dalı sadece siz kullanıyorsanız hiçbir sorun yaratmaz. Ancak dal zaten push edilmiş ve başka bir geliştirici bu dalı çekip üzerinde çalışmaya başlamışsa, rebase sonrası ortaya çıkan yeni hash'ler o geliştiricinin elindeki eski hash'lerle uyuşmaz hale gelir. Bu da genellikle karmaşık çakışmalara, "neden benim geçmişimle sunucudaki geçmiş birbirini tutmuyor" türünden kafa karıştırıcı durumlara yol açar.
Bu yüzden Git camiasında yaygın kabul görmüş bir prensip vardır: golden rule. Bu prensibe göre, başkalarıyla paylaşılan (public) dallarda asla rebase yapılmamalıdır. Rebase, yalnızca henüz kimseyle paylaşılmamış, yerel veya sadece sizin üzerinde çalıştığınız dallarda güvenle kullanılmalıdır.
Çakışma (Conflict) Çözme Deneyimindeki Fark
İki yöntem arasındaki pratik farklardan biri de çakışma çözme deneyimidir. Merge yapıldığında, iki dal arasındaki tüm farklılıklar tek bir noktada karşılaştırılır ve çakışmalar varsa bunlar tek seferde çözülür. Birleştirme işlemi bittiğinde iş tamamlanmış olur.
Rebase'de ise durum farklıdır. Git, commit'leri tek tek yeniden uyguladığı için her commit kendi çakışmasını ayrı ayrı ortaya çıkarabilir. Beş commit'lik bir dalı rebase ederken teorik olarak beş farklı noktada çakışma çözmeniz gerekebilir. Bu, özellikle çok sayıda commit içeren ve uzun süredir ana daldan ayrı kalmış dallarda rebase'i daha zahmetli hale getirebilir.
Ancak bu zahmetin kabul edilebilir olduğu durumlar da vardır: dal küçükse, commit sayısı azsa veya zaten temiz bir geçmiş oluşturmak öncelikliyse, commit başına çakışma çözmek makul bir maliyettir. Büyük ve uzun ömürlü dallarda ise bu süreç zaman alıcı hale gelebilir ve bazen merge daha pratik bir seçim olur.
Hangi Durumda Hangisi Tercih Edilmeli
Net bir kural yoktur; seçim ihtiyaca göre değişir:
- Temiz, doğrusal bir geçmiş isteniyorsa: Özellik dalınızı ana dala almadan önce rebase ile düzenlemek iyi bir seçenektir. Özellikle henüz kimseyle paylaşmadığınız yerel dalınızda rebase yapıp ardından
main'e temiz bir şekilde merge etmek, hem okunabilirlik hem güvenlik açısından dengeli bir yaklaşımdır. - Geçmişin dallanmış haliyle korunması önemliyse: Hangi özelliğin hangi dalda geliştirildiğinin, ne zaman birleştiğinin izlenebilir kalması gerekiyorsa merge tercih edilmelidir. Özellikle büyük projelerde bu izlenebilirlik, hata ayıklama ve geçmişi anlama açısından değerlidir.
- Takım büyüklüğü ve proje karmaşıklığı: Küçük ve disiplinli ekiplerde rebase alışkanlığını yerleştirmek daha kolaydır; herkes golden rule'a uyduğu sürece sorun çıkmaz. Büyük, dağınık veya deneyim seviyesi farklı geliştiricilerden oluşan ekiplerde ise merge, yanlışlıkla paylaşılan dallarda rebase yapma riskini ortadan kaldırdığı için daha güvenli bir varsayılan olabilir.
- Ekip alışkanlıkları: Bazı ekipler "her özellik dalı rebase edilip sonra fast-forward merge ile birleştirilir" kuralını benimser, bazıları ise her birleşmede merge commit oluşmasını tercih eder. Burada teknik doğruluktan çok, ekibin ortak iş akışına uyum önemlidir.
Interactive Rebase ile Ek Kullanım Alanları
Rebase'in tek kullanım alanı dal birleştirme değildir. git rebase -i (interactive rebase) komutu, commit geçmişini düzenlemek için de yaygın şekilde kullanılır. Bu modda:
- Birden fazla küçük commit'i tek bir anlamlı commit haline getirebilirsiniz (squash),
- Commit'lerin sırasını değiştirebilirsiniz,
- Commit mesajlarını düzeltebilirsiniz,
- İstenmeyen bir commit'i tamamen kaldırabilirsiniz.
Bu, özellikle bir özellik dalını paylaşmadan veya pull request açmadan önce geçmişi "temizlemek" için sıkça başvurulan bir pratiktir. Örneğin geliştirme sırasında oluşturduğunuz "wip", "düzeltme", "tekrar düzeltme" gibi dağınık commit'leri tek, anlamlı bir commit'e dönüştürmek, hem kod inceleyenler hem de ileride geçmişe bakacaklar için büyük kolaylık sağlar.
Sonuç: Doğru Aracı Doğru Yerde Kullanmak
Merge ve rebase birbirinin rakibi değil, farklı ihtiyaçlara hizmet eden iki farklı araçtır. Merge, geçmişi olduğu gibi koruyarak izlenebilirlik sağlar; rebase ise geçmişi yeniden düzenleyerek daha sade ve doğrusal bir anlatı oluşturur. Hangisinin doğru olduğu sorusunun tek bir cevabı yoktur — proje geçmişinin nasıl okunmak istendiğine, ekip büyüklüğüne ve iş akışı alışkanlıklarına bağlıdır.
Yeni başlayan geliştiriciler için en önemli çıkarım, golden rule'u hatırlamaktır: paylaşılan dallarda rebase yapmaktan kaçının. Bunun dışında, kendi yerel dallarınızda küçük denemeler yaparak hem merge hem rebase'i deneyimlemek, ekibinize ve projenize hangi yaklaşımın daha uygun olduğunu zamanla görmenizi sağlayacaktır.



