Merhabalar. Bugün Git kullanırken en çok kafa karıştıran konulardan birini ele alacağız: rebase ve merge arasındaki farklar ve hangisini ne zaman kullanmanız gerektiği. Eğer takım halinde çalışıyorsanız, bu karar projenizin geçmişini (history) nasıl okuyacağınızı doğrudan etkiler. Adım adım inceleyelim.

Merge Nedir?

Merge, iki dalın (branch) geçmişini birleştirmek için kullanılan komuttur. Diyelim ki main dalında çalışıyorsunuz ve feature/login dalındaki değişiklikleri ana dala almak istiyorsunuz. git merge komutunu çalıştırdığınızda Git, her iki dalın commit geçmişini korur ve birleştirme işlemi için yeni bir “merge commit” oluşturur.

git checkout main
git merge feature/login

Bu komutun ardından geçmişiniz şu şekilde görünür:

*   d9e3a1f (HEAD -> main) Merge branch 'feature/login'
|\
| * b2c4f8a (feature/login) Login sayfası eklendi
| * a1b3c7d Kullanıcı modeli oluşturuldu
|/
* e5f6g7h Initial commit

Gördüğünüz gibi her commit orijinal sırasıyla korunuyor ve birleştirme noktası açıkça görülüyor. Bu, “ne zaman, hangi dalda ne yapıldı” sorusunun cevabını kolayca bulmanızı sağlar.

Rebase Nedir?

Rebase ise biraz farklı çalışır. Rebase, bir dalın commit’lerini alıp diğer dalın en üstüne sırayla yeniden uygular. Yani geçmişi yeniden yazar. Diyelim ki feature/login dalındasınız ve main dalındaki güncellemeleri kendi dalınıza almak istiyorsunuz:

git checkout feature/login
git rebase main

Bu komut çalıştığında Git, feature/login dalınızdaki commit’leri geçici olarak çıkarır, main dalının en son commit’ini taban alır ve sonra sizin commit’lerinizi sırayla bunun üstüne ekler. Sonuç:

  • a1b3c7d’ (HEAD -> feature/login) Login sayfası eklendi
  • b2c4f8a’ Kullanıcı modeli oluşturuldu
  • e5f6g7h (main) Initial commit

Dikkat ederseniz commit hash’leri değişti (a1b3c7d → a1b3c7d’). Çünkü rebase geçmişi yeniden yazıyor. Merge commit de yok. Geçmiş tamamen doğrusal (linear).

Temel Farklar

| Özellik | Merge | Rebase |
| Geçmiş | Korunur, olduğu gibi bırakılır | Yeniden yazılır, doğrusallaştırılır |
| Merge Commit | Evet, yeni bir commit oluşur | Hayır |
| Geçmiş Okuma | Dallanmalar görünür, izleme kolay | Doğrusal, temiz görünüm |
| Güvenlik | Paylaşılan dallarda güvenli | Paylaşılan dallarda TEHLİKELİ |
| Commit Hash | Değişmez | Değişebilir |

En önemli kural şudur: Rebase, paylaşılan (başkalarının da kullandığı) dallarda asla kullanılmamalıdır. Çünkü geçmişi yeniden yazdığı için, sizin commit’lerinizi çekmiş olan ekip arkadaşlarınızın geçmişiyle çakışmaya neden olur.

1. Merge Kullanmanız Gereken Durumlar

Paylaşılan Dallarda Birleştirme

Eğer main veya develop gibi takımın ortak kullandığı bir dala feature dalınızı birleştiriyorsanız, merge kullanın. Bu, en güvenli yoldur. Herkesin commit geçmişi korunur ve kimse bir sürpriz commit hash değişikliğiyle karşılaşmaz.

git checkout main
git merge --no-ff feature/login

--no-ff parametresi “no fast-forward” anlamına gelir. Git’in otomatik olarak fast-forward birleştirme yapmasını engeller ve her zaman bir merge commit oluşturur. Bu sayede feature dalının nerede başlayıp bittiği geçmişte açıkça görünür.

Takım Halinde Çalışılan Feature Dallarında

Eğer bir feature dalında birden fazla kişi çalışıyorsa, o dalda da merge kullanın. Rebase yaparsanız diğer geliştiricilerin commit’lerinin hash’leri değişir ve ellerinde conflict’ler birikebilir.

2. Rebase Kullanmanız Gereken Durumlar

Kendi Feature Dalınızı Güncel Tutma

Diyelim ki feature/payment dalında tek başınıza çalışıyorsunuz ve main dalında diğer ekip arkadaşlarınız sürekli güncelleme yapıyor. Siz de kendi dalınızı main ile senkron tutmak istiyorsunuz. Burada rebase harikadır:

git checkout feature/payment
git fetch origin
git rebase origin/main

Bu, main‘deki güncellemeleri alır ve sizin commit’lerinizi en üstte olacak şekilde sıralar. Geçmişiniz temiz ve doğrusal kalır. Merge commit’lerle dolup taşmaz.

Commit’leri Temizleme (Interactive Rebase)

Rebase’in en güçlü özelliklerinden biri interaktif moddur. Ufak ufak yaptığınız commit’leri birleştirmek (squash) veya commit mesajlarını düzenlemek için kullanılır:

git rebase -i HEAD~5

Bu komut son 5 commit’i interaktif olarak düzenlemenizi sağlar. Karşınıza şöyle bir ekran çıkar:

pick a1b3c7d Kullanıcı modeli oluşturuldu
pick b2c4f8a Login sayfası eklendi
pick c3d5e9f typo düzeltmesi
pick d4e6f0a renk değişikliği
pick e5f7a1b typo düzeltmesi 2
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message

Burada pick yerine squash veya fixup yazarak commit’leri birleştirebilirsiniz. Örneğin:

reword a1b3c7d Kullanıcı modeli oluşturuldu
fixup b2c4f8a Login sayfası eklendi
fixup c3d5e9f typo düzeltmesi
fixup d4e6f0a renk değişikliği
fixup e5f7a1b typo düzeltmesi 2

Bu şekilde 5 commit’i tek bir commit’e indirgiyorsunuz. squash commit mesajını birleştirir, fixup ise mesajı atar. İkisi de commit’leri birleştirir ama fixup daha temizdir çünkü gereksiz commit mesajlarını tutmaz.

PR’dan Önce Dalı Temizleme

Pull Request açmadan önce dalınızı temizlemek için rebase harikadır. Interaktif rebase ile commit mesajlarını düzene sokun, gereksiz commit’leri birleştirin, sonra PR açın. Bu sayede inceleyen kişi (reviewer) temiz ve anlaşılır bir commit geçmişi görür.

3. Hibrit Yaklaşım: En İyi Pratik

Pek çok profesyonel ekip şu hibrit yaklaşımı kullanır:

  1. Feature dalında rebase: Kendi feature dalınızı main ile güncel tutmak için rebase kullanın. Bu, dalınızı güncel ve temiz tutar.
  2. Main’e merge: Feature dalınız hazır olduğunda main‘e merge yapın. Bu, takım geçmişini korur.
  3. Squash merge (opsiyonel): Bazı ekipler feature dalındaki tüm commit’leri tek bir commit’e sıkıştırıp main‘e almayı tercih eder. GitHub ve GitLab’da PR birleştirirken “Squash and merge” seçeneği bunu otomatik yapar.
git merge --squash feature/login
git commit -m "Feature: Login sayfası implementasyonu"

Bu yaklaşım hem temiz bir main geçmişi sağlar hem de feature geliştirme sürecini net bir şekilde belgeler.

Yaygın Hatalar ve Çözümleri

Hata: “fatal: refusing to merge unrelated histories”

İki dalın tamamen ayrı commit geçmişleri varsa merge yapılmaz. Eğer bilinçli olarak birleştirmek istiyorsanız:

git merge --allow-unrelated-histories feature/old-branch

Hata: Rebase sırasında conflict çıkması

Rebase sırasında conflict olursa Git durur ve sorunu çözmenizi bekler. Conflict’leri çözdükten sonra:

git add <çözülen-dosyalar>
git rebase --continue

Eğer rebase’i tamamen iptal etmek isterseniz:

git rebase --abort

Hata: “I accidentally rebased a shared branch!”

Eğer yanlışlıkla paylaşılan bir dala rebase yaptıysanız ve force push ettiyseniz, ekip arkadaşlarınıza haber verin. Onlar şu komutla yerel dallarını düzeltebilir:

git fetch origin
git reset --hard origin/branch-name

Bu onların yerel dalını uzaktaki (rebase edilmiş) sürüme sıfırlar. Tabii daha önce yaptıkları commit’ler varsa kaybedebilirler, bu yüzden rebase’i paylaşılan dallarda yapmamak en iyisi.

Hata: Merge yerine rebase yapmak istedim ama yanlış yaptım

Eğer merge yaptınız ama aslında rebase yapmak istiyordunuz ve henüz push yapmadıysanız:

git reset --hard HEAD~1
git rebase origin/main

Bu merge commit’ini geri alır ve rebase ile devam etmenizi sağlar.

Karar Tablosu

Aşağıdaki tablo hangi durumda ne kullanmanız gerektiğini özetler:

  • Paylaşılan dalı birleştirme → Merge
  • Kendi feature dalınızı güncelleme → Rebase
  • PR’dan önce commit temizleme → Interactive rebase
  • Birden fazla kişi aynı dalda → Merge
  • Doğrusal geçmiş istiyorsanız → Rebase
  • Feature geliştirme hikayesini korumak → Merge (–no-ff)
  • Tek commit’lik hızlı feature → Squash merge

Sonuç

Git rebase ve merge’in ikisinin de yeri var. Önemli olan, hangi durumda hangisini kullanacağınızı bilmek. Temel kuralı unutmayın: Rebase’i sadece kendi yerel dallarınızda kullanın, paylaşılan dallarda asla. Eğer takım halinde çalışıyorsanız ve emin değilseniz, merge kullanmak her zaman güvenlidir.

Hibrit yaklaşım (feature dalında rebase, main’e merge) hem temiz bir geçmiş hem de güvenli bir iş akışı sağlar. Pratiğe dönüştürdükçe hangisinin sizin ekibinize daha uygun olduğunu göreceksiniz.

Okuduğunuz için teşekkür ederim!