Git stash: “Kirli çalışan bir ağaca uygulanamaz, lütfen değişikliklerinizi yapın”


133

Daha önce sakladığım değişiklikleri uygulamaya çalışıyorum git stash popve mesajı alıyorum:

Cannot apply to a dirty working tree, please stage your changes

Bununla nasıl başa çıkacağınıza dair herhangi bir öneriniz var mı?

Yanıtlar:


196

Kirli bir çalışma kopyasına saklanmış değişiklikler uygulamak zorunda kaldığımda, örneğin saklamak için birden fazla changeet pop, aşağıdakileri kullanıyorum:

$ git stash show -p | git apply -3 && git stash drop

Temelde

  1. yama oluşturur
  2. Uygula komutuna yönlendirir
  3. herhangi bir ihtilaf varsa, bunların 3 yönlü birleştirme yoluyla çözülmesi gerekir
  4. Apply (veya birleştirme) başarılı olursa, sadece uygulanan stash öğesini bırakır ...

Neden yukarıdaki tek astarlı gibi davranması gereken bir -f(kuvvet) seçeneği olmadığını merak ediyorum git stash pop.

Bu arada, bu tek astarı git takma adı olarak eklemek isteyebilirsiniz:

$ git config --global --replace-all alias.unstash \
   '!git stash show -p | git apply -3 && git stash drop'
$ git unstash

@SamHasler, -3çakışmaları doğrudan 3 yönlü birleştirme yoluyla çözmeyi sağlayan parametreye işaret ettiği için .


git stash show -p | git applyFarklı mı git stash apply?
Faktör Mystic

1
Jo Factor, git stash applykirli çalışan bir kopyanız varsa, saklanan değişiklikleri uygulamaz. Yani bir git stash show -p | git applyçeşit zorlanmış zulası uygularken görebilirsiniz .
muhqu

1
yardımcı değil Ama yardım: git HEAD'i sıfırlayın ve bundan sonra değişiklikleri kaldırın.
Roger Alien

4
Dosyalardan biri için "hata: yama başarısız oldu ... yama geçerli değil" iletisi alıyorum. Keşke birleşme çatışması verseydi.
Aleksandr Dubinsky

1
Bu çözüm benim için çalışmadı, error: <file> does not match indexdeğiştirilen her dosya için başarısız oldu . Ancak, başka bir çözüm işe yaradı.
silvenon

57

Bu şekilde yaparım:

git add -A
git stash apply

ve sonra (isteğe bağlı olarak):

git reset

2
1! Bu, yamalar oluşturmayı veya taahhütleri değiştirmeyi içeren diğer çözümlerden daha basittir ve değişikliklerin doğru bir şekilde birleştirildiğinden emin olana kadar yerel değişikliklerinizi uygulanan saklı değişikliklerden güvenli bir şekilde izole tutar.
peterflynn

Hata alıyorum "... zaten var, ödeme yok ... İzlenmeyen dosyalar saklanandan geri yüklenemedi"
Aleksandr Dubinsky

2
Kullandım git add -u, -Aizlenmeyen dosyalar eklememesi dışında.
Brad Cupit

9

Bunu, bir yama dosyası olarak istediğiniz zulayı dışa aktararak ve manuel olarak uygulayarak mevcut değişikliklerinizi saklamak zorunda kalmadan yapabilirsiniz.

Örneğin, kirli bir ağaca stash @ {0} uygulamak istediğinizi varsayalım:

  1. Stash @ {0} bir düzeltme eki olarak dışa aktarın:

    git stash gösterisi -p stash @ {0}> Stash0.patch

  2. Değişiklikleri manuel olarak uygulayın:

    git Uygula Stash0.patch

İkinci adım başarısız olursa, herhangi bir hatayı düzeltmek için Stash0.patch dosyasını düzenlemeniz ve ardından git Apply komutunu tekrar denemeniz gerekir.


Bu, bir direkte yeniden düzenleme yaptım (kaldırıldı ve adıyla bir sembolik bağlantı oluşturduğum) için pratik ve uygulanabilir. Git, çalışan kopya değişikliklerimin ne olduğunu söyleyemedi.
yclian

1
Bu harika çalıştı. Çalışma ağacımın temiz olduğundan emin olmamıza rağmen bir zulası uygulayamadım.
Shiki

Evet, bir ikili dosyayla ilgili satırları kaldırmak zorunda kaldım.
Dorian

8

Çalışma dizininizi git reset ile temizleyin, değişiklikleri uygulayın veya mevcut değişiklikleri saklamak istiyorsanız şunları deneyin:

$ git stash save "mevcut değişikliklerin açıklaması"
$ git stash pop stash @ {1}

Bu, geçerli değişiklikleri saklayacak ve daha sonra yığın yığınından ikinci saklamayı açacaktır.


5
Ama bu adam iki zuvanın uygulanmasını istiyor!
Elazar Leibovich

@Elazar Soruyu okuyorsunuz. OP sadece önceki bir zuvanayı uygulamak istiyor. Mevcut değişikliklerin saklanacağından eminseniz, çözüm tekrarlanabilir: pop, kesin, tekrarlayın.
William Pursell

Bence ikisini de sınırsız istiyor. Ama sonra tekrar, iki kez taahhüt edebilir ve tek bir taahhütte ezebilir.
Elazar Leibovich

Hata alıyorum "... zaten var, ödeme yok ... İzlenmeyen dosyalar saklanandan geri yüklenemedi"
Aleksandr Dubinsky

6

Mathias'ın çözümü kesinlikle git stash pop --force'a en yakın olanıdır (ve gerçekten Git devs, şimdi bu seçeneği alalım!)

Ancak, aynı şeyi yalnızca git komutlarını kullanarak yapmak istiyorsanız, şunları yapabilirsiniz:

  1. git commit -a -m "Fixme"
  2. git stash pop
  3. git commit -a --amend
  4. git reset KAFA ~

Başka bir deyişle, mevcut değişikliklerinizi taahhüt edin (ki asla itmeyeceğiz). Artık çalışma alanınız temiz, zulanızı patlatın. Şimdi, daha önceki taahhüdünüzde bir değişiklik olarak saklı değişiklikleri yapın. Şimdi yaptığınız her iki değişiklik kümesini tek bir işlemde ("Fixme") birleştirdiğinizde; sadece sıfırlayın (--soft NOT --hard böylece hiçbir şey gerçekten kaybolmaz) ödeme "o taahhüt önce bir" ve şimdi tamamen taahhüt edilmemiş, her iki değişiklik kümesi var.

** DÜZENLE * *

Aslında bunun daha da kolay olduğunu fark ettim; 3. adımı tamamen atlayabilirsiniz, bu yüzden ...

  1. git commit -a -m "Fixme"
  2. git stash pop
  3. git reset KAFA ~

(Geçerli değişiklikleri yap, saklı değişiklikleri kapat, her iki değişiklik kümesini de taahhüt edilmemiş bir durumda bir araya getirme taahhüdünü sıfırla.)


4

Bugün yaptığım gibi kendinizi bu durumda bulursanız, bu cevapların hiçbiri işe yaramaz. Kaç tane git reset --hardyaptığımdan bağımsız olarak , beni hiçbir yere götürmedi. Cevabım (hiçbir şekilde resmi değil):

  1. Stash'ın karma kullanımını anlayın git reflog --all
  2. Bu karmayı ilgilendiğiniz şubeyle birleştirin

1
Çok teşekkürler Yar. Git'in şu anki yerel repoma garip bir şekilde nasıl davrandığı beni hayal kırıklığına uğrattı.
yclian

4

Mathias Leppich'in harika çalışma çözümünü de buldum, bu yüzden global .gitconfig'ime bir takma ad ekledim

[alias]
        apply-stash-to-dirty-working-tree = !git stash show -p | git apply && git stash drop

Şimdi yazabilirim

git apply-stash-to-dirty-working-tree

bu benim için harika çalışıyor.

(Kilometreniz bu uzun takma ad adına göre değişebilir. Ancak bash tamamlamasıyla geldiğinde bir doz ayrıntı vermeyi seviyorum.)


3

Yaptığınız git adddeğişiklikleri yapmak için bir "kirli" ağaca bir zulası uygulayabilir ve böylece ağacı temizleyebilirsiniz. Sonra git stash popsaklı değişiklikleri yapabilir ve uygulayabilirsiniz, sorun değil.


2

Değiştirilmiş, ancak kaydedilmemiş dosyalarınız var. Ya:

git reset --hard HEAD (to bring everything back to HEAD)

veya değişikliklerinizi kaydetmek istiyorsanız:

git checkout -b new_branch
git add ...
git commit
git checkout -b old_branch
git stash pop

1
@MikeCooper - Sanırım taahhüt etmeden önce eklemek istediğiniz her şeyi eklemek istiyordu.
sscirrus

0

Ben de aynı sorunu vardı ama git sıfır değiştirilmiş dosyaları vardı. Ortaya çıkan bir index.lock dosyam olduğu anlaşılıyor. Silinmesi sorunu çözdü.


0

Bunların çoğunu çalıştıramadım; bir nedenle her zaman bir dosyada yerel değişikliklerim olduğunu düşünüyor. Zımba uygulayamam, yamalar uygulanmaz checkoutve reset --hardbaşarısız olur. Sonunda işe yarayan, saklamayı bir şube olarak kaydetmek git stash branch tempbranchnameve daha sonra normal bir şube birleştirmesi yapmaktı: git checkout masterve git merge tempbranchname. Http://git-scm.com/book/en/Git-Tools-Stashing adresinden :

Depolanmış değişiklikleri tekrar test etmenin daha kolay bir yolunu istiyorsanız, sizin için yeni bir dal oluşturan git çalışmasını şubeyi çalıştırabilir, çalışmanızı sakladığınız sırada taahhüdünüzü kontrol edebilir, çalışmanızı orada yeniden uygulayabilir ve ardından bırakabilirsiniz. başarıyla uygulanırsa saklamak

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.