Git ile Hataları Geri Alma Kılavuzu (2. Kısım)

Yayınlanan: 2022-03-10
Hızlı özet ↬ Hatalar. Bu zalim kötüler, yazılım geliştirmenin güzel dünyasında durmuyor bile. Ancak hata yapmaktan kaçınamasak da, onları geri almayı öğrenebiliriz! Bu makale, Git ile günlük çalışmalarınız için doğru araçları gösterecektir. Serinin ilk yazısına da göz atmak isteyebilirsiniz.

“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:

Git'in Reflog'u, yerel depomuzdaki tüm önemli eylemleri protokoller
Git'in Reflog'u, yerel depomuzdaki tüm önemli eylemleri protokoller. (Büyük önizleme)

Çı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!

Tower gibi bir masaüstü GUI, hataları geri alma sürecini kolaylaştırabilir.
Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

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?

Bir taahhüdü doğru hedef şubesine taşıma
Taahhüdümüz yanlış şubeye indi. Doğru hedef şubesine nasıl taşıyabiliriz? (Büyük önizleme)

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:

Doğru daldaki taahhüdün bir kopyası, ancak orijinalin hala yanlış dalda olduğu gösteriliyor
Doğru dalda taahhüdün bir kopyasını başarıyla oluşturduk, ancak orijinali hala burada - yanlış dalda. (Büyük önizleme)

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.

Değiştirmeye değer bir taahhüt mesajı
İşte değiştirmeye değer bir taahhüt mesajı. (Büyük önizleme)

İ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:

İnteraktif Rebase oturumumuzda düzenlemek için seçtiğimiz taahhütlerin aralığını gösteriyor
İnteraktif Rebase oturumumuzda düzenlemek için seçtiğimiz taahhütler aralığı. (Büyük önizleme)

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:

Eski bir taahhüdün mesajını baştan sona düzenlemek için İnteraktif Rebase'i kullanma.

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:

  1. 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!
  2. 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.
Sözde yara bandı taahhütleriyle küçük hataları sürekli olarak düzeltirseniz, taahhüt geçmişinizi okumak çok zor olabilir.
Küçük hataları "yara bandı taahhütleri" ile sürekli olarak düzeltmek, taahhüt geçmişinizi okumayı çok zorlaştırır. (Büyük önizleme)

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!

Düzeltme, düzeltmelerinizi orijinal taahhüde uygular ve ardından gereksiz yara bandı taahhüdünü ortadan kaldırır
Düzeltme, düzeltmelerinizi orijinal taahhüde uygular ve ardından gereksiz yara bandı taahhüdünü ortadan kaldırır. (Büyük önizleme)

Birlikte pratik bir örnek üzerinden gidebiliriz! Diyelim ki burada seçilen taahhüt bozuldu.

Seçilmiş olan yanlış taahhüdü zarif bir şekilde düzeltme
Seçilen taahhüt yanlış - ve bunu zarif bir şekilde düzelteceğiz. (Büyük önizleme)

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:

Etkileşimli Yeniden Temel oturum penceresi
Etkileşimli Yeniden Temel oturum penceresi (Geniş önizleme)

--autosquash seçeneği sayesinde Git bizim için ağır işi çoktan halletmiştir:

  1. 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.
  2. 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.
Temiz bir taahhüt geçmişinin nasıl göründüğüne dair bir örnek
Düzeltme aracını kullandıktan sonraki sonuç: temiz bir taahhüt geçmişi! (Büyük önizleme)

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!