Stash ve Worktree
Giriş — Yarım Kalan İşler
Şöyle bir sahne düşün: feature branch'inde çalışıyorsun, kodun yarısı yazılmış, hiçbir şey commit'lenecek durumda değil. Tam o sırada production'da kritik bir bug rapor ediliyor. Hemen hotfix yapman lazım. Ama branch değiştirirsen yarım kalan değişikliklerin ne olacak?
Üç seçeneğin var:
Yarım yamalak bir "WIP" commit'i at (kirli tarihçe)
Değişiklikleri bir yere yedekle, sonra geri getir (karmaşık)
`git stash` kullan — değişikliklerini geçici bir rafa koy, işini bitir, sonra raftan geri al
Ve bir dördüncü seçenek daha var: `git worktree` ile aynı repo'nun ikinci bir çalışma dizinini aç ve iki branch'te paralel çalış!
Git Stash — Geçici Raf
Analoji — Masanı Toparlama
Masanda bir puzzle yapıyorsun. Yarısı tamamlanmış, parçalar her yere yayılmış. Tam o sırada misafir geliyor ve masayı temizlemen lazım. Ne yaparsın?
Tüm puzzle parçalarını bir kutuya koyarsın — sıraları bozulmadan. Misafir gidince kutuyu açar, masaya geri yayar ve kaldığın yerden devam edersin.
git stash işte bu kutu. Working directory ve staging area'daki değişikliklerini geçici olarak saklar, çalışma alanını temizler.
Working Directory (Masa) Stash (Kutu)
┌─────────────────────┐ ┌─────────────┐
│ modified: auth.js │ ──► │ stash@{0} │
│ staged: user.js │ ──► │ auth.js │
│ new: helper.js │ ──► │ user.js │
│ │ │ helper.js │
└─────────────────────┘ └─────────────┘
Temizlendi! ✨ Güvende! 🔒Temel Kullanım
# 1. Değişiklikleri stash'e koy
git stash
# Terminal çıktısı:
# Saved working directory and index state WIP on feature/login: abc1234 feat: Add login form# 2. Çalışma alanı temiz — branch değiştirebilirsin
git status
# On branch feature/login
# nothing to commit, working tree clean
git checkout main
# ... hotfix yap ...
git checkout feature/login# 3. Stash'ten geri al
git stash pop
# On branch feature/login
# Changes not staged for commit:
# modified: src/auth.js
# Changes to be committed:
# new file: src/helper.jsStash Komutları Detaylı
# ═══════════════════════════════════════
# STASH OLUŞTURMA
# ═══════════════════════════════════════
# Basit stash (tracked ve staged dosyalar)
git stash
# Mesajlı stash (ne sakladığını hatırlamak için)
git stash push -m "Login formu yarım kaldı"
# Belirli dosyaları stash'le
git stash push -m "Sadece auth" src/auth.js src/middleware.js
# Untracked (yeni) dosyaları da dahil et
git stash -u
# veya
git stash --include-untracked
# .gitignore'da olan dosyaları da dahil et (nadiren kullanılır)
git stash -a
# veya
git stash --all
# Sadece staging area'yı stash'le (staged hariç unstaged kalsın)
git stash --keep-index
# Bu, "staged değişiklikleri test edip, unstaged'ları stash'le" için yararlı
# ═══════════════════════════════════════
# STASH LİSTELEME
# ═══════════════════════════════════════
git stash list
# stash@{0}: WIP on feature/login: abc1234 feat: Add login form
# stash@{1}: On main: def5678 Hotfix attempt
# stash@{2}: WIP on feature/search: ghi9012 Search WIP
# Stash içeriğini gör (ne değişmiş?)
git stash show
# src/auth.js | 15 +++++++++------
# src/helper.js | 8 ++++++++
# 2 files changed, 17 insertions(+), 6 deletions(-)
# Detaylı diff
git stash show -p
# veya
git stash show -p stash@{1}
# ═══════════════════════════════════════
# STASH GERİ ALMA
# ═══════════════════════════════════════
# Pop: Geri al VE stash'ten sil
git stash pop
# En son stash'i geri alır ve listeden siler
# Belirli bir stash'i pop et
git stash pop stash@{2}
# Apply: Geri al AMA stash'te kalsın
git stash apply
# Stash listeden silinmez — birden fazla branch'e uygulamak için
git stash apply stash@{1}
# ═══════════════════════════════════════
# STASH SİLME
# ═══════════════════════════════════════
# Belirli bir stash'i sil
git stash drop stash@{0}
# Tüm stash'leri sil
git stash clearpop vs apply
pop = apply + drop (geri al ve sil)
apply = sadece geri al (stash'te kalsın)
Ne zaman apply kullanırsın?
→ Aynı stash'i birden fazla branch'e uygulamak istiyorsan
→ "Geri aldım ama çalışıyor mu diye emin değilim" durumunda
(sorun olursa stash hâlâ orada)💡 İpucu:
git stash popsırasında conflict çıkarsa, stash otomatik olarak silinmez (drop yapılmaz). Conflict'i çözdükten sonra ellegit stash dropyapman gerekir.
Stash İleri Kullanım
Stash'ten Branch Oluşturma
Stash'teki değişiklikleri yeni bir branch olarak açmak istiyorsan:
git stash branch new-feature-branch stash@{0}
# 1. stash@{0} oluşturulduğu andaki commit'ten yeni branch açar
# 2. Stash'i uygular
# 3. Stash'i listeden silerBu, özellikle stash oluşturduğundan beri branch çok değiştiyse ve conflict çıkacaksa yararlıdır. Stash'in orijinal commit'inden yeni branch açarak conflict'i önler.
Patch Modunda Stash
Dosyanın sadece bir kısmını stash'lemek istiyorsan:
git stash push -p
# Her değişiklik bloğu için sorar:
# Stash this hunk [y,n,q,a,d,/,s,e,?]?
# y = evet, stash'le
# n = hayır, bırak
# s = daha küçük parçalara bölStash ile Geçici Temiz Test
# "Acaba bu bug benim değişikliklerimden mi kaynaklanıyor?"
# 1. Değişiklikleri geçici olarak sakla
git stash
# 2. Temiz halinde test et
npm test
# Testler geçiyor → Bug benim kodumda
# 3. Değişiklikleri geri al
git stash popGit Worktree — Paralel Çalışma Dizinleri
Analoji — İki Ayrı Çalışma Masası
Stash, masanı toparlayıp sonra geri açmak gibi. Ama ya iki ayrı masan olsa? Bir masada feature branch'inde çalışırsın, öbür masada hotfix branch'inde. İki masa aynı anda açık — birini toplamadan diğerine geçersin.
git worktree tam olarak bunu yapar: aynı repository'nin birden fazla çalışma dizinini aynı anda açık tutar.
my-project/ ← Ana worktree (feature/login branch'i)
├── .git/
├── src/
└── package.json
my-project-hotfix/ ← Ek worktree (hotfix branch'i)
├── src/
└── package.json
Her iki dizin aynı .git veritabanını paylaşır!Temel Kullanım
# Mevcut repo'da çalışıyorsun (feature branch)
cd ~/projects/my-project
git branch
# * feature/login
# main
# hotfix/payment
# Yeni bir worktree oluştur — farklı branch'te
git worktree add ../my-project-hotfix hotfix/payment
# Terminal çıktısı:
# Preparing worktree (checking out 'hotfix/payment')
# HEAD is now at abc1234 fix: Payment calculation# Şimdi iki ayrı dizinde iki ayrı branch:
cd ~/projects/my-project # feature/login
cd ~/projects/my-project-hotfix # hotfix/payment
# Her birinde bağımsız çalışabilirsin!Worktree Komutları
# Worktree'leri listele
git worktree list
# /home/user/projects/my-project abc1234 [feature/login]
# /home/user/projects/my-project-hotfix def5678 [hotfix/payment]
# Yeni branch oluşturarak worktree ekle
git worktree add ../my-project-review -b review/pr-47
# Worktree'yi sil (dizini sildikten sonra)
rm -rf ../my-project-hotfix
git worktree prune
# veya temiz kaldırma:
git worktree remove ../my-project-hotfixWorktree Kuralları
1. Her branch sadece bir worktree'de checkout edilebilir
❌ İki worktree'de aynı branch'i açamazsın
2. Ana worktree'yi (.git'in olduğu) silemezsin
3. Tüm worktree'ler aynı .git veritabanını paylaşır
→ Bir worktree'de commit, diğerinde görünür
→ Stash tüm worktree'ler arasında paylaşılırNe Zaman Worktree Kullanılır?
Stash kullan:
→ Kısa süreli context switch (5-10 dakikalık hotfix)
→ Tek bir branch yeterli
→ Basit değişiklikler
Worktree kullan:
→ Uzun süreli paralel çalışma
→ İki branch'i aynı anda açık tutmak istiyorsan
→ CI/CD pipeline testleri
→ Code review yaparken (reviewer branch'i ayrı dizinde)
→ Büyük projelerde npm install / build süreleri uzunsa
(her worktree'nin kendi node_modules'ü var)Worktree Pratik Senaryosu
# Senaryo: Feature branch'inde çalışıyorsun, acil PR review lazım
# 1. Review için yeni worktree
git worktree add ../project-review -b review/pr-52
cd ../project-review
# 2. PR branch'ini çek
git fetch origin
git checkout origin/feature/new-feature
# 3. Kodu incele, test et
npm install
npm test
# 4. Notlarını al, review yap
# ... GitHub'da review comment'lerini yaz ...
# 5. Review bitti, worktree'yi temizle
cd ../my-project
git worktree remove ../project-reviewStash İç Yapısı — Stash Aslında Ne?
Stash aslında gizli bir commit'tir. İki (veya üç) commit'ten oluşur:
Stash yapısı:
stash@{0}
├── commit (WIP on branch)
│ ├── parent 1 → HEAD'deki commit (hangi commit'teydin)
│ └── parent 2 → index commit (staging area durumu)
│ └── parent 3 → untracked commit (-u ile, varsa)# Stash'in commit olduğunu kanıtlama:
$ git stash
$ git stash list
stash@{0}: WIP on main: abc1234 feat: Son commit
# Stash aslında refs/stash altında tutulan bir ref
$ cat .git/refs/stash
def5678abc1234567890123456789abcdef012345
# Stash commit'inin detayı
$ git cat-file -p stash
tree abc123...
parent abc1234... # HEAD'deki commit
parent def5678... # Index (staging) durumu
author Tolgahan Kaya ...
WIP on main: abc1234 feat: Son commitBu, stash'in neden cherry-pick ve branch ile uyumlu çalıştığını açıklıyor — aslında commit zinciri.
Stash Automation — Git Alias'lar
Sık kullanılan stash komutlarını kısaltmak için alias'lar:
# Stash alias'ları
git config --global alias.ss "stash push -u -m"
# Kullanım: git ss "Login yarım kaldı"
git config --global alias.sl "stash list"
# Kullanım: git sl
git config --global alias.sp "stash pop"
# Kullanım: git sp
git config --global alias.sd "stash show -p"
# Kullanım: git sd stash@{0}
# Pratik kullanım:
$ git ss "Dashboard chart component WIP"
$ git sl
stash@{0}: On feature/dashboard: Dashboard chart component WIP
$ git sp # İşin bitince geri alStash ile İlgili İpuçları
Stash İçinden Belirli Dosyayı Çıkarma
Stash'in tamamını pop etmek istemiyorsun, sadece belirli bir dosyayı çıkarmak istiyorsun:
# Stash'teki belirli dosyayı working directory'ye çıkar
$ git checkout stash@{0} -- src/auth.js
# Sadece auth.js geri geldi, diğer dosyalar stash'te kaldı
# veya git restore ile (Git 2.23+)
$ git restore --source=stash@{0} -- src/auth.jsBirden Fazla Stash ile Çalışma Stratejisi
# Her stash'e anlamlı mesaj ver
$ git stash push -m "Auth: OAuth2 entegrasyonu yarım"
$ git stash push -m "UI: Dashboard redesign devam ediyor"
$ git stash push -m "API: Rate limiter test edilmedi"
# Listele — hangisini istiyorsun?
$ git stash list
stash@{0}: On feature/api: API: Rate limiter test edilmedi
stash@{1}: On feature/ui: UI: Dashboard redesign devam ediyor
stash@{2}: On feature/auth: Auth: OAuth2 entegrasyonu yarım
# İstediğini seç
$ git stash pop stash@{1}
# Dashboard redesign geri geldiStash'lerin Tarihi Kontrolü
# Stash ne zaman oluşturuldu?
$ git stash list --date=relative
stash@{0}: 2 hours ago: On main: WIP login
stash@{1}: 3 days ago: On feature: Dashboard yarım
# Stash'lerin istatistikleri
$ git stash show --stat stash@{0}
src/auth.js | 25 ++++++++++++++++--------
src/login.js | 12 ++++++++++++
2 files changed, 29 insertions(+), 8 deletions(-)Stash vs Worktree — Karşılaştırma
┌──────────────────┬─────────────────────┬─────────────────────┐
│ Özellik │ git stash │ git worktree │
├──────────────────┼─────────────────────┼─────────────────────┤
│ Amaç │ Geçici saklama │ Paralel çalışma │
│ Süre │ Kısa (dakikalar) │ Uzun (saatler/günler)│
│ Disk alanı │ Minimal │ Ek (working dir) │
│ npm install │ Gereksiz │ Gerekebilir │
│ Paralel edit │ Hayır (tek masa) │ Evet (iki masa) │
│ Karmaşıklık │ Düşük │ Orta │
│ Build cache │ Paylaşılır │ Ayrı │
│ IDE desteği │ Tam │ Her dizin ayrı pencere│
└──────────────────┴─────────────────────┴─────────────────────┘Stash ile İlgili Yaygın Hatalar
1. Stash Unutmak
# ❌ 3 ay önce stash yaptın ve unuttun
git stash list
# stash@{0}: WIP on feature/old: abc1234 something from 3 months ago
# Artık ne olduğunu hatırlamıyorsun bile...
# ✅ Stash'e her zaman mesaj ekle:
git stash push -m "Login: form validation yarım, API bağlantısı yapılmadı"
# ✅ Stash'leri düzenli temizle2. Yanlış Stash'i Pop Etmek
# ❌ Yanlış stash'i pop ettin
git stash pop stash@{2} # Yanlış!
# ✅ Önce içeriğine bak:
git stash show -p stash@{2}
# Doğru stash olduğundan emin ol, sonra pop et3. Stash Pop Conflict
# Pop sırasında conflict çıktı
git stash pop
# CONFLICT in src/auth.js
# Conflict'i çöz
git add src/auth.js
# Dikkat: Stash hâlâ listede! Pop başarısız olduğunda silinmez.
git stash drop # Manuel sil4. Untracked Dosyaları Stash'lememek
# ❌ Yeni bir dosya oluşturdun ama stash'lenmiyor:
git stash
# Yeni dosya working directory'de kaldı!
# ✅ -u ile untracked dosyaları da dahil et:
git stash -u
# veya
git stash --include-untrackedPratik: Acil Hotfix Senaryosu
İki yaklaşımı da uygulayalım:
Yöntem 1: Stash ile
# Feature branch'inde çalışıyorsun
git status
# modified: src/dashboard.js
# modified: src/components/Chart.js
# new file: src/utils/analytics.js
# 1. Stash'le
git stash push -u -m "Dashboard analytics: chart component yarım"
# 2. Hotfix branch'ine geç
git checkout main
git checkout -b hotfix/critical-bug
# 3. Bug'ı düzelt
echo "// Fixed!" >> src/payment.js
git add .
git commit -m "fix: Correct payment rounding error"
# 4. Main'e merge et
git checkout main
git merge hotfix/critical-bug
git push origin main
git branch -d hotfix/critical-bug
# 5. Feature branch'ine dön ve stash'i geri al
git checkout feature/dashboard
git stash pop
# Kaldığın yerden devam! ✅Yöntem 2: Worktree ile
# Feature branch'inde çalışıyorsun — hiçbir şeye dokunma!
# 1. Hotfix için yeni worktree oluştur
git worktree add ../project-hotfix -b hotfix/critical-bug main
# 2. Hotfix dizinine git
cd ../project-hotfix
# 3. Bug'ı düzelt
echo "// Fixed!" >> src/payment.js
git add .
git commit -m "fix: Correct payment rounding error"
git push origin hotfix/critical-bug
# 4. Main'e merge (veya PR ile)
git checkout main
git merge hotfix/critical-bug
git push origin main
# 5. Hotfix worktree'yi temizle
cd ../my-project
git worktree remove ../project-hotfix
git branch -d hotfix/critical-bug
# Feature branch'inde hiç bir şey bozulmadı! ✅Özet
Bu derste yarım kalan işlerle başa çıkmanın iki güçlü yolunu öğrendik:
Git stash, çalışma alanındaki değişiklikleri geçici olarak saklar — branch değiştirip geri döndüğünde kaldığın yerden devam edersin.
push -mile mesaj ekle,-uile untracked dosyaları da dahil et`pop` vs `apply` — pop geri alır ve siler, apply geri alır ama stash'te bırakır. Conflict çıkınca pop sessizce drop yapmaz, manuel silmen gerekir
`git stash branch` ile stash'i doğrudan yeni bir branch'e çevirebilirsin — conflict riski olmadan temiz bir başlangıç
Git worktree, aynı repo'nun birden fazla çalışma dizinini açmanı sağlar — stash'e gerek kalmadan iki branch'te paralel çalışırsın
Stash kısa süreli (dakikalar) geçişler için, worktree uzun süreli (saatler/günler) paralel çalışma için idealdir
Her zaman stash'e açıklayıcı mesaj ekle ve stash listeni düzenli temizle
💡 İpucu: Stash ve worktree, context switching (görev değiştirme) sorununu çözen iki farklı araçtır. Hangisini kullanacağına karar verirken şunu sor: "Bu kesinti 5 dakika mı sürecek, yoksa 5 saat mi?" 5 dakikaysa stash, 5 saatten fazlaysa worktree kullan.
Bir sonraki derste projenin dönüm noktalarını işaretlemenin yolunu göreceğiz: Tag ve Release.
AI Asistan
Sorularını yanıtlamaya hazır