Yanlış Commit'i Geri Alma: Revert, Reset ve Reflog

Haberci

SEO UZMANI
Yönetici
Katılım
21 May 2023
Mesajlar
475
Tepki
17
Puan
18
Bir commit’i geri almakla onu geçmişten silmek aynı şey değil. Özellikle değişiklik uzak depoya gönderildiyse, panikle yazılan tek bir reset --hard komutu küçük bir hatayı ekipçe çözülecek daha büyük bir probleme çevirebilir.

Önce şu ayrımı yapın: Paylaşılan geçmişi mi düzeltiyorsunuz, yalnızca kendi yerel dalınızı mı? Doğru komut bu cevaptan sonra belli olur.



748




Komuttan önce' Alıntı:
Çalışma ağacındaki commit edilmemiş dosyalar reflog’un korumasında değildir. Önce durumu görün, sonra geri alma yöntemini seçin.

İlk iki dakikada fotoğrafı çekin​


Hemen geçmişi değiştirmek yerine üç çıktıyı alın:

Kod:
git status --short
git log --oneline --decorate -5
git reflog --oneline -10

git status --short boş değilse commit edilmemiş değişiklikleriniz var demektir. Bunları ayrı bir geçici commit’e almak veya git stash push -u -m "geri alma öncesi" ile saklamak düşünülebilir. Stash kullandıysanız git stash list çıktısında kaydı gördüğünüzü doğrulayın.

Yanlış commit hâlâ HEAD konumundaysa bir güvenlik dalı açmak da ucuz bir önlemdir:

Kod:
git branch yedek/yanlis-commit HEAD

Bu dal sorunu çözmez; yalnızca o commit’e kolayca dönebileceğiniz sabit bir isim verir.

Üç araç aynı işi yapmıyor​


  • Revert: Seçilen commit’in etkisini tersine çeviren yeni bir commit oluşturur. Eski commit geçmişte kalır. Push edilmiş ve başkalarının çekmiş olabileceği bir değişiklikte genellikle en güvenli başlangıç budur.
  • Reset: Bulunduğunuz dalın ucunu başka bir commit’e taşır. --soft, --mixed ve --hard çalışma alanını farklı biçimde etkiler; bu yüzden “geri al” düğmesi gibi düşünülmemelidir.
  • Reflog: Yerel depoda dal ve HEAD işaretçilerinin yakın geçmişte nerede bulunduğunu gösterir. Yanlış reset veya rebase sonrasında kaybolmuş görünen commit’in kimliğini bulmak için kullanılır.

Dosya düzeyindeki git restore ise ayrı bir araçtır. Dalın ucunu taşımaz; seçilen kaynaktaki dosya içeriğini çalışma ağacına veya indekse getirir. Commit edilmemiş içeriği üzerine yazabileceği için bunda da önce git diff ile bakmak gerekir.

Push edilmiş commit için geçmişi koruyun​


Ekip arkadaşınızın çekmiş olabileceği bir commit’i düzeltirken temel yol şudur:

Kod:
git revert <yanlis_commit_sha>
git status
git log --oneline -3

Git ters değişikliği hazırlayıp yeni bir commit oluşturur. Çakışma çıkarsa dosyaları rastgele geçmek yerine hangi satırın korunacağına karar verin; vazgeçmek gerekirse git revert --abort işlemi başlangıç durumuna döndürür.

Bir merge commit’ini geri almak için internette görülen git revert -m 1 ... komutunu doğrudan kopyalamayın. -m ile hangi ebeveynin ana hat olduğunu siz söylersiniz; yanlış seçim sonraki birleştirmelerin davranışını etkileyebilir.

Henüz paylaşılmamış son commit’te reset düşünülebilir​


Son commit yalnızca sizin yerel dalınızdaysa ve dosyaları kaybetmeden commit’i yeniden düzenlemek istiyorsanız:

Kod:
git reset --soft HEAD^
git diff --cached

--soft dalı bir commit geri taşırken değişiklikleri staged durumda bırakır. Düzeltip yeniden commit edebilirsiniz. Varsayılan --mixed değişiklikleri çalışma dosyalarında tutar fakat staged durumdan çıkarır.

--hard ise hedef commit’e uymayan takip edilen çalışma dosyalarını ve indeksi de değiştirir. “Nasıl olsa reflog var” diyerek kullanılacak bir seçenek değildir; özellikle commit edilmemiş değişiklikler ve Git’in hiç takip etmediği dosyalar için reflog bir yedek değildir.

Yanlış hard reset sonrasında gerçek bir kurtarma örneği​


Aşağıdaki kısa oturum boş bir geçici depoda Git 2.43.0 ile çalıştırıldı. Commit hash’leri bu denemeye aittir; sizde farklı olacaktır.

Kod:
$ git log --oneline -2
b8bbcbb yanlış değişiklik
614b353 çalışan sürüm

$ git reset --hard HEAD^
HEAD is now at 614b353 çalışan sürüm

$ git reflog --oneline -2
614b353 HEAD@{0}: reset: moving to HEAD^
b8bbcbb HEAD@{1}: commit: yanlış değişiklik

$ git branch kurtarma HEAD@{1}
$ git show --no-patch --oneline kurtarma
b8bbcbb yanlış değişiklik

Burada commit silinmedi; dalın ucu geriye taşındı. Reflog eski konumu gösterince önce kurtarma dalı oluşturuldu. Bu, kaydı incelerken yeni işlemlerle HEAD@{1} sırasının değişmesinden de korur. Daha sonra gerekirse o commit’ten dosya alınabilir, cherry-pick yapılabilir veya güvenli bir düzeltme hazırlanabilir.

Reflog’un yalnızca o yerel depodaki hareketleri tuttuğunu unutmayın. Başka bilgisayara senkronlanan bir yedek değildir ve eski girdiler zamanla temizlenebilir. Commit’i bulduğunuz anda anlamlı isimli bir dal ya da etiketle erişilebilir hâle getirmek bu yüzden önemlidir.

Tek dosyayı eski hâline almak istiyorsanız​


Bütün commit’i değil, yalnızca bir dosyanın bilinen sürümünü geri getirmek için kaynak commit’i açıkça belirtin:

Kod:
git restore --source=<saglam_commit_sha> -- yol/dosya.ext
git diff -- yol/dosya.ext

Önce farkı inceleyin, testinizi çalıştırın, sonra bunu normal bir commit olarak kaydedin. Böylece “hangi dosya niçin geri döndü?” sorusunun cevabı geçmişte kalır.

Git’e yeni başlıyorsanız forumdaki Git’in temel özellikleri ve kullanımı konusu kavramları tamamlıyor. Commitleri küçük tutma, test ve kod inceleme tarafı için veri odaklı yazılım geliştirme akışına da bakabilirsiniz.

Komutların güncel davranışı için Git projesinin revert, reset, reflog ve restore belgeleri birincil kaynaktır.

Takıldığınız yerde, gizli bilgileri temizleyerek git status --short, son birkaç git log satırı ve yapmak istediğiniz sonucu paylaşın. “Commit görünmesin mi, değişiklikler dosyalarda kalsın mı, yoksa ortak geçmiş mi düzeltilsin?” sorusunun cevabı doğru yolu epey kısaltır.



Dijital Dünyanıza Yön Veren Pusula
 

Ekli dosyalar

  • git-te-guvenli-geri-alma_1000x120.jpg
    git-te-guvenli-geri-alma_1000x120.jpg
    7.5 KB · Görüntüleme: 1
Geri
Üst