Git Notları #7 — Git Reset

Mustafa Zahid Efe
6 min readJan 23, 2018

Gecenin 3'ünde yazılmaya başlanmış bir yazıdan daha herkese merhaba. Bu saatlerde güzel jazz müzikler eşliğinde yazı yazmayı çok seviyorum. Şu anda bu şarkıyı dinliyorum, okurken siz de dinleyebilirsiniz. Benim odaklanmama yardımcı oluyor, belki sizde de benzeri bir etki bırakabilir.

Bu bölümde sizlere Git’in reset komutundan bahsedeceğim. Bu komutun temel amacı yanlışlıkla oluşturduğumuz commitleri geri almak diyebiliriz. Şimdi hemen daha önceki yazılarda üzerinde çalıştığımız dizine gidelim. Branchler için örnek göstermek adına oluşturduğumuz güzide dizinimizi açalım terminalimizde ve hemen yeni bir örnekle başlayalım. Öncelikle bir değişiklik yapmamız lazım. README.md adında bir dosya oluşturalım ve içine herhangi bir şey yazalım. Tek satırlık bir yazı olursa iyi olur.

Şu anda readme dosyamız untracked durumda. Şimdi dosyamızı Git’e ekleyelim ve bir commit alalım.

git add README.md

git commit -m "Readme dosyasi olusturuldu"

Şimdi git log diyelim ve sonuca bir bakalım. Son durumumuz neymiş.

git log

Gördüğünüz gibi şu anda Readme dosyamızın eklendiği commit en son commit olarak görünüyor.

O da ne ? Bir problem var. Meğer bu readme dosyası bu projeye ait değilmiş. Commit de aldık şimdi. Dosyayı silebiliriz ama git log dediğimiz zaman bu kara leke her zaman karşımıza çıkacak. Bizim zamanda yolculuk yapıp bu commiti geri almamız lazım. Şimdi tam olarak reset komutunu kullanmanın zamanı.

Reset komutuna bakmadan önce bilmemiz gereken bir kavram var. HEAD kavramı…

Üzerinde bulunduğunuz branchteki en son alınan commite HEAD denir. Eğer checkout ile herhangi bir commite gidilirse (bu olayı daha sonraki yazılarda anlatacağım), bu gittiğimiz commit HEAD olur ve bu duruma da detached Head denir. Zaten fark ettiyseniz git log dediğimiz zaman son aldığımız commitin yanında (HEAD -> master) yazıyordu. Bu bilgiyi öğrendiğimize göre şimdi reset komutumuzu inceleyebiliriz.

Reset Komutu Nedir, Ne İşe Yarar ?

Reset komutu, yaptığımız herhangi bir committen sonraki bütün commitleri kaldırmaya yarar. İşinize yarayacağını düşündüğüm üç tane parametresi var, bunlardan bahsetmek istiyorum. Bu parametreler: Soft, mixed ve hard.

Önce ne olduklarını söyleyeyim, sonra örnek yapalım.

Git reset komutuna soft parametresini verip bir commit belirtirseniz eğer, Git bu belirttiğimiz commiti ve sonrasındaki commitleri silecektir, düzenlenmiş dosyalar da Git’e eklenmiş hale gelecektir. Dosyalardaki değişiklikler bozulmayacaktır.

Git reset komutuna mixed parametresini verdiğimiz zaman ise Git, bu belirttiğimiz commiti ve sonrasındaki commitleri silecektir. Dosyalarımızdaki değişiklikler gitmeyecek ancak dosyalarımız Git’e eklenmemiş olacaktır, yani untracked hale gelecektir.

Git reset komutuna hard parametresini verip bir commit belirttiğinizde ise bu belirttiğiniz commiti ve sonrasındaki commitleri tamamen silip dosyalarda yaptığınız değişiklikleri de geri alıyor. Yani yaptığınız her şey uçup gidiyor. Bunu kullanacağınız zamanlarda çok dikkatli olun.

Evet, teorik kısmı hallettik. Şimdi canlı canlı örnek yapalım.

Readme dosyası oluşturup bir commit almıştık hatırlarsanız. Şimdi şöyle bir şey yapalım. Bu değişikliğimizi geri alalım ama dosyamız hala tracked halde olsun. Bunun için git reset komutuna soft parametresini vereceğiz. Hangi commite döneceğimizi belirtmek için de commitin hashini kullanacağız. Hani git log dediğiniz zaman çıkan o uzun, anlamsız yazı var ya. İşte o bizim commitimizin hashi oluyor.

Öncelikle bütün commitleri listeleyelim ve dönüş yapacağımız commitin hashini alalım.

git log --pretty=oneline

Bütün commitlerimizi güzelce ekrana yazdırdık.

Şimdi aşağıdan üçüncü, yukarıdan ikinci commite geri dönelim. Bu commitimizin hashindeki ilk 7 karakteri almamız yeterli. İsterseniz daha fazla da alabilirsiniz. Şimdi sadece commiti silelim ancak değişikliklerimiz Git’e eklenmiş halde kalsın. Vermemiz gereken komut şu:

git reset --soft 08d467a

Eğer isterseniz hash’in tamamını veya bir kısmını da kopyalayıp yapıştırabilirsiniz. Şimdi ufak bir ipucu vereyim sonra devam edelim. Mevcut branch üzerindeki son commitin HEAD olduğundan bahsetmiştik. Eğer bu hashi yazmak istemiyorsak ve HEAD’e yakın bir commite gideceksek head~1 veya head~2 gibi ifadeler kullanabiliriz. Örnek olarak şu komutu verdiğimizde,

git reset --soft HEAD~1

Git, en son commitimizden (yani headden) bir önceki commite dönecektir. Eğer isterseniz bu sayıyı 2, 3, 5 vs. yaparak daha eski commitlere de dönebilirsiniz. Zaten birçoğunuz fark etmiştir ama yine de belirtmekte fayda görüyorum, HEAD’den sonra gelen işaret eksi değil, tilda işareti kullandık.

Bu ipucunu da verdiğimize göre devam edebiliriz. Şimdi tekrar git log diyip bir bakalım, commitlerimizin son hali neymiş.

git log --pretty=oneline

Gördüğünüz gibi şu anda sadece üç tane commitimiz var. Diğer commitimiz silinmiş. Bir de dosyalarımızın durumuna bakalım.

git status

Gördüğünüz gibi dosyamız Git’e eklenmiş halde duruyor.

Bu parametremiz bu kadardı. Şimdi hemen mixed parametresine bir bakalım, onu canlı canlı görelim. Tabii bundan önce tekrar commit almamız gerekiyor. Şu anda readme dosyamız zaten Git’e ekli olduğu için sadece commit alalım.

git commit -m "README dosyasi eklendi"

Şimdi diğer parametremizi deneyelim.

git reset --mixed HEAD~1

Önceki örnekte yaptığımız gibi en sondan bir önceki commitimize döndük. Şimdi tekrar dosyalarımızın durumuna bakalım.

git status

Gördüğünüz gibi değişikliklerimiz hâlâ duruyor ama dosyamız untracked olmuş.

Şimdi son olarak da hard parametremize bakalım. Her şeyden önce bu parametrenin çok tehlikeli olduğunu ve değişikliklerinizi kalıcı olarak kaybedebileceğinizi unutmayın. Öncelikle tekrar dosyamızı Git’e ekleyip commit alalım.

git add README.md

git commit -m "README tekrar eklendi."

Şimdi bir önceki adımda yaptığımız şeyi tekrar yapalım, bu sefer hard parametresi ile.

git reset --hard HEAD~1

Böylece son committen bir önceki commitimize dönmüş olduk ve döndüğümüz committen sonraki bütün commitleri sildik. Yalnız bu komutunun diğerlerinden ciddi bir farkı var. Şimdi git status diyerek son duruma bir bakalım.

Gördüğünüz gibi yeni oluşturduğumuz dosyamız silinmiş durumda. Bir de hard parametresini kullandığınız zaman şu şekilde bir çıktıyla karşılaşıyorsunuz.

HEAD’imizin artık a593dca ile başlayan hashe sahip commit olduğunu söylüyor. Hemen yan tarafında da commit açıklaması var.

Şunu merak ediyor olabilirsiniz: Bu git resetin parametreleri var, iyi güzel de kendi başına hiçbir işe yaramıyor mu bu ?

Yarıyor tabii ki de efendim. Yaramaz olur mu ? Tek başına git reset komutunu verdiğiniz zaman Git’e eklediğiniz dosyaları untracked hale getiriyor. İsterseniz hemen bir örnek dosya oluşturalım. Mesela test.html olsun dosya ismimiz. İçine de sadece html etiketlerini açıp kapatabilirsiniz, çok bir şey yazmanıza gerek yok. Şimdi hemen bu dosyamızı Git’e ekleyelim.

git add test.html

Şimdi git status diyerek bir kontrol edelim, dosyamızın son durumunu.

git status

Şu an gördüğünüz üzere commit edilecek değişiklikler arasına gelmiş bulunuyor test.html dosyamız.

Şimdi hemen reset komutumuzu verelim ve bir bakalım, neler olacak ?

git reset

Herhangi bir çıktı görmemiş olmanız gerekiyor bu komuttan sonra. Şimdi tekrar status diyip bir bakalım.

git status

Gördüğünüz üzere test.html dosyamız artık untracked dosyalar arasında. Eğer burada birden fazla dosya olsaydı bunların hepsi untracked olmuş olacaktı.

Evet, bu yazıda anlatacaklarım bu kadar. Eğer bir yanlışlık, eksiklik veya sorunuz varsa bunları yorum olarak belirtebilirsiniz. Bir sonraki yazıda görüşmek üzere, herkese iyi günler ve iyi çalışmalar dilerim.

--

--

Mustafa Zahid Efe

Web Developer @ Megafonn Creative Digital Agency. Blogger, Youtuber. (More information: zahidefe.net)