GIT MERGE VE REBASE FARKI
Yaygın bir yanlış var: "Merge de rebase de aynı işi yapar, sadece tercih meselesi." Oysa ikisi aynı sonucu vermez. Merge commit geçmişini olduğu gibi bırakır ve birleşmeyi gösteren yeni bir commit ekler; rebase ise commit'leri yeniden yazar ve geçmişi düzleştirir. Bu yapısal fark, public branch'te rebase yapmanın neden takım arkadaşlarınızın deposunu bozabileceğini ve neden bazı projelerin "rebase yasak" kuralı koyduğunu açıklar. Farkı net görmeden seçim yapmak, code review akışınızı ve git log'unuzu uzun vadede ciddi şekilde etkiler.
Merge ve rebase neden aynı sonucu vermez
Yüzeyde her ikisi de "iki branch'i birleştirmek" işini yapar. Fakat sonuçta ortaya çıkan commit grafiği bambaşkadır. Merge yapıldığında Git, iki ata commit'i olan yeni bir "merge commit" üretir; branch'lerin ayrılıp tekrar birleştiği nokta history'de görünür kalır. Rebase yapıldığında ise feature branch'inizdeki commit'ler, hedef branch'in en güncel commit'inin üstüne tek tek yeniden uygulanır. Aynı içerikte ama farklı SHA değerine sahip yeni commit'ler oluşur.
Sonuç şudur: rebase sonrası eski commit'leriniz teknik olarak başka commit'lerdir. Aynı değişikliği taşıyorlar ama Git nesne deposunda artık farklı kimliklere sahipler. Bu, sadece lokalde çalıştığınız bir branch için sorun değildir; ancak başkalarının da o commit'leri çekmiş olduğu durumda kaos yaratır.
Git merge nasıl çalışır
Bir feature branch'i main'e merge ettiğinizde Git iki yoldan birini seçer:
- Fast-forward: main, feature ayrıldığından beri hiç ilerlemediyse Git sadece main pointer'ını ileri taşır. Yeni bir commit oluşmaz, history düz görünür.
- Three-way merge: her iki branch de yeni commit aldıysa Git ortak ata commit'i bulur, üç noktadan içeriği birleştirir ve iki ataya bağlanan yeni bir merge commit yaratır.
Three-way merge'in görünür dezavantajı history'nin "diamond" şekline girmesidir. Çok sayıda paralel branch'in birleştiği projelerde grafik karmaşıklaşır. Avantajı ise hiçbir commit'in kaybolmaması ve her birleşmenin açıkça izlenebilir olmasıdır.
Git rebase nasıl çalışır
Rebase, feature branch'inizdeki commit'leri "söker" ve hedef branch'in tepesine sırayla yeniden uygular. Her commit için tek tek cherry-pick yapılıyor gibidir. Sonuçta history doğrusal kalır; merge commit'i yoktur, sanki feature branch baştan main'in son halinden çıkmış gibi görünür.
Interactive rebase (git rebase -i) daha güçlüdür: commit'leri birleştirebilir (squash), yeniden sıralayabilir, mesajlarını düzenleyebilir veya silebilirsiniz. Pull request açmadan önce commit geçmişini temizlemek için sık kullanılan bir yöntemdir. Komutun davranışı ve ileri seçenekleri için resmi dokümantasyonu incelemek faydalıdır.

History şekli neden önemlidir
Bazı projeler "her zaman merge" der, bazıları "her zaman rebase". İki yaklaşımın da gerekçesi history'nin nasıl okunmasını istediğinizle ilgilidir:
- Merge tarafı: "Gerçeği görmek istiyoruz. Hangi branch ne zaman birleşmiş, kim hangi feature'u nasıl entegre etmiş, hepsi grafikten okunsun."
- Rebase tarafı: "
git logokunabilir olsun. Linear history bisect ile bug aramada kolaylık verir, gereksiz merge commit'leri kalabalık yapmaz."
Her iki yaklaşım da geçerlidir; karar genelde projenin büyüklüğü, paralel branch sayısı ve code review akışıyla şekillenir. Git komutlarına yeni başlıyorsanız temel kavramları toparlamak için git eğitimi içeriğinden yararlanabilirsiniz.
Public branch'te rebase neden risklidir
Altın kural: Başkasının çektiği bir branch'i rebase etme. Sebep şudur: rebase commit SHA'larını değiştirir. Siz paylaşılan bir branch üzerinde rebase yaptıysanız ve git push --force ile gönderdiyseniz, aynı branch'i daha önce pull'lamış olan herkes artık eski-yeni karışık iki paralel history ile karşılaşır.
Pratikte yaşananlar şöyle gelişir:
- Siz force push ile rebase edilmiş branch'i remote'a gönderirsiniz.
- Bir başkası eski commit'lerin üstüne yeni iş yapmıştır.
- O kişi pull yaptığında Git, yeni ve eski commit'leri merge etmeye çalışır. Aynı değişiklik iki defa history'de görünür ve conflict'ler saatlerce uğraştırır.
Bu yüzden çoğu projenin yazılı kuralı şudur: lokal branch'inde istediğin kadar rebase yap, ama paylaşılan branch'e (özellikle main, develop, release) asla rebase ile force push etme.
Conflict çözümünde fark
Merge sırasında conflict olursa tek bir noktada çözersiniz: birleşmenin yapıldığı an. Rebase sırasında ise her bir commit'in yeniden uygulanması ayrı bir adımdır; aynı dosya üzerinde birden fazla commit varsa aynı conflict'i defalarca çözmek zorunda kalabilirsiniz. git rerere tekrar eden çözümleri hatırlayarak bu acıyı bir nebze hafifletir ama tamamen ortadan kaldırmaz.
Pratik sonuç: çok sayıda commit'i olan ve hedef branch ile arası açılmış bir feature dalını rebase etmek yorucu olabilir. Bu senaryoda merge daha az acı veren seçenektir, çünkü tüm birikmiş conflict'i tek seferde çözersiniz.
Hangi durumda hangisini seçmelisiniz
Tek bir doğru cevap yoktur ama pratik yönlendirici kurallar var:
- Lokal feature branch'ini main ile güncel tutmak: rebase tercih edilir, history temiz kalır.
- PR açmadan önce commit'leri temizlemek: interactive rebase ile squash ve reword idealdir.
- PR'ı paylaşılan main'e almak: merge (veya squash merge) güvenlidir, force push gerekmez.
- Birden fazla kişinin çalıştığı feature branch: rebase YAPMAYIN; merge ile senkronize edin.
- Production hotfix: küçük ve direkt — fast-forward merge en sade çözümdür.

Sonuçta merge ve rebase rakip değil, farklı amaçlara hizmet eden iki araçtır. Merge tarihi olduğu gibi korur, rebase okunaklı kılar. Yanlış olan, ikisini birbirinin yerine sanmak ve paylaşılan branch'te rebase ile force push ederek başkalarının deposunu bozmaktır. Branch'i kimin kullandığını, history'den ne beklediğinizi ve takım kurallarınızı bilince doğru tercih kendiliğinden netleşir.



