Git ile Panik Yönetimi
Uygulama geliştirirken bazen işler istediğimiz gibi gitmez ve bu durumda favori versiyon kontrol sistemine güveniriz. Yaptığımız değişiklikleri geri almamız ya da eski revizyonları kontrol etmemiz gerekebilir.
Aklıma gelen muhtemel panik senaryoları ve kendimizi nasıl kurtarabileceğimize bakalım..
Başlangıç olarak:
Şeklinde commit tarihimizi başlatalım.
Yanlış dosyayı git add ile ekledim ne yapmalıyım?
git add komutu yerel repomuzdaki değişiklikleri, sıradaki commit‘e eklemek üzere staging dediğimiz indekse yüklemek için kullanılır.
Ups. ceviz.md dosyasını staging‘e ekledik ama -eklememiz- gerekiyordu.
Panik Yok!
Çözümü çok basit.
İşte bu kadar. Artık dosyamız git status ile kontrol ettiğimizde orada olmayacak.
En son commit’i nasıl geri alırım?
Aşağıdaki gibi commit eklediğimizi varsayarsak?
Aslında git ile commit geri almanın zilyon tane yolu var. En basitlerinden bazılarını açıklayalım.
git revert
Bunu yaptığınız da editörünüz açılacak ve sizden bir commit mesajı girmenizi isteyecektir. Ve en son committe yaptığımız değişikleri geri alan yeni bir commit oluşturacaktır.
Tabi ki bu yöntemin avantajları olduğu gibi dezavantajları da olacaktır. En önemli avantajı son derece güvenli olması yan etkilerinin kolaylıkla geri alınabilmesidir.
Neler olduğuna şöyle bir göz atarsak:
Çıktıdan anladığımız kadarıyla revert komutu, aslında gerçek anlamda geri alma işlemi yapmıyor, aksine bir commitin etkilerini geri alan yeni bir commit oluşturuyor.
Burada dikkat etmemiz gereken can alıcı nokta; git revert ile commit tarihi değişmedi ve aynen duruyor. Bu yaklaşım public olmuş branch’lar için başka kullanıcıların değişikliklerini yıkmamak adına ve proje tarihini takip edebilmek için oldukça mantıklı. Ancak lokal bir branch’ta çalışıyorsanız ve değişiklikleriniz henüz başkalarıyla paylaşılmamışsa aynı dosyalarla ilgili değişiklikleri içeren ekstra bir commit oldukça mantıksız olacaktır.
git reset
git reset, revert’e göre daha tehkileli bir yöntem. reset ile yaptığınız bazı işlemleri geri alamayabilirsiz.
Şimdi senaryomuza geri dönelim ve lokal branchta çalışırken revert’in oluşturduğu ekstra committen duyduğumuz memnuniyetsizlikle son commit’i geri alalım.
Gördüğünüz gibi revert komutunun oluşturduğu commit ve etkileri gitti. HEAD~1 diyerek kafayı bir commit geri çekmiş olduk, git reset HEAD~2 deseydik doğrudan İlk Commit’e gelmiş olurduk. git status ile kontrol edersek revert commitinin yaptığı değişikliğin staging’e eklenmemiş olduğunu görürüz. Bu durum aslında git reset komutunun default davranışı ile alakalı bir durum.
git reflog komutu ile çıktıyı kontrol edin. Göreceksiniz ki git, yaptığımız her hareketi kayıt almış. Çalışma dizinimizi HEAD@{n} şeklinde ifade edilen konumlara resetleyebiliriz. bunun için e5f4 ile başlayan git revert işlemini yaptığımız kısma dönelim.
Şimdi git reset kısmını farklı türlü denemek için git reset HEAD~1 yapmadan önceki konumumuza geri döndük. git reset komutunu farklı bir parametre ile deneyelim.
Ve git status komutunu daha önce verdiğimizde ceviz.md dosyasının silinmek üzere staging’de beklediğini görmüştük. Şimdi tekrar kontrol ettiğimizde staging temiz ve ceviz.md olması gerektiği gibi dizinimizde duruyor ama daha önce stagingdeki değişikler uçmuş. Peki ne değişti?
git reset‘in farklı çalışma modları vardır ve bu modlardan ön tanımlı olan –mixed modunu ilk reset işleminde mod parametresi belirlemeyerek test etmiş olduk. Daha sonra ise –hard parametresini de ekleyerek tekrar denedik aradaki farkı anlamaya çalıştık. git help reset ile diğer modları kontrol ettiğimizde –mixed, –hard, –soft, –keep ve –merge olmak üzere 5 adet olduklarını görürüz. Bunlardan ilk üçünü daha sıklıkla kullanıldığı için açıklamaya çalışacağım.
-
–mixed, git reset –mixed HEAD~1 : git reset komutunun öntanımlı davranışıdır ve geri aldığımızda değişikler staging’e otomatik eklenmemiştir. git status komutu ile dosyaların eklenmek üzere olduklarını görürüz.
-
–soft, git reset –soft HEAD~1 : –mixed moduna çok benzer aradaki fark, değişiklikleri git status ile kontrol ettiğimizde, staginge eklendiklerini ve commit etmek için beklediklerini görürüz.
-
–hard, git reset –hard HEAD~1 : Bu modun denemesini beraber yapmıştık. Değişikler stagingde değil doğru kaybolmuş olurlar.
NOT: Public olmuş branchlarda reset kullanmayın. Aksine revert kullanmayı tercih edin.
Eyvah! commit mesajını yanlış girdim
Bu çok olur. Saçma bir imla hatası ya da anlam kayması her ne sebepten olursa olsun commit mesajını yenilemek gerekebilir.
Bu sayede commit mesajlarını düzenlediğiniz editör açılır ve siz commit mesajının yeni halini tekrar yayınlarsınız.
Tek satırda halledebilmek için -m parametresini eklemek.
Gördüğünüz commit kodu değişmiş. Bu da demek oluyor ki commit tarihine müdahale etmişiz. Commit tarihini değiştiren bir komut olduğu için paylaşılan branchlarda commit –amend kullanmayın.
Ben bu commit’e başka bir dosya daha ekleyecektim!
Panik yapmanın alemi yok. Olur böyle şeyler. :) –amend komutu en son commit’te değişiklikler yapmamızı sağlıyordu. Yine yardımcı olabilir.
İyi de foo ve bar ekledik ama sadece foo ekledik bar olduğu gibi duruyor.
Görüldüğü üzere –no-edit ekleyerek commit mesajına dokunmadan eksik kalan dosyayı da ekleyerek son commit güncellendi.
Gerilerde öyle bir commit var resmen yüz karası. Derhal kurtulmalıyım!
git ile tarihi baştan yazabileceğiniz çok önemli bir yardımcıya kavuşursunuz. O yardımcının adı rebase. –interactive veya kısaca -i parametresi ekleyerek geçmişe gidebilir, commit birleştirebilir, bölebilir, silebilir hatta yer değiştirebilirsiniz.
Diyelim ki foo ve bar’ın projede yeri olmadığına ve tamamen gitmeleri gerektiğine karar verdiniz.
Açılan editöre bir takım ayarlar yapmalıyız. foo ve barı kaldıracağız ve ceviz dosyasını oluşturmak ve başlık eklemek için ayrı commitler olması da anlamsız. Şimdi düzenleyerek aşağıdaki hale getirelim:
Commit mesajının ne olacağını sorduğunda “Ceviz eklendi” olanı seçiyoruz yani diğerini # ile yorum satırı yapıyoruz.
Açıkçası bayağı bir temizlik olmuş gibi :)
ekranda “ceviz” çıktısını aldıysak herşey istediğimiz gitmiş başlık eklediğimiz commit ceviz oluşturduğumuz commit ile birleşmiş demektir.
Çok sıkıntılı işlem yaptım geçmişe dönmem gerek
Git, bizim için yaptığımız işlemlere referans kaydı tutuyor. Yukarıda revert komutunu geri alırken kullandığımız gibi. git reflog ile HEAD@{n} ‘i takiben yapılan işlemle de ilgili açıklamalar. Tarihten bu kesitlere istediğiniz gibi ışınlanabilirsiniz tek yapmanız gereken git reset HEAD@{n} ile istediğiniz noktaya gidebiliriz.
Örneğin:
En temel panik yönetimi yöntemlerinden bahsetmiş olduk. Başka bir yazıda görüşmek üzere.
NOT: Hata bulursanız ya da eklemek istediğiniz birşeyler olursa yorum bırakmayı unutmayın.
Görüşmek üzere…