Git Stash, üzerinde çalıştığımız ancak henüz commit aşamasına gelmemiş değişiklikleri geçici olarak güvenli bir yere kaldıran komuttur.
Kodlarımı kaybetme ama şu an önümden çek demenin Git'teki karşılığıdır.
Bu komutu çalıştırdığımızda Çalışma dizinimiz (Working Directory) tertemiz olur ve sanki hiç değişiklik yapmamışız gibi başka bir branch'a geçebiliriz.
Git Stash Neden Kullanılır?
Şöyle bir durumla pek çok yazılımcı karşılaşmıştır. Bir Cuma günü ve hafta sonunun hayalini kurduğunuz bir anda bir email/telefon/mesaj geliyor ve proddaki kodun patladığını söylüyor. Siz de başka bir özellik üzerinde çalışıyorsunuz.
İki seçeneğimiz var:
A)- Yarım kalan, hata veren kodlarımızı commit etmek (önerilmez).
B)- Git Stash ile değişikliklerimizi stash'a taşıyıp ortamı temizleyip gerekli branch'a geçip hatayı düzeltmek.
Git stash, stack (yığın) veri yapısı gibi davranır. Yani son eklenen stash ilk çıkar (LIFO - Last In First Out).
Çekmece Benzetmesi
Masamızın üzerinde yarım iş var. Acil bir iş geldi ve masamızı temizlememiz gerekiyor. Yarım işi çekmeceye kaldırıyoruz ve o acil işi yapıyoruz. Sonra çekmeden çıkarıp kaldığımız yerden devam edebiliyoruz.
git stash = çekmeceye kaldır.
git stash pop = çekmeden geri çıkar ve içini boşalt
git stash apply = çekmeceden bir kopya al ama orijinali orada kalsın.
git stash
git checkout hotfix
# düzeltmeyi yap
git commit -m "fix: prod hatası"
git checkout feature-branch
git stash pop
Git Stash Nasıl Kullanılır? Parametreleri Nelerdir?
- git stash: Değişiklikleri sakla, working directory'i temizle (git stash push olarak yazılması önerilir).
- git stash pop: Son sakladığını geri getir ve listeden sil.
- git stash apply: Son sakladığını geri getir ve listeden silme.
- git stash list: Adından da anlaşılacağı gibi tüm stashleri listeler. Her zaman en üstteki en yenisidir.
- git stash show: Stash içinde ne olduğunu gösterir. -p stash@{0} şeklinde ek alır.
- git stash branch: Stash’i yeni branch açarak uygular. Az bilinir ama çok efektif bir komuttur ve conflict riskini azaltır çünkü stash'i yeni bir branch'a uygularken o branch stash'in yapıldığı commit'ten başladığı için çakışma ihtimali düşer.
- git stash drop: Belirli bir stash'i listeden kaldırır. Eğer birden fazla stash varsa indis (Stash ID) belirtebiliriz: stash@{1}
- git stash clear: Dikkat: git stash clear tüm listeyi kalıcı olarak siler, geri alınamaz.
git stash ve git stash pop bu iki komut birinin en iyi arkadaşıdırlar. En çok bilinen ve kullanılanlar arasında birinciliği üstlenir çünkü stack (yığın) mantığıyla çalışmaktadır. Yani son giren ilk çıkar mantığı işler. git stash ile gönderip + pop ile en son gönderdiğimizi çekebiliriz.
Git Stash Pop vs Apply: Aralarındaki Fark Nedir?
"Eğer değişikliği geri alıp işimize devam edeceksek pop, ama değişikliği hem geri alıp hem de bir yedeğini listede tutmak istiyorsak apply kullanmalıyız. Stash birden fazla branch'a kolaylıkla uygulanabilmektedir. Eğer birden fazla branch'a uygulayacaksak tercihimiz apply olmalıdır."
Örneğin; yeni bir özellik yaptık ve iki farklı branchımız var ve ikisinde de farklı farklı konfigürasyonda çalışıyor. Biz yeni özelliği bu iki branchta git stash apply komutu ile uygulamamız mümkündür.
| Özellik | git stash pop | git stash apply |
|---|---|---|
| İşlem Sonucu | Değişikliği geri getirir. | Değişikliği geri getirir. |
| Listeden Silme | Evet (Otomatik siler) | Hayır (Listede tutar) |
| En Uygun Durum | İşi bitirip kaldığınız yerden devam edecekseniz. | Aynı değişikliği birden fazla branch'a uygulayacaksanız. |
| Hata Riski | Çakışma (conflict) çıkarsa kayıt silinmez, güvendesiniz. | Zaten silmediği için her zaman güvendesiniz. |
Özetle: Eğer "Bu işi rafa kaldırmıştım, şimdi geri alıyorum ve rafla işim bitti" diyorsanız pop; "Bu işi geri alıyorum ama belki başka bir yerde de lazım olur, bir kopyası rafta dursun" diyorsanız apply kullanın.
Önemli Detaylar
Untracked (takip edilmeyen) dosyaları varsayılan olarak kapsamaz
Yani git versiyonlama algoritması untracked olan dosyaları ek komut yazmadığımız sürece stash bölümüne aktarmaz. Eğer aktarmak istiyorsak:
git stash --include-untracked veya kısaca git stash -u. Hatta ignore edilen dosyaları da dahil etmek isterseniz git stash -a komutunu kullanabilirsiniz.
Birden fazla Stash olabilir
Stash yapısının stack yapısıyla çalıştığını, son girenin ilk çıktığını söylemiştik. Eğer birden fazla stash varsa git stash list şöyle görünür:
stash@{0}: WIP on main: login sayfası
stash@{1}: WIP on main: ödeme ekranı taslağı
stash@{2}: WIP on develop: api entegrasyonu
Stash'e İsim Bile Verebiliriz
Birden fazla stash varken ayırt etmek için çok kullanışlıdır. Söz dizimi git commit komutuna çok benzer.
Tek stash kullanıyorsan isimlendirme gereksiz olabilir ama ikincisi ve sonrakiler geldiğinde isim girmek kaçınılmaz olur. Aynı gün birden fazla yarım iş bıraktığımızda ya da birkaç gün sonra eski stash'e dönmemiz gerektiğinde ihtiyacı hissederiz. "3 gün önce ne sakladım?" sorusu geldiğinde WIP on main: abc1234 çok iyi bir hafızamız yoksa ipucu vermez.
git stash push -m "login sayfası yarım kaldı, yaşasın hafta sonu!"
# İsimsiz stash listesi — hiçbir şey anlatmıyor
stash@{0}: WIP on main: a1b2c3d
stash@{1}: WIP on main: a1b2c3d
stash@{2}: WIP on develop: a1b2c3d
# İsimli stash listesi — bakışta anlıyorsun
stash@{0}: On main: login formu validasyon yarım
stash@{1}: On main: ödeme ekranı tasarım değişikliği
stash@{2}: On develop: api timeout sorunu araştırılıyor
Belirli Bir Stash'ı Geri Getirme
pop ve apply komutlarının en son gireni getirdiğini söylemiştik. Aslında geliştiricilerin büyük bir kısmı tek bir stash ile kodlama yapsa da birden fazla stash kullanmamız mümkün.
git stash apply stash@{1} gibi
Stash yaparken yarım kalan işlerimi kaybeder miyim?
Hayır, Git Stash sistemi kodlarımızı yerel veritabanında güvenli bir şekilde saklar. Bilgisayarımız çökmediği veya .git klasörünü silmediğimiz sürece kodlarımız kaybolmaz. Benzer şekilde çakışma (conflict) yaşadığınız durumlarda git kaydı listeden silinmez. Çakışmayı çözene kadar stash beklemeye devam eder. Dikkat etmeniz gereken nokta, git stash clear komutunun çalıştırılmamasıdır.
Git Stash Komut Rehberi
| Hedef | Komut |
|---|---|
| Değişiklikleri rafa kaldır (sakla) | git stash |
| Yeni dosyaları (untracked) da sakla | git stash -u |
| Tüm saklananları listele | git stash list |
| Sonuncuyu geri getir ve listeden sil | git stash pop |
| Geri getir ama listede tut (kopya al) | git stash apply |
| Belirli bir kaydı geri getir | git stash apply stash@{2} |
| Tüm listeyi tamamen temizle | git stash clear |