Git ile Hataları Geri Alma Kılavuzu (2. Kısım)
Yayınlanan: 2022-03-10“Git ile Hataları Geri Almak” konulu serimizin bu ikinci bölümünde, tehlikenin gözlerinin içine tekrar cesurca bakacağız: Dört yeni kıyamet senaryosu hazırladım - elbette, kellemizi kurtarmanın bazı akıllı yolları da dahil! Ancak konuya girmeden önce: Git'teki hatalarınızı geri almanıza yardımcı olacak daha da fazla kendini kurtarma yöntemi için Git'teki önceki makalelere göz atın!
Hadi gidelim!
Reflog Kullanarak Silinmiş Bir Dalı Kurtarma
Hiç bir şubeyi sildiniz ve kısa bir süre sonra silmemeniz gerektiğini anladınız mı? Bu duyguyu bilmiyorsanız pek olası olmasa da bunun iyi bir duygu olmadığını söyleyebilirim. O şubenin taahhütlerine giren tüm zor işleri, şimdi kaybettiğiniz tüm değerli kodları düşünürken, bir hüzün ve öfke karışımı sizi süründürür.
Neyse ki, "Reflog" adlı Git aracının yardımıyla bu dalı ölümden geri getirmenin bir yolu var. Bu aracı serimizin ilk bölümünde kullanmıştık, ancak burada biraz bilgi tazeleyelim: Reflog, Git'in yerel deponuzdaki HEAD işaretçisinin her hareketini not ettiği bir günlük gibidir. Diğer bir deyişle, daha az nerdy kelimeler: her kontrol ettiğinizde, taahhütte bulunduğunuzda, birleştirdiğinizde, yeniden temellendirdiğinizde, kirazdan seçim yaptığınızda, vb., bir günlük girişi oluşturulur. Bu, işler ters gittiğinde Reflog'u mükemmel bir güvenlik ağı yapar!
Somut bir örneğe bakalım:
$ git branch * feature/login master
Şu anda şube feature/login
kontrol ettiğimizi görebiliyoruz. Diyelim ki sileceğimiz dal bu (yanlışlıkla). Ancak bunu yapmadan önce farklı bir şubeye geçmemiz gerekiyor çünkü mevcut HEAD şubemizi silemeyiz!
$ git checkout master $ git branch -d feature/login
Değerli özellik dalımız artık yok - ve (a) hatamızın ciddiyetini anlamanız ve (b) biraz yas tutmanız için size bir dakika vereceğim. Gözyaşlarını sildikten sonra bu dalı geri getirmenin bir yolunu bulmalıyız! Reflog'u açalım (sadece git reflog
yazarak) ve bizim için neler sakladığını görelim:
Çıktıyı anlamanıza yardımcı olacak bazı yorumlar:
- Her şeyden önce, Reflog'un girişlerini kronolojik olarak sıraladığını bilmeniz gerekir: en yeni öğeler listenin başındadır.
- En üstteki (ve dolayısıyla en yeni) öğe, dalı silmeden önce gerçekleştirdiğimiz
git checkout
komutudur. Reflog'un görev bilinciyle kaydettiği bu “HEAD işaretçi hareketlerinden” biri olduğu için burada Reflog'a kaydedilir. - Büyük hatamızı geri almak için, bundan önceki duruma geri dönebiliriz - bu da Reflog'da açık ve net bir şekilde kaydedilmiştir!
Öyleyse, bu "önce" durumu SHA-1 karmasıyla başlayan yeni bir şube ("kayıp" şubemizin adıyla) oluşturarak deneyelim:
$ git branch feature/login 776f8ca
Ve işte! Görünüşe göre kayıp şubemizi şimdi restore ettiğimizi görmekten memnun olacaksınız!
“Tower” gibi bir Git masaüstü GUI kullanıyorsanız, güzel bir kısayol kullanabilirsiniz: son komutu geri almak için klavyenizde CMD + Z tuşlarına basmanız yeterlidir - bir dalı şiddetle silmiş olsanız bile!
Taahhüdü Farklı Bir Şubeye Taşıma
Çoğu ekipte, main
veya develop
gibi uzun süredir devam eden dallarda taahhüt vermeme konusunda bir anlaşma vardır: bunun gibi şubeler yalnızca entegrasyonlar (örneğin, birleştirmeler veya yeniden temeller) yoluyla yeni taahhütler almalıdır . Ve yine de, elbette, hatalar kaçınılmazdır: Yine de bazen bu dalları unutur ve taahhüt ederiz! Peki yaptığımız pisliği nasıl temizleyebiliriz?
Neyse ki, bu tür sorunlar kolayca düzeltilebilir. Kollarımızı sıvayıp işe başlayalım.
İlk adım, doğru hedef şubeye geçmek ve ardından Cherry cherry-pick
komutunu kullanarak taahhüdü aşırı taşımaktır:
$ git checkout feature/login $ git cherry-pick 776f8caf
Şimdi, ilk etapta olması gereken yerde, istediğiniz dalda taahhüdünüz olacak. Mükemmel!
Ama hala yapılacak bir şey var: İlk başta kazara düştüğü dalı temizlememiz gerekiyor! cherry-pick
komutu, tabiri caizse, taahhüdün bir kopyasını oluşturdu - ancak orijinal, uzun süredir devam eden şubemizde hala mevcut:
Bu, uzun süredir devam eden şubemize geri dönmemiz ve onu kaldırmak için git reset
kullanmamız gerektiği anlamına gelir:
$ git checkout main $ git reset --hard HEAD~1
Gördüğünüz gibi, hatalı taahhüdü silmek için burada git reset
komutunu kullanıyoruz. HEAD~1
parametresi Git'e "HEAD'in arkasındaki 1 revizyona geri gitmesini" söyler ve bu dalın geçmişinden en üstteki (ve bizim durumumuzda: istenmeyen) taahhüdü etkin bir şekilde siler.
Ve işte: taahhüt şimdi olması gereken yerde ve uzun süredir devam eden şubemiz temiz - sanki hatamız hiç olmamış gibi!
Eski Bir Taahhüdün Mesajını Düzenleme
Bir yazım hatasını gizlice bir taahhüt mesajına sokmak çok kolaydır - ve bunu ancak çok sonra keşfedebilirsiniz. Böyle bir durumda, git commit
commit'in eski --amend
seçeneği bu sorunu çözmek için kullanılamaz, çünkü yalnızca en son taahhütte çalışır. Bundan daha eski olan herhangi bir taahhüdü düzeltmek için “Interactive Rebase” adlı bir Git aracına başvurmamız gerekiyor.
İlk olarak, Interactive Rebase'e taahhüt geçmişinin hangi bölümünü düzenlemek istediğimizi söylemeliyiz. Bu, ona bir taahhüt karması besleyerek yapılır: manipüle etmek istediğimizin ana taahhüdü.
$ git rebase -i 6bcf266b
Ardından bir editör penceresi açılacaktır. Komutta İnteraktif Rebase için temel olarak sağladığımızdan sonraki tüm taahhütlerin bir listesini içerir:
Burada, ilk dürtünüzü takip etmemeniz önemlidir: bu adımda henüz taahhüt mesajını düzenlemiyoruz. Bunun yerine Git'e yalnızca hangi taahhüt(ler)le ne tür bir manipülasyon yapmak istediğimizi söyleriz. Oldukça uygun bir şekilde, bu pencerenin altındaki yorumlarda not edilen bir eylem anahtar kelime listesi var. Bizim durumumuz için, 1. satırı reword
ile işaretliyoruz (böylece standart pick
yerine geçiyor).
Bu adımda yapılması gereken tek şey editör penceresini kaydedip kapatmaktır. Karşılığında, işaretlediğimiz taahhüdün mevcut mesajını içeren yeni bir editör penceresi açılacaktır. Ve nihayet düzenlemelerimizi yapmanın zamanı geldi !
İşte sizin için tüm süreç bir bakışta:
Bozulan Bir Taahhüdü Düzeltme (Çok Zarif Bir Şekilde)
Son olarak, geri alma aletlerinin İsviçre Çakısı fixup
bir göz atacağız. Basitçe söylemek gerekirse, olaydan sonra bozuk/eksik/yanlış bir taahhüdü düzeltmenize izin verir. İki nedenden dolayı gerçekten harika bir araçtır:
- Sorunun ne olduğu önemli değil.
Dosya eklemeyi unutmuş, bir şeyi silmiş, yanlış bir değişiklik yapmış veya sadece bir yazım hatası yapmış olabilirsiniz.fixup
tüm bu durumlarda işe yarar! - Son derece zariftir.
Bir taahhütteki bir hataya karşı normal, içgüdüsel tepkimiz, sorunu çözen yeni bir taahhüt oluşturmaktır. Bu çalışma şekli, ne kadar sezgisel görünse de, taahhüt geçmişinizin çok yakında çok kaotik görünmesini sağlar. "Orijinal" taahhütleriniz ve ardından orijinal taahhütlerde yanlış giden şeyleri düzelten bu küçük "yara bandı" taahhütleriniz var. Geçmişiniz, kod tabanınızda ne olduğunu anlamayı zorlaştıran küçük, anlamsız yara bandı taahhütleriyle dolu.
fixup
girdiği yer burasıdır. Yine de bu düzeltici yara bandı taahhüdünü yapmanıza olanak tanır. Ama işte sihir geliyor: daha sonra bunu orijinal, bozuk taahhüde uygular (bunu bu şekilde onarır) ve ardından çirkin yara bandı taahhüdünü tamamen atar!
Birlikte pratik bir örnek üzerinden gidebiliriz! Diyelim ki burada seçilen taahhüt bozuldu.
Bir de error.html
isimli bir dosyada sorunu çözecek değişiklikler hazırladığımı da söyleyelim. İşte yapmamız gereken ilk adım:
$ git add error.html $ git commit --fixup 2b504bee
Yeni bir taahhüt oluşturuyoruz, ancak Git'e bunun özel bir taahhüt olduğunu söylüyoruz: bu, belirtilen SHA-1 karma (bu durumda 2b504bee
) ile eski bir taahhüt için bir düzeltmedir.
Şimdi ikinci adım, bir Etkileşimli Yeniden Taban oturumu başlatmaktır - çünkü fixup
, Etkileşimli Yeniden Tabanın büyük araç setine aittir.
$ git rebase -i --autosquash 0023cddd
Bu komut hakkında iki şey açıklamaya değer. İlk olarak, neden burada revizyon karması olarak 0023cddd
? Çünkü, İnteraktif Rebase oturumumuzu, bozuk arkadaşımızın ebeveyn taahhüdünde başlatmamız gerekiyor.
İkincisi, --autosquash
seçeneği ne işe yarar? Omuzlarımızdan çok iş alıyor! Artık açılan editör penceresinde bizim için her şey hazır:
--autosquash
seçeneği sayesinde Git bizim için ağır işi çoktan halletmiştir:
- Küçük yara bandı taahhüdümüzü
fixup
eylemi anahtar kelimesiyle işaretledi. Bu şekilde Git, onu doğrudan yukarıdaki taahhütle birleştirecek ve sonra atacaktır. - Ayrıca satırları buna göre yeniden düzenledi ve yara bandı taahhüdümüzü düzeltmek istediğimiz taahhüdün hemen altına taşıdı (yine:
fixup
, işaretlenmiş taahhüdü yukarıdaki ile birleştirerek çalışır!).
Kısacası: Bizim için pencereyi kapatmaktan başka yapacak bir şey yok!
Son sonuca bir göz atalım.
- Daha önce bozulan taahhüt düzeltildi: artık yara bandı taahhüdümüzde hazırladığımız değişiklikleri içeriyor.
- Çirkin yara bandı taahhüdü atıldı: taahhüt geçmişi temiz ve okunması kolay - sanki hiçbir hata yapılmamış gibi.
Hataları Geri Almayı Bilmek Bir Süper Güçtür
Tebrikler! Artık birçok zor durumda boynunuzu kurtarabilirsiniz! Bu durumlardan gerçekten kaçınamayız: geliştiriciler olarak ne kadar deneyimli olursak olalım, hatalar işin bir parçasıdır. Ama artık onlarla nasıl başa çıkacağınızı bildiğinize göre, rahat bir kalp atış hızıyla onlarla yüzleşebilirsiniz.
Git ile yapılan hataları geri alma hakkında daha fazla bilgi edinmek istiyorsanız, tam olarak bu konuyla ilgili bir dizi kısa video olan ücretsiz "Git için İlk Yardım Seti" ni önerebilirim.
Hata yaparken eğlenin - ve tabii ki onları kolaylıkla geri alın!