Git'te Silinen Commit ve Branch Nasıl Geri Getirilir?
Git'te Her Şeyi Mahvettim: Kayıp Commit, Silinen Branch ve Yanlış Push Nasıl Kurtarılır?
Saatler süren çalışmanın ardından bir komut yazıyorsunuz. Enter'a basıyorsunuz. Ve bir anda her şey yanlış.
Yanlış branch'e commit attınız. Çalışan bir dosyayı sildıniz. Ya da daha kötüsü — hiçbir şeyin nerede bozulduğunu bile bilmiyorsunuz ve proje çalışmıyor.
Bu hissi her geliştirici yaşamıştır. Git güçlü bir araç ama hataları da o ölçüde sert görünüyor. İyi haber şu: Git'te neredeyse her şey kurtarılabilir. Tek yapmanız gereken doğru komutu bilmek.
Bu yazıda en yaygın Git felaketlerini ve her birinden çıkış yolunu tek tek anlatacağız. Panikle değil, komutlarla.
---
Git Neden Bu Kadar Korkutucu Görünüyor?
Git'in temel mantığı aslında çok basit: her commit bir anlık görüntü. Bir şeyi commit ettiyseniz Git onu hatırlıyor. Silseniz bile. Branch'i silseniz bile. Hatta reset atsanız bile.
Asıl sorun, bu anlık görüntülere nasıl ulaşacağınızı bilmemek. Çoğu geliştirici commit'leri bir "kaydet" butonu gibi kullanıyor ve bir şeyler yanlış gittiğinde panikliyor. Ama Git aslında bir zaman makinesi — sadece nasıl kullanacağınızı öğrenmeniz gerekiyor.
Şimdi en sık yaşanan senaryolara geçelim.
---
Senaryo 1: Yanlışlıkla Commit Attım
Kodu commit ettiniz ama henüz push etmediniz. Mesajı yanlış yazdınız, yanlış dosya eklediniz ya da o commit'in hiç olmadığını istiyorsunuz.
Sadece commit mesajını düzeltmek istiyorsanız:
bash
git commit --amend -m "Doğru mesaj buraya"
Son commit'in mesajını değiştirir. Dosyalar aynı kalır.
Son commit'i tamamen geri almak istiyorsanız ama değişiklikler kalsın:
bash
git reset --soft HEAD~1
Commit geri alınır ama yaptığınız değişiklikler staged olarak kalır. Sanki commit hiç atılmamış gibi.
Commit'i ve değişiklikleri tamamen silmek istiyorsanız:
bash
git reset --hard HEAD~1
Dikkatli kullanın: bu komut commit'i ve o commit'teki tüm değişiklikleri siler. Geri dönüş zordur.
---
Senaryo 2: Yanlış Branch'e Commit Attım
Main branch'te çalışıyordunuz ama aslında yeni bir feature branch açmanız gerekiyordu. Ya da tam tersi — yanlış branch'teydiniz.
Önce yeni branch açın, sonra commit'i taşıyın:
bash
git branch yeni-branch-adi git reset --soft HEAD~1 git checkout yeni-branch-adi git commit -m "Doğru branch'e commit"
Mantık şu: commit'i soft reset ile geri alıyorsunuz, değişiklikler staged kalıyor. Sonra doğru branch'e geçip yeniden commit atıyorsunuz.
Eğer birden fazla commit yanlış branch'e gittiyse:
bash
git log --oneline
Önce kaç commit'i taşımanız gerektiğini görün. Sonra HEAD~1 yerine HEAD~3 gibi sayıyı ayarlayın.
---
Senaryo 3: Yanlışlıkla Dosya Sildim
Git'e eklenmiş bir dosyayı sildıniz. Commit etmemiştiniz, ama dosya gitti.
Son commit'teki haline geri getirmek için:
bash
git checkout HEAD -- dosya-adi.js
dosya-adi.js yerine kendi dosya yolunuzu yazın. Örneğin src/components/Button.jsx gibi.
Birden fazla dosyayı geri getirmek için:
bash
git checkout HEAD -- .
Nokta işareti tüm değiştirilmiş ve silinen dosyaları son commit haline döndürür. Commit edilmemiş tüm değişiklikler kaybolur — dikkatli olun.
---
Senaryo 4: Commit Mesajını Yanlış Yazdım ve Push Ettim
Henüz push etmediyseniz amend komutu yeterli. Ama push ettiyseniz iş biraz karmaşıklaşıyor.
Önce lokal'de düzeltin:
bash
git commit --amend -m "Düzeltilmiş mesaj"
Sonra zorla push edin:
bash
git push --force-with-lease origin branch-adi
force yerine force-with-lease kullanmak önemli: başkası o branch'e push ettiyse sizi uyarır ve o değişiklikleri ezmez.
Uyarı: Eğer başka geliştiriciler aynı branch'i kullanıyorsa force push yapmadan önce ekibinize haber verin.
---
Senaryo 5: Her Şeyi Mahvettim — Git Reflog ile Zaman Makinesi
En ciddi durum bu. Ne yaptığınızı bilmiyorsunuz, proje çalışmıyor, neye döneceğinizi bilmiyorsunuz.
Git reflog burada devreye giriyor. Reflog, branch ve HEAD'in son 90 gün içindeki tüm hareketlerini kaydeder. Reset atsanız bile, branch silseniz bile.
bash
git reflog
Şuna benzer bir çıktı göreceksiniz:
plaintext
a3f2c1b HEAD@{0}: reset: moving to HEAD~2
8b4e9d2 HEAD@{1}: commit: Butona hover efekti eklendi
2c1a7f3 HEAD@{2}: commit: Navbar düzenlendi
Çalışan son halin hangi commit olduğunu bulun. Sonra:
bash
git reset --hard 8b4e9d2
Hash yerine kendi commit hash'inizi yazın. Proje o ana geri döner.
---
Senaryo 6: Branch'i Sildim
bash
git branch -D silinen-branch
Komutu çalıştırdınız ve sonra içinde önemli commit'ler olduğunu hatırladınız.
Git reflog burada da çalışıyor:
bash
git reflog
Silinen branch'in son commit'ini bulun. Sonra o commit'ten yeni bir branch oluşturun:
bash
git checkout -b kurtarilan-branch 8b4e9d2
Branch geri geldi. İçindeki tüm commit'ler sağlam.
---
Senaryo 7: Değişikliklerimi Geçici Olarak Saklamam Gerekiyor
Ortada bir iş varken acil başka bir branch'e geçmeniz gerekiyor. Commit atmak istemiyorsunuz çünkü iş yarım, ama değişiklikler de kaybolmasın.
git stash tam bu durum için var. Commit atmadan değişikliklerinizi geçici bir rafа kaldırır.
bash
git stash
Çalışma dizininiz temizlenir, başka bir branch'e geçebilirsiniz. Geri dönmek istediğinizde:
bash
git stash pop
Değişiklikler geri gelir. Birden fazla stash varsa listeyi görmek için:
bash
git stash list
Belirli bir stash'i geri almak için:
bash
git stash apply stash@{2}
Stash'i geri aldıktan sonra listeden silmek istiyorsanız pop kullanın. apply kullandıysanız stash listede kalmaya devam eder. Artık işe yaramayan stash'leri temizlemek için:
bash
git stash drop stash@{0}
Pratik bir kullanım: yeni bir özellik üzerinde çalışırken müşteriden acil bir hata bildirimi geldi. git stash ile yarım işi raflayın, main'den yeni bir hotfix branch açın, sorunu çözün, merge edin, sonra git stash pop ile kaldığınız yerden devam edin.
---
Senaryo 8: Merge Conflict — Hangi Kodu Alacağımı Bilmiyorum
İki branch'i birleştiriyorsunuz ve Git şunu söylüyor: "CONFLICT". Bu mesajı görünce çoğu geliştirici donup kalıyor. Aslında Git sadece iki farklı versiyonun aynı satırı değiştirdiğini söylüyor ve sizden hangisinin kalacağını seçmenizi istiyor.
Önce hangi dosyalarda conflict olduğunu görün:
bash
git status
"both modified" yazan dosyalar conflict içeriyor. O dosyayı açtığınızda şunu görürsünüz:
plaintext
<<<<<<< HEAD const title = "Eski başlık"; ======= const title = "Yeni başlık"; >>>>>>> feature/yeni-ozellik
HEAD sizin mevcut branch'inizdeki kod, alttaki ise merge etmeye çalıştığınız branch'teki kod. İstediğiniz versiyonu bırakın, diğerini ve işaretçileri (<<<, ===, >>>) silin. Sonra:
bash
git add dosya-adi.js git commit -m "Merge conflict çözüldü"
Eğer merge'den vazgeçmek istiyorsanız, hiçbir şeyi değiştirmeden:
bash
git merge --abort
Her şey merge öncesi haline döner. Conflict'i çözdükten sonra doğrulama yapmak için:
bash
git diff
Conflict işaretçisi kalmadığından emin olduktan sonra commit atın.
---
Senaryo 9: Başka Branch'teki Tek Bir Commit'i Almak İstiyorum
Bir branch'te güzel bir özellik geliştirdiniz ama tüm branch'i merge etmek istemiyorsunuz. Sadece o tek commit'i main'e taşımak yeterli.
git cherry-pick tam bu iş için var.
Önce almak istediğiniz commit'in hash'ini bulun:
bash
git log --oneline feature/ozellik-branch
Sonra main branch'e geçin ve commit'i alın:
bash
git checkout main git cherry-pick a3f2c1b
O commit, main branch'e uygulandı. Birden fazla commit almak istiyorsanız:
bash
git cherry-pick a3f2c1b 8b4e9d2 2c1a7f3
Cherry-pick sırasında conflict çıkarsa merge conflict çözme adımlarının aynısını uygulayın. Vazgeçmek istediğinizde:
bash
git cherry-pick --abort
---
Senaryo 10: .env Dosyasını Commit Ettim ve Push Ettim
Bu ciddi bir güvenlik sorunu. API anahtarları, veritabanı şifreleri, servis credentials — bunları commit edip push etmek gerçek bir tehdit.
Önce yapılması gereken: push ettiğiniz servislerdeki tüm anahtarları hemen döndürün (rotate edin). Bu adımı atlamamak kritik çünkü GitHub, push edilen secret'ları otomatik tarayan botlar tarafından saniyeler içinde tespit edilebilir.
Sonra .env dosyasını Git geçmişinden tamamen silmek için:
bash
git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch .env" \ --prune-empty --tag-name-filter cat -- --all
Bu komut tüm commit geçmişini yeniden yazar ve .env'i her yerden siler. Sonra force push:
bash
git push origin --force --all
Bu işlemi yaptıktan sonra takım arkadaşlarınızın repoyu yeniden clone etmesi gerekir.
Ve bir daha olmayacak şekilde hemen .gitignore'a ekleyin:
plaintext
.env .env.local .env.production
---
Senaryo 11: Yanlış Dosyaları Commit'e Ekledim
Commit atmak üzeresiniz ama git status'a bakınca staged alanda olmaması gereken dosyalar var. node_modules, build klasörü, ya da test çıktıları girmiş.
Tüm staged dosyaları unstage etmek için:
bash
git restore --staged .
Değişiklikler kaybolmaz, sadece staged listesinden çıkar. Tek bir dosyayı çıkarmak için:
bash
git restore --staged dosya-adi.js
Sonra gerçekten commit etmek istediklerinizi tek tek ekleyin:
bash
git add src/components/Button.jsx git add src/styles/main.css
Aynı dosyanın sadece belirli satırlarını commit etmek istiyorsanız interactive mode kullanın:
bash
git add -p dosya-adi.js
Git size dosyadaki değişiklikleri tek tek gösterir ve her biri için "bu satırları ekle / atlа" diye sorar. Büyük dosyalarda kısmi commit atmak için çok kullanışlı.
---
Git Alias: Sık Kullandığınız Komutları Kısaltın
Git komutları bazen uzun ve ezberlemesi zor. Alias sistemiyle kendi kısa komutlarınızı tanımlayabilirsiniz.
bash
git config --global alias.st status git config --global alias.co checkout git config --global alias.br branch git config --global alias.last "log -1 HEAD" git config --global alias.unstage "restore --staged"
Artık git status yerine git st, git checkout yerine git co yazabilirsiniz. Son commit'i görmek için git last, staged'den çıkarmak için git unstage dosya.js.
Güzel bir log görünümü için:
bash
git config --global alias.lg "log --oneline --decorate --graph --all"
git lg yazdığınızda tüm branch'lerin görsel bir ağaç yapısını görürsünüz. Hangi branch'in nereden ayrıldığını, hangi commit'lerin nerede olduğunu tek bakışta anlarsınız.
---
Git Panic Button: Komut Ezberlemenize Gerek Yok
Tüm bu komutları ezberlemek zorunda değilsiniz. NeonDijital'in ücretsiz Git Panic Button aracını kullandığınızda yaşadığınız durumu seçiyorsunuz ve size tam olarak terminale yapıştırmanız gereken komutu veriyor.
Yanlışlıkla commit attım, yanlış branch'e yazdım, dosya sildim, commit mesajı yanlış, her şeyi mahvettim — beş farklı senaryo için hazır komutlar tek tıkla karşınızda.
Tüm geliştirici araçlarına göz atmak isterseniz benzer birçok ücretsiz araç sizi bekliyor.
---
Git'te Felaketi Önlemek İçin 5 Alışkanlık
Kurtarma komutlarını bilmek önemli ama önlemek daha iyi.
1. Push etmeden önce diff alın.
bash
git diff --staged
Commit etmek üzere olduğunuz değişiklikleri son kez gözden geçirin.
2. Küçük ve sık commit atın. Büyük commit'leri geri almak karmaşık. Küçük commit'ler hem daha kolay yönetilir hem de daha kolay geri alınır.
3. Main branch'i koruma altına alın. GitHub veya GitLab üzerinde main branch'e direkt push'u engelleyin. Her şey pull request üzerinden gitsin.
4. .gitignore'u baştan kurun. node_modules, .env, build klasörleri — bunları baştan ignore edin. Yanlışlıkla commit etmek istemezsiniz.
5. Reflog'u aklınızda tutun. Git'te neredeyse her şey kurtarılabilir. Panik yapmadan önce git reflog çalıştırın.
---
Sık Sorulan Sorular
git reset --hard kullandım, dosyalarım gitti. Kurtarabilir miyim?
Eğer o dosyalar daha önce commit edilmişse evet. git reflog ile önceki commit'i bulun ve oraya reset atın. Hiç commit edilmemişse ne yazık ki kurtarma şansı çok düşük.
Force push yaptım, takım arkadaşımın değişiklikleri kayboldu mu?
force-with-lease kullandıysanız ve arkadaşınızın commit'leri varsa Git sizi uyardı ve işlemi yapmadı. Eğer --force kullandıysanız ve onun commit'leri üzerine yazdıysanız durum karmaşık. Arkadaşınızın local branch'i hâlâ sağlamsa onun değişikliklerini geri alıp yeniden push edebilirsiniz.
Commit edilmemiş değişikliklerimi geçici olarak saklayabilir miyim?
Evet, git stash tam bunun için var.
bash
git stash git stash pop
stash değişikliklerinizi geçici bir yere kaldırır. pop ile geri alırsınız.
Yanlış dosyayı staged'e ekledim, commit etmedim.
bash
git restore --staged dosya-adi.js
Dosyayı staged'den çıkarır, değişiklikler kaybolmaz.
Git'i yeni öğreniyorum, bu komutlar güvenli mi?
--hard flag'i içeren komutlar dikkat ister. Diğerleri genellikle güvenli. Emin olmadığınızda önce git status ve git log çalıştırın, sonra adım atın. Ve kritik bir operasyon öncesinde yeni bir branch açarak çalışmak her zaman güvenli bir alışkanlık.
---
Sonuç
Git hataları korkulacak şeyler değil. Her geliştirici yanlış commit atar, yanlış branch'te çalışır, bir şeyleri siler. Önemli olan paniğe kapılmamak.
git reset, git checkout ve git reflog — bu üç komutun ne yaptığını anladığınızda Git felaketlerinin büyük çoğunluğunu çözebilirsiniz.
Hangi komutu çalıştıracağından emin değilsen, durumunu seçip doğru kurtarma komutunu veren ücretsiz Git Panic aracını kullanabilirsin.
---
Aykan KÖMÜRCÜ
NeonDijital