İleri Komutlar
Giriş — Kayıp Eşyalar Bürosu
Bir havalimanı düşünün. Yolcular her gün eşya kaybeder — çanta, telefon, pasaport. Ama havalimanının bir "kayıp eşyalar bürosu" vardır. Burada kaybedilen her şey belirli bir süre saklanır. Eşyanızı ne zaman kaybettiğinizi ve kabaca nerede olduğunu biliyorsanız, geri alabilirsiniz.
Git'in reflog'u tam olarak bu kayıp eşyalar bürosudur. git reset --hard yaptınız ve commit'leriniz kayboldu mu? Branch'i yanlışlıkla sildiniz mi? Rebase karmaşası yüzünden kod kayboldu mu? Panik yapmayın — Git neredeyse hiçbir şeyi gerçekten silmez. Bu derste kayıp commit'leri nasıl kurtaracağınızı, repo'nuzun sağlığını nasıl kontrol edeceğinizi ve Git'in iç işleyişindeki güvenlik ağlarını öğreneceğiz.
git reflog — Git'in Gizli Günlüğü
Reflog Nedir?
Reflog (Reference Log), HEAD ve branch referanslarının her hareketini kaydeden yerel bir günlüktür. Her checkout, commit, reset, merge, rebase işlemi reflog'a yazılır.
# Reflog'u görüntüle
git reflog
# Çıktı:
abc1234 (HEAD -> main) HEAD@{0}: commit: feat: add payment module
def5678 HEAD@{1}: checkout: moving from feature to main
ghi9012 HEAD@{2}: commit: fix: resolve login bug
jkl3456 HEAD@{3}: rebase (finish): returning to refs/heads/feature
mno7890 HEAD@{4}: rebase (pick): feat: add user profile
pqr1234 HEAD@{5}: reset: moving to HEAD~3
stu5678 HEAD@{6}: commit: feat: add dashboard
vwx9012 HEAD@{7}: commit: feat: add sidebar
yza3456 HEAD@{8}: commit: feat: add navigationHer satır şunu söyler:
abc1234 → Commit SHA
HEAD@{0} → Kaç adım önce (0 = şu an)
commit: feat:... → Ne yapıldıReflog vs Log Farkı
# git log — commit geçmişini gösterir (branch'in bildiği commit'ler)
# git reflog — HEAD'in hareket geçmişini gösterir (silinen dahil!)
# Senaryo:
git commit -m "A" # commit A
git commit -m "B" # commit B
git commit -m "C" # commit C
git reset --hard HEAD~2 # A'ya geri dön
# git log sadece A'yı gösterir (B ve C "kayboldu")
# git reflog B ve C'yi de gösterir!git log görünümü: git reflog görünümü:
A ← HEAD HEAD@{0}: reset: HEAD~2
HEAD@{1}: commit: C ← BURADA!
HEAD@{2}: commit: B ← BURADA!
HEAD@{3}: commit: AReflog Detaylı Kullanım
# Belirli branch'in reflog'u
git reflog show main
git reflog show feature/auth
# Zaman bazlı filtreleme
git reflog --since="2 hours ago"
git reflog --since="yesterday"
git reflog --since="2024-01-15"
# Detaylı format
git reflog --format='%C(yellow)%h %C(green)%gd %C(blue)%gs %C(reset)%s'💡 İpucu: Reflog yereldir — remote'ta yoktur. Her geliştiricinin kendi reflog'u var.
git pushveyagit cloneile aktarılmaz. Reflog varsayılan olarak 90 gün tutulur.
Kurtarma Senaryoları
Senaryo 1: git reset --hard Sonrası Kurtarma
En yaygın "felaket" senaryosu:
# Durum: 3 commit'i yanlışlıkla sildik
git reset --hard HEAD~3
# "Oh hayır! 2 günlük çalışmam gitti!"
# Kurtarma:
# 1. Reflog'da kayıp commit'i bul
git reflog
# abc1234 HEAD@{0}: reset: moving to HEAD~3
# def5678 HEAD@{1}: commit: feat: add payment validation ← BU!
# ghi9012 HEAD@{2}: commit: feat: add payment form
# jkl3456 HEAD@{3}: commit: feat: add payment model
# 2. Kayıp commit'e geri dön
git reset --hard def5678
# HEAD is now at def5678 feat: add payment validation
# Tüm commit'ler geri geldi! 🎉Senaryo 2: Silinen Branch'i Kurtarma
# Durum: Branch'i yanlışlıkla sildik
git branch -D feature/important-work
# Deleted branch feature/important-work (was abc1234).
# "O branch'te 1 haftalık çalışma vardı!"
# Kurtarma:
# 1. Silinme anındaki commit SHA'yı bul
git reflog | grep "feature/important-work"
# veya silme mesajındaki SHA'yı kullan: abc1234
# 2. O commit'ten yeni branch oluştur
git branch feature/important-work abc1234
git checkout feature/important-work
# Branch ve tüm commit'leri geri geldi! 🎉Senaryo 3: Kötü Giden Rebase'i Kurtarma
# Durum: Interactive rebase sırasında bir şeyler karıştı
git rebase -i HEAD~5
# ... bazı commit'leri sildiniz, squash yanlış gitti ...
# Sonuç: kod bozuldu, commit'ler kayıp
# Kurtarma:
# 1. Rebase öncesi durumu bul
git reflog
# abc1234 HEAD@{0}: rebase (finish): returning to refs/heads/feature
# def5678 HEAD@{1}: rebase (squash): feat: combined commit
# ghi9012 HEAD@{2}: rebase (start): checkout main
# jkl3456 HEAD@{3}: commit: feat: my last good commit ← REBASE ÖNCESİ
# 2. Rebase öncesine dön
git reset --hard jkl3456
# veya rebase sırasındayken:
git rebase --abortSenaryo 4: Yanlış Merge'i Geri Alma
# Durum: Yanlış branch'i merge ettik
git merge wrong-branch
# Auto-merging...
# Merge made by the 'recursive' strategy.
# Kurtarma:
# 1. Merge öncesi commit'i bul
git reflog
# abc1234 HEAD@{0}: merge wrong-branch: Merge made by recursive
# def5678 HEAD@{1}: checkout: moving from feature to main ← MERGE ÖNCESİ
# 2. Merge öncesine dön
git reset --hard def5678
# veya merge commit'i revert et (geçmişi koruyarak)
git revert -m 1 abc1234Senaryo 5: Stash Drop Sonrası Kurtarma
# Durum: Stash'i yanlışlıkla drop ettik
git stash drop
# Dropped refs/stash@{0} (abc123def456789...)
# Kurtarma:
# 1. Dangling commit'leri bul
git fsck --no-reflogs | grep commit
# dangling commit abc123def456789
# 2. İçeriğini kontrol et
git show abc123def456789
# 3. Geri uygula
git stash apply abc123def456789
# veya branch oluştur
git branch recovered-stash abc123def456789git fsck — Repo Sağlık Kontrolü
fsck Nedir?
fsck (File System Check), Git object veritabanının bütünlüğünü kontrol eder. Bozuk object'leri, yetim (dangling) commit'leri ve tutarsızlıkları tespit eder.
# Temel sağlık kontrolü
git fsck
# Çıktı (sağlıklı repo):
# Checking object directories: 100% (256/256), done.
# Checking objects: 100% (1234/1234), done.
# Çıktı (sorunlu repo):
# Checking object directories: 100% (256/256), done.
# dangling commit abc1234def5678901234567890abcdef12345678
# dangling blob def5678abc1234567890123456789abcdef012345
# dangling tree ghi9012345678901234567890abcdef0123456789Dangling Objects Nedir?
Dangling (Yetim/Sarkan) Object:
Hiçbir branch, tag veya reflog tarafından referans edilmeyen
ama hâlâ .git/objects/ içinde var olan object'ler.
Nasıl oluşur?
- git reset --hard (commit'ler artık branch'te değil)
- git branch -D (branch silindi ama commit'ler kaldı)
- git rebase (eski commit'ler replaced ama silinmedi)
- git stash drop (stash commit'i referanssız kaldı)
- git commit --amend (eski commit replaced)# Dangling object'leri bul
git fsck --no-reflogs
# dangling commit abc1234...
# dangling commit def5678...
# dangling blob ghi9012...
# Dangling commit'in içeriğini gör
git show abc1234
# commit abc1234...
# Author: Ahmet <ahmet@email.com>
# Date: Mon Jan 15 10:30:00 2024
#
# feat: add user authentication
#
# diff --git a/src/auth.js b/src/auth.js
# ...
# Eğer kurtarmak istiyorsanız:
git branch recovered abc1234Detaylı fsck
# Tam kontrol (yavaş ama kapsamlı)
git fsck --full
# Ulaşılamayan (unreachable) object'leri göster
git fsck --unreachable
# Sadece dangling'leri göster
git fsck --dangling
# Bozuk object'leri kontrol et
git fsck --strictgit gc — Çöp Toplama
gc Nedir?
gc (Garbage Collection), gereksiz dosyaları temizler ve repo'yu optimize eder:
# Otomatik gc (Git gerektiğinde kendisi çalıştırır)
git gc --auto
# Manuel gc
git gc
# Agresif gc (daha iyi sıkıştırma, daha yavaş)
git gc --aggressive
# gc ne yapar:
# 1. Loose object'leri packfile'a sıkıştırır
# 2. Dangling object'leri siler (expire süresi geçmişse)
# 3. Reflog'u temizler (expire süresi geçmişse)
# 4. Boş dizinleri temizlergc ve Kurtarma Süresi
# Dangling object'ler hemen silinmez!
# Varsayılan: 2 hafta sonra gc tarafından temizlenir
# gc expire süresini kontrol et
git config gc.pruneExpire
# default: 2.weeks.ago
# Reflog expire süresi
git config gc.reflogExpire
# default: 90.days
# DİKKAT: Bu komutu çalıştırırsanız dangling'ler HEMEN silinir
git gc --prune=now # ⚠️ Kurtarma şansınız kaybolur!Kurtarma Zaman Çizelgesi:
Commit kaybı
│
├── 0-90 gün: reflog'dan kurtarılabilir ✅
│
├── 90 gün sonra: reflog temizlenir
│ └── Ama dangling object hâlâ var ✅
│
├── 14 gün sonra (gc çalışırsa): dangling silinir ❌
│
└── gc --prune=now: HEMEN silinir ❌💡 İpucu: Kritik bir kurtarma yapmanız gerekiyorsa, önce gc çalıştırmayın! gc, kurtarabileceğiniz dangling object'leri silebilir.
Gelişmiş Kurtarma Teknikleri
Cherry-pick ile Kısmi Kurtarma
Tüm branch'i değil, sadece belirli commit'leri kurtarmak istiyorsanız:
# 1. Kayıp commit'leri bul
git reflog | grep "feat: important"
# abc1234 HEAD@{5}: commit: feat: important feature part 1
# def5678 HEAD@{4}: commit: feat: important feature part 2
# 2. Sadece ihtiyacınız olan commit'leri al
git cherry-pick abc1234
git cherry-pick def5678Patch ile Kurtarma
Commit'i doğrudan uygulayamıyorsanız patch olarak çıkarabilirsiniz:
# 1. Kayıp commit'i patch'e çıkar
git show abc1234 > recovery.patch
# 2. Patch'i incele
cat recovery.patch
# 3. Patch'i uygula
git apply recovery.patch
git add .
git commit -m "recovered: important feature"Lost Merge Commit Kurtarma
# Merge commit'in parent'larını bul
git cat-file -p abc1234
# tree def567890...
# parent 111222333... ← ilk parent (merge yapılan branch)
# parent 444555666... ← ikinci parent (merge edilen branch)
# author ...
# committer ...
#
# Merge branch 'feature' into main
# Bu parent SHA'lardan branch oluşturabilirsiniz
git branch recovered-main 111222333
git branch recovered-feature 444555666git blame ile Soruşturma
git blame doğrudan bir kurtarma aracı olmasa da, "bu satırı kim, ne zaman, neden değiştirdi?" sorusuna cevap verir:
# Her satırın son değiştirilme bilgisi
git blame src/api/handler.js
# Çıktı:
# abc1234 (Ahmet 2024-01-15 10:30 1) const express = require('express');
# abc1234 (Ahmet 2024-01-15 10:30 2)
# def5678 (Mehmet 2024-01-20 14:15 3) // Handle payment processing
# ghi9012 (Ayşe 2024-02-01 09:00 4) async function processPayment(req) {
# ghi9012 (Ayşe 2024-02-01 09:00 5) const { amount, currency } = req.body;
# Belirli satır aralığı
git blame -L 10,20 src/api/handler.js
# Belirli bir commit'ten önceki durumu göster
git blame abc1234^ -- src/api/handler.js
# Satır taşınmalarını/kopyalanmalarını takip et
git blame -C -C src/api/handler.js
# Whitespace değişikliklerini yoksay
git blame -w src/api/handler.js💡 İpucu:
git blame'i "suçlama" için değil, "anlama" için kullanın. Bir satırın neden böyle yazıldığını anlamak, o satırı değiştirmeden önce çok önemlidir. Commit mesajını okumak genellikle kodu okumaktan daha aydınlatıcıdır.
Repo Bakımı ve Sağlık Kontrolü
Düzenli Bakım Checklist'i
# 1. Repo boyutunu kontrol et
du -sh .git/
git count-objects -vH
# 2. Sağlık kontrolü
git fsck --full
# 3. Gereksiz object'leri temizle
git gc
# 4. Remote'tan silinmiş branch referanslarını temizle
git remote prune origin
# veya fetch ile birlikte:
git fetch --prune
# 5. Merge edilmiş local branch'leri temizle
git branch --merged main | grep -v "main" | xargs git branch -dgit maintenance (Git 2.29+)
Modern Git, otomatik bakım komutu sunar:
# Otomatik bakımı başlat
git maintenance start
# Bu komut şunları otomatik yapar:
# - Hourly: prefetch (remote'dan arka planda fetch)
# - Daily: loose-objects (loose object'leri packle)
# - Daily: incremental-repack (packfile'ları optimize et)
# - Weekly: pack-refs (referansları pack et)
# Bakım durumunu kontrol et
git maintenance run --task=gc
git maintenance run --task=commit-graph
# Otomatik bakımı durdur
git maintenance stopGerçek Dünya Senaryosu: Cuma Günü Felaketi
# Senaryo: Cuma 17:00, sprint kapanışı, acele ediyorsunuz
# 1. Yanlış branch'tesiniz ama fark etmediniz
git checkout main # Aslında feature'da olmalıydınız
git commit -m "feat: finish sprint task"
git push origin main # Oops! Main'e direkt push!
# 2. Panik — geri al!
git reset --hard HEAD~1
git push --force origin main # Force push ile geri aldınız
# 3. AMA! O commit'teki kod lazım!
# Kurtarma:
git reflog
# abc1234 HEAD@{0}: reset: moving to HEAD~1
# def5678 HEAD@{1}: commit: feat: finish sprint task ← BU!
# 4. Doğru branch'te uygula
git checkout feature/sprint-task
git cherry-pick def5678
# 5. PR aç, review al, merge et (doğru şekilde)
git push origin feature/sprint-task
gh pr create --title "feat: finish sprint task"
# Felaket önlendi! 🎉
# Ders: Branch protection açık olsaydı,
# main'e direkt push edemezdik.git bisect — Binary Search ile Bug Arama
git bisect, binary search algoritmasıyla bug'ın hangi commit'te girdiğini bulur. 1000 commit arasında bile 10 adımda suçlu commit'i tespit eder:
# Bisect başlat
$ git bisect start
# Bu commit'te bug var (bad)
$ git bisect bad HEAD
# Bu eski commit'te bug yoktu (good)
$ git bisect good v1.0.0
# Git ortadaki bir commit'e checkout yapar
# Bisecting: 256 revisions left to test
# [abc1234] feat: Add payment module
# Test et — bug var mı?
$ npm test
# Bug var → bad
$ git bisect bad
# Git yeni bir commit'e checkout yapar
# Bisecting: 128 revisions left to test
# [def5678] refactor: Update auth module
# Test et
$ npm test
# Bug yok → good
$ git bisect good
# ... birkaç adım daha ...
# abc1234 is the first bad commit
# commit abc1234
# Author: Mehmet <mehmet@email.com>
# Date: Mon Feb 15 2026
#
# feat: Add caching layer
#
# Bug bu commit'te girmiş! 🎯
# Bisect'i bitir
$ git bisect resetOtomatik Bisect
Eğer bug'ı tespit eden bir test/script varsa, bisect'i otomatikleştirebilirsiniz:
# Otomatik bisect — script 0 dönerse good, 1+ dönerse bad
$ git bisect start HEAD v1.0.0
$ git bisect run npm test
# veya özel script
$ git bisect run ./check-bug.sh
# Git otomatik olarak binary search yapar ve suçlu commit'i bulur!Komut Referans Tablosu
Durum │ Çözüm
──────────────────────────────┼──────────────────────────────
reset --hard geri al │ git reflog → git reset --hard SHA
Silinen branch kurtarma │ git reflog → git branch name SHA
Kötü rebase geri al │ git reflog → git reset --hard SHA
│ veya git rebase --abort
Stash drop kurtarma │ git fsck --no-reflogs → git stash apply SHA
Amend öncesi commit kurtarma │ git reflog → git cherry-pick SHA
Merge geri alma │ git reset --hard MERGE_HEAD~1
│ veya git revert -m 1 MERGE_SHA
Bozuk repo tespiti │ git fsck --full
Repo optimize etme │ git gc --aggressive
Kayıp dosya arama │ git log --all --full-history -- path
Remote stale branch temizleme │ git fetch --pruneYaygın Hatalar
1. Reflog'un Yerel Olduğunu Unutmak
# ❌ "Reflog'dan kurtarabilirim" deyip repo'yu silmek
rm -rf my-repo
git clone origin my-repo
git reflog # BOŞ! Reflog yereldi, clone ile gelmez!
# ✅ Kritik kurtarmadan önce repo'yu yedekleyin
cp -r my-repo my-repo-backup2. gc --prune=now Acele Çalıştırmak
# ❌ Kurtarma gerektiren durumda gc çalıştırmak
git reset --hard HEAD~5 # 5 commit kayboldu
git gc --prune=now # Dangling object'ler silindi!
# Artık kurtarılamaz! 💀
# ✅ Önce kurtarma, sonra temizlik
git reflog # Kayıp commit'i bul
git reset --hard abc1234 # Kurtarma yap
# ... her şey yolunda olunca ...
git gc # Şimdi temizlik güvenli3. Force Push Sonrası Kurtarmaya Güvenmek
# ❌ "Nasılsa reflog var" diyerek force push yapmak
git push --force origin main
# Ekip üyelerinin local'indeki reflog SİZİN reflog'unuz değil!
# ✅ Force push öncesi düşünün
# - Ekibi bilgilendirin
# - --force-with-lease kullanın
# - Branch protection açık olsunÖzet
Bu derste Git'in kurtarma ve bakım araçlarını öğrendik:
📋 git reflog — HEAD'in hareket geçmişi, kayıp commit'leri bulma
🔄 reset kurtarma —
git reflog+git reset --hard SHAile geri dönüş🌿 branch kurtarma — silinen branch'i reflog'dan geri oluşturma
🔍 git fsck — repo sağlık kontrolü, dangling object'leri tespit
🧹 git gc — çöp toplama, repo optimizasyonu
⏰ Kurtarma penceresi — reflog 90 gün, dangling 2 hafta
🔧 git maintenance — otomatik bakım, arka plan optimizasyonu
👀 git blame — satır bazlı geçmiş soruşturması
💡 Son İpucu: Reflog, Git'in en az bilinen ama en hayat kurtarıcı özelliğidir. Kural: panik yapmadan önce her zaman
git reflogçalıştırın. Git neredeyse hiçbir şeyi gerçekten silmez — 90 gün boyunca her şeyi hatırlar. Bu bilgi bir gece yarısı production hotfix'inde hayatınızı kurtarabilir.
Bir sonraki derste büyük repo'ların performans optimizasyonunu ele alacağız: sparse checkout, partial clone, commit graph ve scalar.
AI Asistan
Sorularını yanıtlamaya hazır