Rebase, bir daldan commit’leri başka bir dalın tepesine taşıyan, gereksiz merge commit’leri olmadan doğrusal bir geçmiş oluşturan bir Git işlemidir. Birleştirmenin aksine, rebase geçmişi yeniden yazar: taşınan her commit, ebeveyni değiştiği için yeni bir hash alır. Git dokümantasyonuna (2026) göre rebase, pull request oluşturmadan önce feature dallarını main’in güncel durumuyla senkronize etmek için kullanılır. git rebase komutu, Git Flow kullanan projelerde temiz bir geçmiş sürdürmek için ana araçlardan biridir.
Ana Noktalar
Rebase, geçerli dalı belirtilen bir dal üzerine yeniden temellendiren bir Git komutudur: geçerli daldaki tüm commit’leri alır, geçici olarak kaydeder, dal işaretçisini hedef commit’e taşır ve kaydedilen commit’leri sırayla onun üzerine uygular. Sonuç — geçmiş, geliştiricinin doğrudan hedef dalın son commit’inden çalışmış gibi görünür.
Temel sözdizimi: git rebase main — bir feature dalındayken, bu komut tüm feature commit’lerini main’in tepesine taşır. Git, her commit için ayrı ayrı üç yönlü birleştirme stratejisi kullanır. Commit A zaten hedef dalda mevcutsa (hash ile belirlenir), Git onu otomatik olarak atlar ve yinelenen değişiklikleri önler.
Rebase ayrıca bir commit alt kümesini taşımak için onto modunu destekler: git rebase --onto target start end — bu form, bir daldan bir commit aralığı çıkarmaya ve bunları başka bir dalın üzerine uygulamaya izin verir. Örneğin, git rebase --onto main feature~3 feature, feature dalının son üç commit’ini main üzerine taşır.
# Switch to feature branch
git checkout feature
# Rebase feature onto main
git rebase main
# After successful rebase — history is linear
git log --oneline --graph
# Move last 3 commits to main
git rebase --onto main HEAD~3 HEAD
Rebase ve merge aynı görevi çözer — farklı dallardan değişiklikleri birleştirmek — ancak temelde farklı şekillerde yapar. Merge, iki ebeveynli bir merge commit oluşturarak tam birleştirme geçmişini korur. Rebase geçmişi yeniden yazar ve onu doğrusal hale getirir. Aralarındaki seçim, ekibin çalışma akışına ve depo yönetim kurallarına bağlıdır.
Temel fark, birleştirme olayının nasıl kaydedildiğidir. Merge şunu korur: “bu noktada feature’u main’e birleştirdik” — bu proje geçmişi için bilgilendiricidir ancak sık birleştirmelerle günlüğü karmaşık hale getirir. Rebase şunu gösterir: “feature commit’leri main’in son durumundan sırayla oluşturuldu” — bu temizdir ancak geliştirmenin paralel yapıldığı gerçeğini gizler.
İkinci fark çakışma yönetimidir. Merge ile çakışmalar bir kez çözülür ve çözüm merge commit’inde kaydedilir. Rebase ile taşınan her commit için çakışmalar oluşabilir ve her biri ayrı çözüm gerektirir. Bu daha fazla emek gerektirir ancak hangi değişikliklerin son sürüme dahil edileceği üzerinde daha hassas kontrol sağlar.
| Kriter | Rebase | Merge |
|---|---|---|
| Geçmiş | Doğrusal, merge commit’i olmadan | Doğrusal olmayan, merge commit’leri ile |
| Commit hash’leri | Yeniden yazılır (yeni) | Orijinal korunur |
| Çakışmalar | Her commit için ayrı ayrı | Merge commit’inde bir kez |
| Genel dallar | Yasak | İzin verilir |
| Geri alma komutu | git rebase --abort | git merge --abort |
Etkileşimli rebase (git rebase -i), Git’in bir commit listesi ve her biri için kullanılabilir eylemler içeren bir düzenleyici açtığı bir moddur. Geliştirici, uzak bir depoya göndermeden önce geçmişi yeniden yazabilir. Bu, bir feature dalında temiz commit’ler sürdürmek için birincil araçtır.
Etkileşimli modda kullanılabilir komutlar: pick (commit’i olduğu gibi bırak), reword (commit mesajını değiştir), edit (değişiklik için dur), squash (önceki commit ile birleştir, her iki mesajı da koru), fixup (birleştir, mesajı at), drop (commit’i sil). Her komut, açılan düzenleyicide commit hash’inden önce yerleştirilir.
Squash ve fixup, commit’leri birleştirmek için en sık kullanılan komutlardır. Bir geliştirici çalışma sırasında 5 küçük düzeltme commit’i yaptıysa, squash bunları anlamlı bir mesajla tek bir mantıksal commit’te birleştirir. Fixup, yazım hatalarını düzeltmek için kullanışlıdır: değişiklikler, kendi mesajlarını korumadan önceki commit’e gider.
# Open editor for last 4 commits
git rebase -i HEAD~4
# Editor will show:
pick a1b2c3d Add authentication
pick e4f5g6h Fix typo in login
squash i6j7k8l Additional login fixes
pick m9n0o1p Add auth tests
# After saving — Git performs rebase
# and opens editor for squashed commit message
# Auto-squash without opening editor
git rebase -i HEAD~4 --autosquash
--autosquash bayrağı, mesajları fixup! veya squash! ile başlayan commit’ler için otomatik olarak fixup/squash düzenler. Geliştirici, daha sonra birleştirme için commit’leri önceden işaretlerse bu, çalışmayı hızlandırır. --committer-date-is-author-date bayrağı, rebase sırasında orijinal commit tarihini korur — geçmişte kronolojik sırayı sürdürmek için kullanışlıdır.
Rebase sırasında çakışmalar, Git hedef daldaki değişikliklerle çelişkiler nedeniyle taşınan bir commit’i otomatik olarak uygulayamadığında meydana gelir. Çakışmanın bir kez çözüldüğü merge’in aksine, rebase ile her commit bir çakışmaya neden olabilir ve en eskiden en yeniye her commit için sırayla çözülmelidir.
Bir çakışma meydana geldiğinde, Git rebase’i duraklatır ve hangi commit’in soruna neden olduğunu bildirir. Geliştirici çakışan dosyayı açar (Git çakışma alanlarını <<<<<<<, =======, >>>>>>> işaretleriyle belirler), düzenler, dizine ekler (git add) ve git rebase --continue ile rebase’e devam eder. Çözüm bulunamazsa — git rebase --abort rebase’i tamamen iptal eder.
İpucu: birden fazla çakışma olduğunda, çakışmaları çözmek için görsel bir düzenleyici açan git mergetool kullanmak daha verimlidir. Sorunlu commit atlanabilir (git rebase --skip), ancak bu, değişikliklerini son geçmişten kaldırır ve bu nadiren doğru karardır.
# Start rebase with conflict
git rebase main
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt
# Check status
git status
# both modified: file.txt
# Edit conflicted sections → git add → continue
git add file.txt
git rebase --continue
# If uncertain — abort
git rebase --abort
Rebase’in altın kuralı: zaten uzak bir depoya gönderilmiş ve diğer geliştiriciler için kullanılabilir olan commit’leri asla rebase etmeyin. Rebase commit hash’lerini yeniden yazdığı için, meslektaşlarınız senkronize olmaya çalışırken çakışmalarla karşılaşacaktır — yerel geçmişleri, yeniden yazılmış uzak geçmişten farklı olacaktır.
Rebase’in kesinlikle yasak olduğu bir durum: birisi zaten sizin commit’lerinize dayalı bir dal oluşturmuşsa (örneğin, bir meslektaşınız sizin feature dalınızdan bir dal oluşturduysa), geçmişi yeniden yazmak onun çalışmasını bozacaktır. Bu gibi durumlarda merge kullanın. Ayrıca bir teslim tarihinden hemen önce rebase yapılması önerilmez — çakışma çözümünde bir hata beklenenden daha uzun sürebilir ve sürümü bloke edebilir.
İstisna: dal yalnızca bir geliştirici tarafından kullanılıyorsa (kişisel feature dalı, yayınlanmamış veya taslak modunda yayınlanmış), push’tan önce rebase standart bir uygulamadır. Yayınlama ve işbirlikçi çalışmaya başladıktan sonra — yalnızca merge. GitHub ve GitLab varsayılan olarak bir uzlaşma olarak squash merge sunar: commit’leri birleştirir ancak hedef dalın geçmişini yeniden yazmaz.
Modern ekipler en sık olarak GitHub Flow ile birleştirilmiş rebase odaklı bir çalışma akışı kullanır. Süreç şöyledir: geliştirici main’den bir feature dalı oluşturur, içinde çalışır, periyodik olarak git rebase main ile senkronize olur ve bir pull request oluşturmadan önce geçmişi temizlemek için etkileşimli bir rebase gerçekleştirir.
Bir PR oluşturduktan sonra (main’den yeni değişiklikler çekilmesi gerekiyorsa), normal git pull yerine git pull --rebase main kullanılır. Bu, gereksiz bir merge commit oluşturmadan değişiklikleri çeker. --rebase bayrağı ile git pull, git fetch + git rebase’e eşdeğerdir — Git önce yeni commit’leri indirir, ardından yerel değişiklikleri bunların üzerine rebase eder.
Git, pull için varsayılan davranış olarak rebase’i yapılandırmaya izin verir: git config --global pull.rebase true. Bu ayardan sonra, git pull her zaman merge yerine rebase yapar. Normal bir pull gerekiyorsa — git pull --no-rebase kullanılır. Birçok ekip ayrıca autostash’i etkinleştirir: git config --global rebase.autoStash true — bu, rebase’den önce commit edilmemiş değişiklikleri otomatik olarak gizler ve sonra geri yükler.
Sıkça Sorulan Sorular
Rebase etmek, git rebase çalıştırmak anlamına gelir: geçerli daldaki commit’leri başka bir dalın tepesine taşımak. Sonuç olarak, geçmiş doğrusal hale gelir, her commit yeni bir hash alır ve merge commit’leri oluşturulmaz. Komut, günlükte gereksiz birleştirme noktaları olmadan dalları senkronize etmek için kullanılır.
Merge, iki ebeveynli bir merge commit oluşturur, paralel geçmişi ve orijinal hash’leri korur. Rebase geçmişi yeniden yazar — commit’ler yeni hash’ler alır ve geçmiş doğrusal hale gelir. Merge genel dallar için daha güvenlidir, rebase daha temiz bir günlük sağlar.
git rebase -i HEAD~N komutu, son N commit ile bir düzenleyici açar. Her commit için bir eylem seçilebilir: pick (bırak), reword (yeniden adlandır), edit (değiştir), squash (öncekiyle birleştir), fixup (mesaj olmadan birleştir), drop (sil). Kaydettikten sonra Git seçilen değişiklikleri uygular.
Rebase commit hash’lerini yeniden yazar, bu da geçmişi diğer geliştiricilerin makinelerindeki aynı commit’lerin kopyalarıyla uyumsuz hale getirir. Bir meslektaşınız zaten git pull ile commit’lerinizi aldıysa ve sonra siz onları rebase ettiyseniz, onun git push’u reddedilecek ve git pull yinelenen commit’ler ve çakışmalar oluşturacaktır.
Tamamlanmadan önce — git rebase --abort tamamen iptal eder. Tamamlandıktan sonra, git reflog aracılığıyla önceki durum geri yüklenebilir — rebase’den önceki commit hash’ini bulun ve üzerine git reset --hard çalıştırın. Reflog, varsayılan olarak 30 gün boyunca HEAD hareket geçmişini saklar.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun