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 sonra git reset HEAD~1 ile 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.patch ile değişiklikleri dosyaya yazıp sonra git apply degisiklikler.patch ile 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.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir