İçeriğe geç

Reklam

Git Reflog ile Kayıp Commit Kurtarma: Tam Rehber

Git logosu ve koyu temalı terminalde çalıştırılan git reflog ile kayıp commit kurtarma komutları

Bir dalı sildiniz ve tam beş dakika sonra içindeki iki günlük çalışmayı hatırladınız. Ya da yanlış dalda git reset --hard çalıştırdınız. Panik yapmadan önce bilmeniz gereken tek şey var: git reflog ile kayıp commit kurtarma, bu kazaların neredeyse tamamını geri alır. Git, siz fark etmeseniz bile her hareketinizin arkasına bir güvenlik ağı gerer.

Bu yazımızda git reflog nedir ve nasıl kullanılır sorusunu baştan ele alıyoruz. Komutun çıktısını nasıl okuyacağınızı, hangi kazada hangi komutun işinizi kurtardığını ve reflog’un bile yetmediği durumlarda ne yapabileceğinizi sizler için adım adım derledik. Örneklerin tamamı Git’in resmi reflog belgesine dayanıyor ve gerçek bir depoda çalıştırılarak doğrulandı.

Reklam

Git Reflog Nedir?

Reflog, “reference log” yani referans günlüğü demek. Git, deponuzdaki referansların — yani HEAD’in ve dal uçlarının — her hareketini bu günlüğe yazar. Commit attığınızda, dal değiştirdiğinizde, merge, rebase, reset ya da amend yaptığınızda arka planda satır satır kayıt düşülür.

Bu kayıtlar deponuzun içindeki .git/logs/ klasöründe düz metin olarak durur. Görmek için tek komut yeterlidir:

git reflog

Tipik bir çıktı şuna benzer:

8b7d3a9 HEAD@{0}: reset: moving to HEAD~2
9d2b8e4 HEAD@{1}: commit: ödeme formu doğrulaması eklendi
1a4c6f0 HEAD@{2}: commit: sepet toplamı hesabı düzeltildi
8b7d3a9 HEAD@{3}: checkout: moving from main to odeme-ekrani
8b7d3a9 HEAD@{4}: commit: README güncellendi

Buradaki en kritik ayrıntı şu: en üstteki satırda bir reset var ve o reset iki commit’i tarihçeden düşürmüş. Her satırdaki adres, işlemin ardından HEAD’in durduğu noktayı gösterir; bu yüzden en üstteki reset satırında, iki commit geriye dönülen 8b7d3a9 adresi yazar. Ama 9d2b8e4 ile 1a4c6f0 hâlâ listede duruyor. Yani commit’ler silinmedi, sadece hiçbir dalın ucundan erişilemez hale geldi. Reflog, o adreslerin hâlâ elinizde olduğunu gösteren not defteridir.

Komutun kendisi aslında bir kısayoldur; resmi belgeye göre git reflog, git log -g --abbrev-commit --pretty=oneline çağrısının takma adıdır. Bu tercih tesadüf değil: Git, Linus Torvalds’ın 2005’te Linux çekirdeği için yazdığı dağıtık bir sürüm kontrol sistemidir (version control) ve her aracı küçük, tek bir işi iyi yapacak biçimde tasarlanmıştır. Reflog da bu yüzden kurtarma işlemini kendisi yapmaz; size doğru commit adresini verir, gerisini git reset, git branch ya da git cherry-pick halleder. Bu tasarım anlayışının kökenini merak ediyorsanız Unix tasarım felsefesini anlattığımız yazımıza göz atabilirsiniz.

git reflog komutunun terminal çıktısı: HEAD@{0}, HEAD@{1} satırları ve commit, checkout, reset işlem etiketleri
git reflog komutunun örnek çıktısı: HEAD@{0}, HEAD@{1} satırları ve işlem etiketleri.

Git Reflog ile Git Log Arasındaki Fark Nedir?

Çoğu geliştirici git log‘u ezbere bilir ama reflog’u hiç açmaz. Oysa ikisi bambaşka soruları yanıtlar. git log “bu commit’e nasıl gelindi” der ve ata zincirini yukarı doğru yürür. Reflog ise “bu depoda ne oldu” der ve zaman sırasına bakar.

Ölçütgit loggit reflog
Ne gösterirMevcut commit’in atalarıHEAD ve dalların hareket geçmişi
SıralamaAta zinciriZaman (en yeni en üstte)
Erişilemez commit’lerGörünmezGörünür
PaylaşımKlonlanır, push edilirYalnızca yereldedir
Saklama süresiKalıcıVarsayılan 90 / 30 gün

Tablodaki son iki satır, reflog’u hem güçlü hem de kırılgan yapan şeydir. Silinmiş gibi görünen commit’leri görebilirsiniz; ama bunu yalnızca kazanın olduğu bilgisayardaki depoda ve sınırlı bir süre boyunca yapabilirsiniz.

Git Reflog Çıktısı Nasıl Okunur?

Her satır üç parçadan oluşur. Başta kısaltılmış commit adresi (hash) vardır. Ortada HEAD@{0}, HEAD@{1} gibi bir konum etiketi yer alır. Sonda ise işlemin türü ve mesajı bulunur: commit, checkout, reset, merge, rebase, commit (amend) gibi.

İşlem türü, kazanın nerede olduğunu bulmanın en hızlı yoludur. Hatanız bir reset ise reset: satırını, bir rebase ise rebase satırlarını arayın; aradığınız commit tam onun bir altındadır.

Tarihleri de görmek isterseniz çıktıyı biçimlendirebilirsiniz:

git reflog --date=iso

Yalnızca belirli bir dalın günlüğüne bakmak da mümkündür:

git reflog show odeme-ekrani

HEAD@{n} ile HEAD~n Arasındaki Fark

Doğru git reflog HEAD@{n} kullanımı, kurtarma işleminin can damarıdır ve en sık yapılan hata bu iki gösterimi karıştırmaktır. İkisi tamamen farklı şeylere işaret eder:

  • HEAD@{2}: HEAD’in iki hareket önce nerede durduğu. Kaynağı reflog’dur, yani zamandır.
  • HEAD~2: Bulunduğunuz commit’in iki kuşak önceki atası. Kaynağı commit zinciridir, yani soy ağacıdır.

Bir reset’ten sonra kaybettiğiniz commit tarihçede değil, geçmiş hareketlerde durur. Bu yüzden kurtarmada neredeyse her zaman @{n} gösterimi kullanılır. Ayrıntılı sözdizimi Git’in gitrevisions belgesinde tanımlıdır.

Tarihe Göre Referans Verme

Kaç hareket geriye gideceğinizi bilmiyorsanız sayı yerine tarih yazabilirsiniz. Git, o anda referansın nereyi gösterdiğini bulur:

git show "main@{yesterday}"
git show "HEAD@{2 hours ago}"
git diff "main@{1 week ago}" main

Bu gösterim özellikle “geçen cuma her şey çalışıyordu” durumlarında işe yarar. İki noktaya dikkat edin. Birincisi, tarih ifadeleri İngilizce yazılmalıdır; yesterday çalışır, Türkçe karşılığı çalışmaz. İkincisi, tarih o dönemde atılan commit’leri değil, sizin deponuzda referansın o tarihteki değerini verir. Günlük o tarihe kadar uzanmıyorsa Git bir uyarı basar ve elindeki en eski kaydı gösterir.

Git Reflog ile Kayıp Commit Kurtarma Senaryoları

Şimdi işin pratik kısmına gelelim. Aşağıdaki dört senaryo, günlük hayatta karşınıza çıkacak kazaların büyük çoğunluğunu kapsar. Hepsinde akış aynıdır: önce git reflog ile doğru adresi bulun, sonra o adresi kurtarın.

Bir güvenlik tavsiyesi: kurtarmayı doğrudan reset ile yapmak yerine, önce kayıp commit’ten yeni bir dal açmak her zaman daha güvenlidir. Böylece mevcut dalınızın durumunu bozmadan içeriği inceleyebilirsiniz.

1. git reset –hard Sonrası Commit Geri Getirme

En klasik kaza budur. git reset --hard HEAD~2 yazdınız ve iki commit’lik iş bir anda kayboldu. git reset –hard sonrası commit geri getirme işlemi iki komut sürer:

git reflog
# 9d2b8e4 HEAD@{1}: commit: ödeme formu doğrulaması eklendi

git reset --hard HEAD@{1}

Dalınız artık reset’ten önceki noktaya döner. Daha temkinli davranmak isterseniz aynı adresi yeni bir dala alın:

git branch kurtarma 9d2b8e4

Merge ve rebase gibi işlemlerden hemen sonraysa Git’in otomatik olarak tuttuğu ORIG_HEAD kısayolu da işinizi görür: git reset --hard ORIG_HEAD.

git reset --hard sonrası git reflog ile kayıp commit bulma ve git reset --hard HEAD@{1} ile geri getirme terminal ekran görüntüsü
git reset –hard sonrası git reflog ile kayıp commit bulma ve geri getirme akışı.

2. Silinen Git Dalını Geri Getirme

Silinen git dalını geri getirme, reflog’un en çok hayat kurtardığı senaryodur. Burada önemli bir ayrıntı vardır: bir dalı sildiğinizde o dalın kendi reflog dosyası da silinir. Yani git reflog show silinen-dal çalışmaz.

Çözüm, HEAD’in günlüğüne bakmaktır; çünkü o dalda attığınız commit’ler HEAD’in geçmişinde durur:

git reflog
# 4f512f1 HEAD@{1}: commit: kupon kodu desteği

git branch odeme-ekrani 4f512f1

Dal, silinmeden önceki son commit’iyle geri gelir. Tek tek commit almak isterseniz git cherry-pick 4f512f1 de kullanabilirsiniz.

Silinen git dalını git reflog ile bulup git branch komutuyla geri getirme: git branch -D, git reflog ve git branch odeme-ekrani terminal ekran görüntüsü
Silinen git dalını git reflog ile bulup git branch ile geri getirme akışı.

3. Yanlış git commit –amend İşlemini Geri Alma

git commit --amend, son commit’i değiştirmez; yerine yenisini koyar. Eskisi ortadan kalkmaz, sadece erişilemez hale gelir. Yanlış dosyayı ekleyip amend yaptıysanız eski hâli reflog’da bulursunuz:

git reflog
# 3422f05 HEAD@{0}: commit (amend): yanlış mesaj
# ace34f2 HEAD@{1}: commit: önemli çalışma

git reset --hard HEAD@{1}

Bu senaryoda commit (amend) etiketi işaret fişeğidir; aradığınız orijinal commit her zaman onun hemen altındadır.

4. Hatalı Rebase veya Merge Sonrası Eski Duruma Dönme

Uzun bir interaktif rebase sırasında commit’leri yanlış sıraya soktuysanız ya da çakışmaları hatalı çözdüyseniz, rebase öncesi duruma dönmek mümkündür. Rebase reflog’a birçok satır yazar; siz rebase (start) ya da rebase -i (start) satırının hemen altındaki adrese bakın:

git reflog
# 1a4c6f0 HEAD@{7}: rebase -i (start): checkout main
# 9d2b8e4 HEAD@{8}: commit: ödeme formu doğrulaması eklendi

git reset --hard HEAD@{8}

Aynı yöntem hatalı bir merge için de geçerlidir. Kısaca özetlemek gerekirse:

KazaKurtarma komutu
Yanlış reset --hardgit reset --hard HEAD@{1} veya git reset --hard ORIG_HEAD
Silinen dalgit branch <dal-adı> <hash>
Hatalı --amendgit reset --hard HEAD@{1}
Bozuk rebase / mergegit reset --hard HEAD@{n} (start satırının altı)
Tek bir commit lazımgit cherry-pick <hash>
Reflog’da iz yokgit fsck --no-reflog --lost-found
Git reflog ile kayıp commit kurtarma karar akışı infografiği: commit, silinen dal, düşürülen stash ve commit edilmemiş değişiklik senaryoları
Git reflog ile kayıp commit kurtarma karar akışı infografiği.

Reflog Yetmediğinde: git fsck ile Sarkan Commit’leri Bulmak

Bazı nesneler reflog’a hiç girmez. En bilinen örnek, git stash drop ya da git stash clear ile düşürülen zulalardır. Böyle durumlarda deponun nesne veritabanını doğrudan tarayan git fsck komutu devreye girer.

git fsck --no-reflog | grep "dangling commit"

Komut, hiçbir referanstan erişilemeyen “sarkan” (dangling) commit’leri listeler. Hangisinin aradığınız olduğunu görmek için içeriğine bakın:

git show 4b487e1

Doğru olanı bulduğunuzda düşürdüğünüz zulayı geri uygulayabilir ya da yeni bir dala alabilirsiniz:

git stash apply 4b487e1
git checkout -b kurtarilan 4b487e1

--lost-found seçeneğiyle çalıştırırsanız Git bu nesneleri .git/lost-found/ klasörüne dosya olarak da yazar. Sahnelenmiş ama commit’lenmemiş dosyalar da burada sarkan blob olarak görünür; içerikleri .git/lost-found/other/ altında birebir durur. fsck listesi genellikle uzundur ve okuması reflog kadar keyifli değildir; bu yüzden onu son çare olarak düşünün.

Git Reflog Kayıtları Ne Kadar Süre Saklanır?

Sık dolaşan bir yanlış bilgi var: “Git her şeyi 30 gün tutar.” Doğrusu resmi belgede iki ayrı ayarla tanımlıdır ve git reflog kayıtları ne kadar süre saklanır sorusunun yanıtı ikiye ayrılır:

  • gc.reflogExpire — erişilebilir kayıtlar için varsayılan 90 gün.
  • gc.reflogExpireUnreachable — hiçbir daldan erişilemeyen kayıtlar için varsayılan 30 gün.

Kritik olan ikinci maddedir; çünkü kaybettiğiniz commit’ler tam da bu gruba girer. Yani yanlışlıkla silinen bir çalışma için pratik güvenlik pencereniz genellikle bir aydır. Temizliği git gc arka planda kendiliğinden yapar, bu yüzden “sonra bakarım” demek risklidir.

Pencereyi genişletmek isterseniz ayarları değiştirebilirsiniz:

git config --global gc.reflogExpire "180 days"
git config --global gc.reflogExpireUnreachable "90 days"

Neyin silineceğini önceden görmek için de kuru çalıştırma yapabilirsiniz:

git reflog expire --expire-unreachable=30.days --dry-run --all

Güncel Git sürümlerinde hangi referansların günlüğü olduğunu git reflog list ile listeleyebilirsiniz; bu alt komut eski sürümlerde bulunmaz.

Git Reflog’un Sınırları ve Dikkat Edilmesi Gerekenler

Reflog güçlü bir güvenlik ağıdır ama sihirli değildir. Şu dört sınırı bilmeden ona güvenmeyin:

  • Tamamen yereldir. Push edilmez, klonlanmaz. GitHub veya GitLab arayüzünde reflog’unuzu göremezsiniz; kaza hangi bilgisayarda olduysa kurtarma da orada yapılır.
  • Yeni klonda boştur. Depoyu yeniden klonlarsanız kurtarma şansınızı da geride bırakırsınız.
  • Yalnızca commit’lenmiş işi kurtarır. Hiç commit etmediğiniz değişiklikler reset --hard ile gittiyse reflog boşuna bakılan yerdir. Tek istisna sahnelemedir: git add ile sahnelenmiş (staged) ama commit’lenmemiş bir dosya, git fsck --lost-found ile sarkan blob (dangling blob) olarak hâlâ kurtarılabilir; hiç sahnelenmemiş değişiklikler ise gerçekten kaybolur. Bu yüzden riskli bir işlemden önce hızlıca commit atmak ya da git stash kullanmak en ucuz sigortadır.
  • Süreli çalışır. Erişilemez kayıtlar için varsayılan olarak 30 gününüz vardır.

Buradan çıkan pratik alışkanlık şudur: sık ve küçük commit atın. Özellikle yapay zekâ araçlarıyla hızlı kod üreten bir akışta çalışıyorsanız bu daha da önemli hale gelir; vibe coding yaklaşımını incelediğimiz yazımızda değindiğimiz gibi, üretim hızı arttıkça geri alınması gereken hataların sayısı da artar. Editörünüzü verimli kullanmak da işin yarısıdır; VS Code ayarları rehberimizde günlük akışı hızlandıran ayarları derlemiştik.

Sonuç

Git’te commit’lenmiş hiçbir şey kolay kolay kaybolmaz. git reflog nedir ve nasıl kullanılır sorusunun cevabını bir kez öğrendiğinizde, yanlış bir reset ya da silinmiş bir dal artık felaket olmaktan çıkar; iki komutluk bir işe dönüşür. Kritik olan, kaza anında panikle yeni komutlar denemek yerine önce git reflog yazıp doğru adresi bulmaktır.

Özetle git reflog ile kayıp commit kurtarma üç adımdan ibarettir: günlüğü açın, kazadan önceki satırı bulun, o adresi yeni bir dala alın. Bu refleksi kazanmak için bir felaket beklemeyin; boş bir test deposunda beş dakika deneyerek bugün öğrenebilirsiniz.

Eğer bu tarz teknik içerikler ilginizi çekiyorsa, sitemizde yer alan “Sessiz Veri Bozulması (Bit Rot) Nedir, Nasıl Önlenir?” adlı yazımıza da göz atabilirsiniz.

Reklam

Abone ol
Bildir
guest
0 Yorum
Eskiler
En Yeniler Beğenilenler

Reklam

Reklam