Git Stash Kullanımı: Yarım Kalan Değişiklikleri Yönetme
Bir production sunucusunda kritik bir bug fix üzerinde çalışırken aniden başka bir şeyin öncelik kazandığını hayal et. Yarım kalan değişikliklerini ne yapacaksın? Commit etmek için hazır değiller, ama kaybolmalarını da istemiyorsun. İşte tam bu noktada git stash devreye giriyor ve sysadmin hayatını kurtarıyor.
Git Stash Nedir ve Neden Kullanırız?
Git stash, çalışma dizinindeki ve staging area’daki değişiklikleri geçici olarak saklayan bir mekanizmadır. Düşün ki bir yığın (stack) var ve sen değişikliklerini bu yığına iterek (push) temiz bir çalışma alanına kavuşuyorsun. İşin bitince o değişiklikleri yığından geri çekiyorsun (pop).
Gerçek hayattan bir senaryo düşünelim: Sabah geldin, geceleri çalışan bir backup scriptini optimize ediyordun. Tam ortasında müdürün geldi, “Production’da şu servis çökmüş, bak” dedi. Değişikliklerini ne yapacaksın? Yarım bir commit atarsan git geçmişi kirlenecek, değişiklikleri geri alırsan işin kaybolacak. git stash tam burada seni kurtarıyor.
Temel Git Stash Komutları
Değişiklikleri Saklamak
En basit kullanım şekli tek bir komutla değişikliklerini saklamak:
git stash
Bu komut çalıştığında git, tracked dosyalardaki tüm değişiklikleri ve staged değişiklikleri alır, onları stash stack’ine iter ve çalışma dizinini temizler. Ama dikkat, bu komut untracked dosyaları (yani git add ile hiç eklenmemiş dosyaları) saklamaz.
Untracked dosyaları da dahil etmek için:
git stash -u
# veya uzun hali
git stash --include-untracked
Hem untracked hem de .gitignore’daki dosyaları saklamak istersen:
git stash -a
# veya uzun hali
git stash --all
Stash’e Açıklama Eklemek
Birden fazla stash biriktirince hangisinin ne olduğunu anlamak zorlaşır. Bu yüzden stash’lere açıklama eklemek iyi bir pratiktir:
git stash push -m "backup script optimizasyonu - yarım kaldi"
git stash push -m "nginx config degisiklikleri - test edilmedi"
Bu sayede daha sonra baktığında hangi stash’in ne işe yaradığını anlayabilirsin.
Stash Listesini Görmek
Biriktirdiğin tüm stash’leri görmek için:
git stash list
Çıktı şuna benzer:
stash@{0}: On main: backup script optimizasyonu - yarım kaldi
stash@{1}: On feature/nginx-update: nginx config degisiklikleri - test edilmedi
stash@{2}: WIP on hotfix/bug-123: 4a2f891 critical fix attempt
Burada stash@{0} en son eklenen stash’tir. Sayı büyüdükçe eski stash’lere gidiyorsun.
Stash’ten Geri Dönmek
Pop ile Geri Almak
En yaygın kullanım şekli pop komutudur. Bu komut stash’i uygular ve listeden siler:
git stash pop
Bu komut her zaman en üstteki stash’i (stash@{0}) uygular. Belirli bir stash’i uygulamak istersen:
git stash pop stash@{2}
Apply ile Geri Almak
pop‘tan farkı şu: apply stash’i uygular ama listeden silmez. Aynı değişiklikleri birden fazla branch’e uygulamak istediğinde kullanışlıdır:
git stash apply stash@{1}
Örneğin bir monitoring scriptini hem staging hem de production branch’ine uygulamak istiyorsan stash’i silmeden tutup her iki branch’te de apply yapabilirsin.
Stash İçeriğini İncelemek
Neyin Saklandığını Görmek
Stash’teki değişikliklerin özetini görmek için:
git stash show stash@{0}
Daha detaylı diff görmek istersen:
git stash show -p stash@{0}
# veya
git stash show --patch stash@{0}
Bu komut çok işe yarıyor. Özellikle birkaç günlük çalışmadan sonra bir stash’e bakıp “bunu neden sakladım?” diye sormamak için önce show ile kontrol etmek alışkanlık edinmen gereken bir pratik.
Stash’leri Temizlemek
Tek Bir Stash’i Silmek
git stash drop stash@{1}
Tüm Stash’leri Temizlemek
Stash listesi kirlenirse ve hepsini temizlemek istersen:
git stash clear
Dikkatli kullan! Bu komut geri alınamaz ve tüm stash’leri siler.
Gerçek Dünya Senaryoları
Senaryo 1: Acil Hotfix Durumu
En klasik senaryo bu. Bir branch’te çalışıyorsun ve aniden production’da bir şey bozuluyor:
# feature branch'indesin ve değişiklikler var
git status
# Changes not staged for commit:
# modified: scripts/backup.sh
# modified: config/cron.d/backup
# Acil durum, değişiklikleri sakla
git stash push -m "backup optimizasyonu - production hotfix için bekliyecek"
# Temiz bir durumda hotfix branch'ine geç
git checkout main
git checkout -b hotfix/db-connection-pool
# Hotfix'i yap, commit et
vim config/database.yml
git add config/database.yml
git commit -m "fix: db connection pool limitini artir"
git push origin hotfix/db-connection-pool
# PR açıldı, merge oldu, artık kendi işine dön
git checkout feature/backup-optimization
git stash pop
Senaryo 2: Yanlış Branch’te Çalışmak
Sabah geldin, kafan karışık, direkt main branch’te değişiklik yapmaya başladın. Sonra fark ettin:
# Ana branch'te değişiklik yaptığını fark ettin
git branch
# * main
# Değişiklikleri stash'e al
git stash
# Doğru branch'e geç veya yeni oluştur
git checkout -b feature/log-rotation
# veya mevcut branch'e
git checkout feature/existing-work
# Stash'i uygula
git stash pop
Bu senaryo günde birkaç kez yaşanabiliyor, özellikle birden fazla proje arasında geçiş yapıyorsan.
Senaryo 3: Değişiklikleri Farklı Branch’lere Dağıtmak
Bir config değişikliği yaptın ve bunun hem staging hem production branch’inde olmasını istiyorsun ama şimdilik staging’de test etmek istiyorsun:
# staging branch'indesin
git stash push -m "nginx upstream timeout ayarlari"
# staging'e uygula
git checkout staging
git stash apply stash@{0}
git commit -am "nginx upstream timeout degerlerini guncelle"
git push origin staging
# Test tamamlandı, production'a da uygula
git checkout production
git stash apply stash@{0}
git commit -am "nginx upstream timeout degerlerini guncelle"
git push origin production
# Artık stash'i silebilirsin
git stash drop stash@{0}
Senaryo 4: Stash’ten Yeni Branch Oluşturmak
Bazen stash’teki değişikliklerin aslında ayrı bir branch’te olması gerektiğini anlarsın. Bunun için branch komutu var:
# Stash'ten direkt yeni branch oluştur
git stash branch feature/nginx-improvements stash@{0}
Bu komut şunları yapar: stash’in oluşturulduğu commit’ten yeni bir branch açar, stash’i uygular ve başarılı olursa stash’i siler. Çok temiz bir workflow.
Kısmi Stash: Sadece Bazı Dosyaları Saklamak
Bazen tüm değişiklikleri değil, sadece belirli dosyaları saklamak istersin. --patch veya -p flag’i bunu mümkün kılar:
git stash -p
Bu komut sana her değişiklik için interaktif olarak sorar: sakla, atla, split et gibi seçenekler sunar. y (sakla), n (saklama), s (daha küçük parçalara böl) gibi seçeneklerle ilerleyebilirsin.
Belirli dosyaları doğrudan belirtmek için:
git stash push -m "sadece nginx config" -- config/nginx/nginx.conf config/nginx/sites-available/
Bu özellik özellikle büyük değişiklikler yaptığında çok işe yarıyor. Bir kısmı hazır, bir kısmı henüz olgunlaşmamış olan değişiklikleri ayırt edebiliyorsun.
Staged ve Unstaged Değişiklikleri Ayrı Saklamak
Varsayılan olarak git stash hem staged hem unstaged değişiklikleri birlikte saklar. Sadece staged olanları saklamak istersen:
git stash push --staged
# veya kısa hali
git stash -S
Bu senaryo şu durumda kullanışlı: Bazı değişikliklerini commit’e hazırladın (stage’e ekledin), ama bazıları henüz ham. Hazır olanları başka bir branch’te kullanmak istiyorsun ama ham olanları bırakmak istiyorsun.
Git Stash ve Conflict Yönetimi
Stash’i geri uygularken conflict oluşabilir. Aynı dosyayı hem stash’e aldıktan sonra hem de stash’ten önce değiştirdiysen bu kaçınılmaz:
git stash pop
# Auto-merging config/app.conf
# CONFLICT (content): Merge conflict in config/app.conf
# The stash entry is kept in case you need it again.
Bu durumda conflict olan dosyayı düzenliyorsun:
# Conflict işaretlerini gör
vim config/app.conf
# Conflict'i çözdükten sonra
git add config/app.conf
# Stash'i listeden elle sil (pop başarısız olduğu için silmedi)
git stash drop stash@{0}
Bir önemli not: Conflict durumunda pop stash’i silmez, bu yüzden elle drop yapman gerekir.
İleri Seviye: Stash ile Script Yazma
Otomasyona meraklı bir sysadmin olarak stash’i script’lerde de kullanabilirsin. Örneğin deployment öncesi temiz bir durumda olduğundan emin olmak için:
#!/bin/bash
# deploy.sh - Deployment öncesi temizlik kontrolü
STASH_NAME="pre-deploy-$(date +%Y%m%d-%H%M%S)"
# Değişiklik var mı kontrol et
if ! git diff --quiet || ! git diff --staged --quiet; then
echo "Uncommitted değişiklikler var, stash'e alınıyor..."
git stash push -m "$STASH_NAME"
STASHED=true
fi
# Deployment işlemleri
echo "Deployment başlıyor..."
git pull origin main
./scripts/restart-services.sh
# Stash'i geri uygula
if [ "$STASHED" = true ]; then
echo "Değişiklikler geri yükleniyor..."
git stash pop
fi
Bu tarz bir script, birden fazla kişinin aynı sunucuda çalıştığı ortamlarda veya automated deployment pipeline’larında çok işe yarıyor.
Stash’leri Görsel Olarak İncelemek
Eğer terminal’de daha iyi görselleştirme istiyorsan:
# Stash'lerin log formatında görüntülenmesi
git log --oneline stash
# Tüm stash'lerin detaylı listesi
git stash list --format="%gd: %s (%cr)"
GitLens gibi VS Code eklentileri ya da GitKraken gibi GUI araçları da stash’leri görsel olarak yönetmeni sağlıyor. Ama terminal’de çalışmayı tercih eden biri olarak komut satırının sunduğu kontrol seviyesi benim için hep daha tatmin edici olmuştur.
Yaygın Hatalar ve Çözümleri
“No local changes to save” hatası: Değişikliğin yoksa veya tüm dosyalar untracked ise stash çalışmaz. -u flag’ini eklemeyi dene.
Stash pop sonrası conflict sürprizleri: Stash aldığın branch’ten farklı bir branch’te pop yaparsan conflict olasılığı artar. Stash’i uygulayacağın branch’in durumunu önce git status ile kontrol et.
Eski stash’leri unutmak: git stash list komutunu ara ara çalıştır. Haftalarca orada duran stash’ler genellikle ya obsolete olmuştur ya da kaybolmuş önemli değişiklikler içerir.
git stash clear’ı yanlış kullanmak: Bu komutu çalıştırmadan önce git stash list ile ne kaybedebileceğini gör. Özellikle production ortamlarında dikkatli ol.
Stash Yerine Kullanılabilecek Alternatifler
Stash mükemmel bir araç ama her duruma uygun değil. Alternatifleri de bilmek gerekir:
- WIP commit:
git commit -m "WIP: yarım çalışma"şeklinde geçici commit atıp sonragit reset HEAD~1ile geri alabilirsin. Stash’ten daha görünür bir yöntem. - Geçici branch: Değişiklikleri yeni bir branch’e commit edip oraya bırakmak. Ekip çalışmasında daha şeffaf.
- Patch dosyaları:
git diff > degisiklikler.patchile değişiklikleri dosyaya yazıp sonragit apply degisiklikler.patchile uygulayabilirsin.
Her birinin yeri ve zamanı var. Stash, kısa süreli geçici saklama için ideal. Uzun süre bekleyecek değişiklikler için branch açmak daha sağlıklı.
Sonuç
git stash sysadmin toolbox’ındaki sessiz kahramanlardan biri. Günlük çalışmada defalarca kurtarıcı olabiliyor; acil hotfix’ler, yanlış branch’te yapılan değişiklikler, yarım kalan işler… Temel komutları ezberlemek yeterli değil, show, branch, kısmi stash gibi özellikleri de repertuarına katmak seni çok daha verimli kılacak.
Pratik öneri olarak şunu söyleyeyim: Stash kullanırken her zaman açıklama ekle (-m flag’i), düzenli olarak listeyi kontrol et ve çok uzun süre stash’te bırakma. Stash geçici bir köprü, kalıcı bir depo değil. Değişiklikler uzun süre bekleyecekse branch aç, commit at, push yap. Ekibindeki diğer insanlar da görsün, tartışsın, yorum yapsın. Git’in asıl gücü zaten bu işbirliğinde.
