Git
Chapters ▾ 2nd Edition

7.3 Git Tools - Saklama ve Silme

Saklama ve Silme

Çoğu zaman, projenizin bir kısmında çalışırken, işler karışmış olabilir ve bir süre başka bir şey üzerinde çalışmak için dal değiştirmek isteyebilirsiniz. Ancak sorun şudur ki, daha sonra tamamlamak için geri döneceğiniz için yarım kalmış bir işi katkılamak istemezsiniz. Bu sorunun çözümü, git stash komutundadır.

stash komutu, çalışma dizininizin ham durumunu - yani, değiştirilmiş izlenen dosyalarınızı ve izlem değişikliklerinizi - alır ve bunu her zaman yeniden (hatta farklı bir dalda bile) uygulayabileceğiniz tamamlanmamış değişiklikler yığınına olarak kaydeder.

Örnek 15. git stash push'a geçiş

Ekim 2017’nin sonlarına doğru, Git posta listesinde git stash save komutunun kaldırılıp, alternatif olarak yerine zaten mevcut olan git stash push komutunun kullanılması üzerine kapsamlı bir tartışma yapılmıştır. Bunun ana nedeni, git stash push komutunun, git stash save tarafından desteklenmeyen pathspecs gizleme seçeneğini sunmasıdır.

git stash save yakın zamanda ortadan kalkmayacak, bu yüzden birdenbire kaybolacağından endişelenmeyin. Ancak yeni işlevsellik için push alternatifine geçmeye başlamak isteyebilirsiniz.

Çalışmanızı Saklama

Saklamayı (stashing) göstermek için projenize girip birkaç dosyada çalışmaya başlayacak ve belki de değişikliklerden birini sahneye koyacaksınız. git status komutunu çalıştırırsanız, ham durumunuzu görebilirsiniz:

$ git status
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   index.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   lib/simplegit.rb

Şimdi dal değiştirmek istiyorsunuz, ancak üzerinde çalıştığınız şeyleri henüz kaydetmek istemiyorsunuz, bu yüzden değişiklikleri saklayacaksınız. Yığınınıza yeni bir saklama eklemek için git stash veya git stash push komutunu çalıştırın:

$ git stash
Saved working directory and index state \
  "WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")

Şimdi çalışma dizininizin temizlendiğini görebilirsiniz:

$ git status
# On branch master
nothing to commit, working directory clean

Bu noktada, dal değiştirebilir ve başka bir yerde çalışabilirsiniz; değişiklikleriniz yığınınızda saklanmaktadır. Hangi saklamaları depoladığınızı görmek için git stash list komutunu kullanabilirsiniz:

$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log

Daha önce zaten iki saklama yapılmış olduğu için, şu an üç farklı saklanmış çalışmaya erişiminiz var. Yeni sakladığınızı tekrar uygulamak için orijinal saklama komutunun yardım çıktısında gösterilen komutu çalıştırabilirsiniz: git stash apply Eski saklamalardan birini uygulamak isterseniz, onu şu şekilde adlandırarak belirtebilirsiniz: git stash apply stash@{2}. Bir saklama belirtmezseniz, Git en son saklamayı varsayarak, doğrudan onu uygular:

$ git stash apply
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   index.html
	modified:   lib/simplegit.rb

no changes added to commit (use "git add" and/or "git commit -a")

Görebileceğiniz gibi, Git, saklamayı kaydettiğinizde geri aldığınız dosyaları yeniden getirdi. Saklamayı başlattığınızda temiz bir çalışma diziniz vardı ve onu kaydettiğiniz aynı dalda uygulamaya çalıştınız. Temiz bir çalışma dizinine sahip olmak ve onu aynı dala uygulamak, bir saklama işlemini başarıyla uygulamak için gerekli değildir. Bir saklamayı bir dalda kaydedip daha sonra başka bir dala geçebilir ve değişiklikleri yeniden uygulamayı deneyebilirsiniz. Ayrıca, bir saklamayı uygularken çalışma dizinizde değiştirilmiş ve katkılanmamış dosyalara sahip olabilirsiniz - Git, bir şeylerin artık temiz bir şekilde uygulanmadığında birleştirme çakışmaları verir.

Dosyalarınızdaki değişiklikler tekrar uygulandı, ancak önce izleme aldığınız dosya yeniden izlemlenmedi. Bunu yapmak için, git stash apply komutunu --index seçeneği ile çalıştırmalısınız; bu seçenek komuta, izlemlediğiniz değişiklikleri tekrar uygulamayı denemesini söyler. Öncekini yapmak yerine, bunu çalıştırsaydınız, orijinal konumunuza geri dönecektiniz:

$ git stash apply --index
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   index.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   lib/simplegit.rb

apply (uygula) seçeneği sadece saklanmış çalışmayı uygulamaya çalışır ama onu yığınınızda tutmaya devam edersiniz. Onu kaldırmak için, kaldırmak istediğiniz saklamanın adıyla git stash drop komutunu çalıştırabilirsiniz:

$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)

Ayrıca, saklamayı uygulamak ve ardından hemen yığınınızdan kaldırmak için git stash pop komutunu da çalıştırabilirsiniz.

Yaratıcı Saklama

Faydalı bulabileceğiniz bir kaç farklı saklama seçeneği daha bulunmaktadır. Oldukça popüler olan ilk seçenek: git stash komutuna --keep-index seçeneği eklemektir. Bu, Git’e oluşturulan saklamaya tüm izlemlenmiş içeriği dahil etmenin yanı sıra, aynı anda onları izlem içinde bırakmasını da söyler.

$ git status -s
M  index.html
 M lib/simplegit.rb

$ git stash --keep-index
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file

$ git status -s
M  index.html

"Saklama" ile yapmak isteyebileceğiniz başka yaygın bir şey, izlenen dosyaların yanı sıra izlenmeyen dosyaları da saklamaktır. Varsayılan olarak, git stash, yalnızca değiştirilmiş ve izlemlenmiş (takipte olan - tracked) dosyaları saklar. --include-untracked veya -u 'yu belirtirseniz, Git, oluşturulan saklamaya izlenmeyen dosyaları da dahil eder. Ancak, saklamaya izlenmeyen dosyaları dahil etmek, yoksayılan dosyaları da doğrudan dahil etmez; yoksayılan dosyaları da dahil etmek için --all (veya sadece -a) kullanın.

$ git status -s
M  index.html
 M lib/simplegit.rb
?? new-file.txt

$ git stash -u
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file

$ git status -s
$

Son olarak, --patch bayrağını belirtirseniz, Git değiştirilmiş her şeyi saklamaz ancak bunun yerine size etkileşimli olarak hangi değişiklikleri saklamak istediğinizi ve hangilerini çalışma dizinizde tutmak istediğinizi sorar.

$ git stash --patch
diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index 66d332e..8bb5674 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -16,6 +16,10 @@ class SimpleGit
         return `#{git_cmd} 2>&1`.chomp
       end
     end
+
+    def show(treeish = 'master')
+      command("git show #{treeish}")
+    end

 end
 test
Stash this hunk [y,n,q,a,d,/,e,?]? y

Saved working directory and index state WIP on master: 1b65b17 added the index file

Bir "Saklama"dan Dal Oluşturma

Eğer bir çalışmanızı saklarsanız, bir süre beklerseniz ve sonra çalışmaya devam etmek için sakladığınız işin olduğu dala geri dönerseniz, çalışmanızı tekrar uygulamakta bir problem yaşayabilirsiniz. Eğer uygulama işlemi daha sonra değiştirdiğiniz bir dosyayı değiştirmeye çalışırsa, birleştirme çakışması alırsınız ve bunu çözmeniz gerekir. Saklanmış değişiklikleri tekrar test etmek için daha kolay bir yol isterseniz, git stash branch <yeni dal adı> komutunu çalıştırabilirsiniz. Bu komut, seçtiğiniz dal adıyla sizin için yeni bir dal oluşturur, çalışmanızı saklarken üzerinde bulunduğunuz katkıya gider, çalışmanızı oraya yeniden uygular ve başarıyla uygulanırsa saklamayı kaldırır.

$ git stash branch testchanges
M	index.html
M	lib/simplegit.rb
Switched to a new branch 'testchanges'
On branch testchanges
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   index.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   lib/simplegit.rb

Dropped refs/stash@{0} (29d385a81d163dfd45a452a2ce816487a6b8b014)

Bu, saklanmış işleri kolayca kurtarmak ve bunu yeni bir dalda uygulamak için güzel bir kısayoldur.

Çalışma Dizininizi Temizlemek

Son olarak, çalışma dizininizdeki saklamak istemediğiniz bazı iş veya dosyalardan kurtulmak isteyebilirsiniz; işte bu durumda git clean komutu devreye girer.

Çalışma dizinini temizlemenin yaygın nedenleri, birleştirmeler veya harici araçlar tarafından oluşturulan gereksiz dosyaları kaldırmak veya temiz bir derleme yapabilmek için derleme kalıntılarını kaldırmak istemeniz olabilir.

Bu komutu kullanırken çok dikkatli olmalısınız, çünkü bu komut çalışma dizininizdeki takip edilmeyen dosyaları kaldırmak için tasarlanmıştır. Fikrinizi değiştirirseniz, genellikle bu içeriği kurtarmanın bir yolu yoktur. Daha güvenli bir seçenek: her şeyi kaldırıp, ama aynı anda bir saklama içine kaydetmek için git stash --all komutunu çalıştırmaktır.

Gereksiz dosyaları kaldırmak veya çalışma dizetinizi temizlemek istediğinizi varsayarsak, bunu git clean ile yapabilirsiniz. Çalışma dizininizdeki tüm izlenmeyen dosyaları kaldırmak için git clean -f -d komutunu çalıştırabilirsiniz. Bu komutla boşalan tüm dosya veya alt dizinler de kaldırılır. -f, force (zorlamak, güç kullanarak yaptırmak) anlamına gelir ve Git yapılandırma değişkeni clean.requireForce açıkça "false" (yanlış) olarak ayarlanmamışsa gerekli bir seçenektir.

Eğer bu komutun ne yapacağını görmek isterseniz, komutu --dry-run (veya -n) seçeneği ile çalıştırabilirsiniz; bu da deneme çalıştırması yap ve bana neyi kaldıracağını söyle anlamına gelir.

$ git clean -d -n
Would remove test.o
Would remove tmp/

Varsayılan olarak, git clean komutu sadece yoksayılmayan (not ignored) ve takip edilmeyen (untracked) dosyaları siler. .gitignore veya diğer ignore dosyalarında kendiylhe eşleşen bir kalıp varsa bu dosyalar silinmez. Örneğin, tamamen temiz bir derleme yapmak için oluşturulan tüm .o dosyalarını kaldırmak isterseniz, clean komutuna -x bayrağını ekleyebilirsiniz.

$ git status -s
 M lib/simplegit.rb
?? build.TMP
?? tmp/

$ git clean -n -d
Would remove build.TMP
Would remove tmp/

$ git clean -n -d -x
Would remove build.TMP
Would remove test.o
Would remove tmp/

git clean komutunun ne yapacağını bilmiyorsanız, değişiklik yapmadan önce -n bayrağı ile çalıştırarak kontrol edin. Sonra -n'yi bir -f ile değiştirip, komutu gerçekten çalıştırabilirsiniz. Süreci dikkatli bir şekilde yapmanın başka bir yolu da -i veya interactive (etkileşimli) seçeneği ile çalıştırmaktır.

Bu, temizleme komutunu etkileşimli modda çalıştırır.

$ git clean -x -i
Would remove the following items:
  build.TMP  test.o
*** Commands ***
    1: clean (temizle)          2: filter by pattern (bir desene göre ayıkla)          3: select by numbers (sıra numarasıyla seç)          4: ask each (her birini tek tek sor)          5: quit (çık)          6: help (yardım iste)
What now>

Bu şekilde her dosyayı tek tek inceleyebilir veya silme için desenler belirleyebilirsiniz.

Bazı garip durumlarda, Git’ten çalışma dizininizi temizlemesini istemek için ekstra yetkili olmanız gerekebilir. Mesela alt modül olarak başka Git repolarını kopyaladığınız bir çalışma dizininin altındaysanız, git clean -fd komutu bile bu dizinleri silmeyi reddedecektir. Bu gibi durumlarda, vurgu yapmak için ikinci bir -f seçeneği eklemeniz gerekmektedir.

scroll-to-top