Git ile değişen birden fazla dosyadan yalnızca bir tanesi saklansın mı?


3069

Şubemdeki birden çok değiştirilmiş dosyadan yalnızca birini nasıl saklayabilirim?


109
@ Bukzor'un kabul edilen cevabının sorulduğu gibi soruya doğru bir cevap olduğunu düşünmüyorum. git stash --keep-indexdizini tutar, ancak her şeyi dizinde saklar - hem dizinde hem de dışında.
Raman

@Antonio Bana göre, ödülün aslında ayrı bir soru olmalı, çünkü orijinal sorunun özellikle TortoiseGit ile ilgisi yok.
JesusFreke

1
@JesusFreke Evet, sonuç 50 temsilcisi kaçmış olabilir :) Bu sadece "kısmi stash tortoisegit" aramaya çalışırsanız yönlendirme soru budur. Tortoisegit burada popüler bir konu gibi görünmüyor stackoverflow.com/questions/tagged/tortoisegit
Antonio

7
>>>>>>>>> git diff -- *filename* > ~/patchdaha git checkout -- *filename*sonra yamayı daha sonra tekrar uygulayabilirsinizgit apply ~/patch
neaumusic

36
Aşağıdaki mevcut cevapların çoğu eski. Git 2.13'ten (Q2 2017) beri desteklenmektedir git stash push [--] [<pathspec>...].
Ohad Schneider

Yanıtlar:


1372

Feragatname : Aşağıdaki cevap git 2.13'ten önce git içindir. Git 2.13 ve üzeri için aşağıdan başka bir cevaba göz atın .


Uyarı

Yorumlarda belirtildiği gibi, bu her şeyi hem sahnelendi hem de dizginsiz olarak saklanır. --Keep-endeksi, stash yapıldıktan sonra dizini yalnız bırakır. Bu, daha sonra zulayı patlattığınızda birleştirme çakışmalarına neden olabilir.


Bu, daha önce eklemediğiniz her şeyi saklar. Sadece git addsaklamak istediğiniz şeyler, sonra çalıştırın.

git stash --keep-index

Örneğin, eski bir taahhüdü birden fazla değişiklik kümesine bölmek istiyorsanız, bu yordamı kullanabilirsiniz:

  1. git rebase -i <last good commit>
  2. Bazı değişiklikleri işaretleyin edit.
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. İşleri gerektiği gibi düzeltin. git addHerhangi bir değişikliği unutmayın .
  7. git commit
  8. git stash pop
  9. Gerektiği gibi # 5'ten itibaren tekrarlayın.
  10. git rebase --continue

47
Bu yaklaşımı çok daha basit buluyorum: stackoverflow.com/a/5506483/457268
k0pernikus

561
Bunun neden değerlendirildiğinden emin değilim. Herkesin benden farklı bir beklentisi olmalı. Orijinal yayın "taahhüt edilmemiş değişikliklerin sadece bir kısmını nasıl saklayabilirim?" Sorusunu soruyor. Kullandığımda git stash save -k, evet indeks (yeşil giriş git stat) korunur, ancak tüm değişiklik kümesi (hem yeşil hem de kırmızı) saklanır . Bu OP'nin "sadece bazı değişiklikleri saklamak" talebini ihlal eder. Sadece kırmızıdan bazılarını saklamak istiyorum (gelecekteki kullanım için).
Pistos

70
@Pistos tarafından sorulan sorunun cevabıyla daha fazla ilgileniyorsanız (olduğu gibi), o zaman buraya bakın: stackoverflow.com/questions/5506339/…
Raman

27
@Raman: Mükemmel! git stash -ptam olarak aradığım şeydi. Bu anahtarın henüz yeni eklenmiş olup olmadığını merak ediyorum.
Pistos

14
UYARI: git stash --keep-indexkırık. Daha fazla değişiklik yaparsanız, daha sonra git stash popbirleştirme çakışmaları elde edersiniz, çünkü stash sadece tutmadıklarınızı değil, değiştirdiğiniz dosyaları içerir. Örneğin: A ve B dosyalarını değiştiriyorum, sonra B saklıyor, çünkü A'daki değişiklikleri test etmek istiyorum; Daha sonra düzelttiğim A ile ilgili bir sorun buluyorum; A taahhüt ediyorum; Artık untash yapamıyorum çünkü A'nın eski bir sürümü, bir birleşme çatışmasına neden olan iyi bir nedenden ötürü saklanıyor. Uygulamada A ve B birçok dosya, hatta ikili görüntüler veya başka bir şey olabilir, bu yüzden temelde B'den
vazgeçip

3015

Ayrıca kullanabilirsiniz git stash save -p "my commit message". Bu şekilde, saklamak için hangi iri parçaların ekleneceğini seçebilirsiniz, tüm dosyalar da seçilebilir.

Her bir iri parça için birkaç işlem yapmanız istenir:

   y - stash this hunk
   n - do not stash this hunk
   q - quit; do not stash this hunk or any of the remaining ones
   a - stash this hunk and all later hunks in the file
   d - do not stash this hunk or any of the later hunks in the file
   g - select a hunk to go to
   / - search for a hunk matching the given regex
   j - leave this hunk undecided, see next undecided hunk
   J - leave this hunk undecided, see next hunk
   k - leave this hunk undecided, see previous undecided hunk
   K - leave this hunk undecided, see previous hunk
   s - split the current hunk into smaller hunks
   e - manually edit the current hunk
   ? - print help

5
Değildi. Yaklaşık 7 yıl sonra Darcs'tan ödünç alındı.
nomen

6
Ben bir TortoiseGit bağımlısıyım. Ancak TortoiseGit desteklemez stash -p. Bu yanıtı verdim çünkü en interaktif / kullanıcı dostu olmaya devam ediyor.
Antonio

27
şunları eklemek isteyebilirsiniz git stash save -p my stash message:; argumenst'in sırası çok sezgisel olmadığından ...
Chris Maes

15
Bu ve arasında git log -p, -pbayrak "istediğim havalı şeyi yap ama nasıl ifade edeceğini bilmiyorum" anlamına gelmelidir.
Kyle Strand

2
neden bu büyük cevap 12. konumda? sonuçta bu 0, +1, +2 cevap ??????
DenisFLASH

548

Git temelde tüm bir depo içeriğini ve dizini (ve bir veya birkaç dosyayı değil) yönetmekle ilgili olduğundan git stash, şaşırtıcı bir şekilde,tüm çalışma diziniyle.

Aslında, Git 2.13'ten (Q2 2017) beri, dosyaları ayrı ayrı saklayabilirsiniz git stash push:

git stash push [--] [<pathspec>...]

Ne zaman pathspec'verilir git stash push', yeni zulası sadece Bkz "pathspec eşleşen dosyalar için modifiye durumlarını kaydeder Stash özel dosyalara değiştirir daha".

Basitleştirilmiş örnek:

 git stash push path/to/file

Bu özelliğin test durumu birkaç seçenek daha gösterir:

test_expect_success 'stash with multiple pathspec arguments' '
    >foo &&
    >bar &&
    >extra &&
    git add foo bar extra &&

    git stash push -- foo bar &&   

    test_path_is_missing bar &&
    test_path_is_missing foo &&
    test_path_is_file extra &&

    git stash pop &&
    test_path_is_file foo &&
    test_path_is_file bar &&
    test_path_is_file extra

Orijinal cevap (aşağıda, Haziran 2010) saklamak istediğinizi manuel olarak seçmekti.

Casebash yorum:

Bu ( stash --patchorijinal çözüm) güzel, ama çoğu zaman birçok dosyayı değiştirdim, bu yüzden yama kullanmak sinir bozucu

bukzor 'ın cevabı (upvoted, Kasım 2011) dayalı, daha pratik bir çözüm önerir
git add+git stash --keep-index .
Gidip resmi yanıtı olması gereken cevabını (benim değil) görün ve onaylayın.

Bu seçenek hakkında, chhh yorumlarda alternatif bir iş akışına dikkat çeker :

git reset --softnet aşamalandırmayı geri almak için böyle bir saklamanın ardından " " yapmalısınız :
Orijinal duruma ulaşmak için - bu net bir aşamalandırma alanıdır ve yalnızca bazı aşamalı olmayan değişikliklerle, almak için dizini yumuşak bir şekilde sıfırlayabilir (olmadan sizin gibi bir şey - bukzor - yaptı)


(Orijinal cevap Haziran 2010: manuel saklama)

Yine de, git stash save --patchpeşinde olduğunuz kısmi depolamaya ulaşmanızı sağlar:

İle --patch, HEAD ile saklanacak çalışma ağacı arasındaki farktan etkileşimli olarak seçim yapabilirsiniz.
Stash girdisi, dizin durumu deponuzun dizin durumu ile aynı olacak şekilde oluşturulur ve çalışma ağacı yalnızca etkileşimli olarak seçtiğiniz değişiklikleri içerir. Seçilen değişiklikler daha sonra çalışma ağacınızdan geri alınır.

Ancak bu, tam dizini (zaten dizine eklenmiş diğer dosyaları içerebileceği için istediğiniz şey olmayabilir) ve kısmi bir çalışma ağacını (saklamak istediğiniz dizine benzeyebilir) kaydeder.

git stash --patch --no-keep-index

daha uygun olabilir.


Eğer --patchişe yaramazsa manuel bir işlem:

Bir veya birkaç dosya için, ara bir çözüm:

  • onları Git repo'sunun dışında kopyala
    (Aslında, eleotlecram ilginç bir alternatif öneriyor )
  • git stash
  • onları geri kopyala
  • git stash # bu sefer yalnızca istediğiniz dosyalar saklanıyor
  • git stash pop stash@{1} # tüm dosya değişikliklerinizi yeniden uygulayın
  • git checkout -- afile # herhangi bir yerel değişiklikten önce dosyayı HEAD içeriğine sıfırlayın

Bu oldukça zahmetli işlemin sonunda, yalnızca bir veya birkaç dosya saklanır.


3
Bu güzel, ama çoğu zaman bir çok dosyayı değiştirdim, bu yüzden yama kullanmak sinir bozucu
Casebash

6
@VonC: Yanıt başına sadece bir cevap almak iyi bir stildir. Ayrıca, başkalarının cevaplarını kendinize kopyalamak kötü bir davranıştır.
bukzor

3
@bukzor: Düzenlenen cevabım yanlış görünüyorsa özür dilerim. Tek niyetim cevabınıza daha fazla görünürlük sağlamaktı. Bu niyeti daha açık hale getirmek için görevimi tekrar düzenledim.
VonC

1
@Kal: true, stackoverflow.com/a/13941132/6309 , git reset(karışık) önerir
VonC

3
git is fundamentally about managing a all repository content and index and not one or several files- bu, çözülmekte olan sorunun gölgesinde kalıyor; bu bir açıklama, ama bir gerekçe değil. Herhangi bir kaynak kontrol sistemi "birkaç dosyayı yönetmek" ile ilgilidir. Sadece en çok hangi yorumların yükseltildiğine bakın.
Victor Sergienko

90

Ne zaman git stash -p(ya git add -pile stash --keep-indexçok külfetli olacaktır), ben daha kolay kullanmak bulundu diff, checkoutve apply:

Yalnızca belirli bir dosyayı / dizini "saklamak" için:

git diff path/to/dir > stashed.diff
git checkout path/to/dir

Sonra

git apply stashed.diff

1
git add -pYukarıda kendi cevabımda bahsettiğim ilginç bir alternatif . +1.
VonC

11
İkili dosyalarınız (PNG'ler gibi) varsa, bunların diff dosyasına gönderilmeyeceğini unutmayın. Yani bu% 100 bir çözüm değil.
void.pointer

1
@RobertDailey: olarak Bu bana ilginç bir nokta, var git diff > file.diffve git applyher zamanki kısmi zula araçlardır. Daha git stash -pbüyük değişiklik setleri için geçiş yapmayı düşünebilirim .
thekingoftruth

1
@thekingoftruth İşte yama dosyaları oluşturmak için kullanmak takma olduğunu ve yaptığı destek ikilileri: patch = log --pretty=email --patch-with-stat --reverse --full-index --binary. Ancak bunun yama için yapılması gereken değişiklikleri gerektirdiğini unutmayın.
void.pointer

2
Eğer saklamak için dosya gibi bir şey olsaydı bu benim için temiz çalışma değildi ../../foo/bar.txt. Düzeltme eki Tamam oluşturur, ancak daha sonra düzeltme ekinin uygulanmasını sağlamak için depo köküne geçmem gerekir. Bu konuda sorun yaşıyorsanız, bunu depo kök dizininden yaptığınızdan emin olun.
Michael Anderson

86

Şunun git stash pushgibi kullanın :

git stash push [--] [<pathspec>...]

Örneğin:

git stash push -- my/file.sh

Bu, 2017 ilkbaharında piyasaya sürülen Git 2.13'ten beri mevcuttur.


1
Ama söz yapmak git stash pushzaten yukarıda cevabım , 5 ay önce geçen Mart. Ve burada yeni Git 2.13 komutunu detaylandırdım: stackoverflow.com/a/42963606/6309 .
VonC

Git'in o kadar hızlı ilerlediğine sevindim, uzun zamandır bu mümkün değildi ve sonra 2.13 serbest bırakıldı ve aniden basit bir çözüm var!
sandstrom

1
@VonC haklısınız, doğru cevabı da söylüyorsunuz, ancak iki cevap arasında bunun okunması daha kolay (kafa karıştırıcı metin yok ve ayrıca bir örnek var). Belki bunun yerine cevabınızı düzenlemelilerdi
Utopik

@Utopik Beni "haklısın" da söyledin ... ama evet, cevabımı bir örnek içerecek şekilde düzenledim.
VonC

Daha sonra git stash applysaklanan değişiklikleri kurtarmak için kullanılıyor mu?
Çad

49

Diyelim ki 3 dosyanız var

a.rb
b.rb
c.rb

ve sadece b.rb ve c.rb'yi saklamak istiyorsunuz ama a.rb'yi değil

böyle bir şey yapabilirsin

# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp" 

# then stash the other files
git stash save "stash message"

# then undo the previous temp commit
git reset --soft HEAD^
git reset

Ve işiniz bitti! HTH.


29

Bunu yapmanın başka bir yolu:

# Save everything
git stash 

# Re-apply everything, but keep the stash
git stash apply

git checkout <"files you don't want in your stash">

# Save only the things you wanted saved
git stash

# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}

git checkout <"files you put in your stash">

(Bir kez daha) bu sayfaya geldikten ve ilk iki yanıtı beğenmedikten sonra bunu buldum (ilk cevap soruyu cevaplamıyor ve -pinteraktif modla çalışmaktan hoşlanmıyordum ).

Fikir @VonC'un depo dışındaki dosyaları kullanarak önerdiği ile aynıdır, istediğiniz değişiklikleri bir yere kaydedersiniz, saklamak istemediğiniz değişiklikleri kaldırır ve daha sonra yoldan çıkardığınız değişiklikleri yeniden uygularsınız. Bununla birlikte, git stash'ı "bir yer" olarak kullandım (ve sonuç olarak, ekstra bir adım daha var: sakladığınız cnamge'ları kaldırmak, çünkü bunları da yoldan çıkardınız).


1
en çok bu yaklaşımı tercih ediyorum. Tortoisegit içinde yalnızca stash ve revert komutlarını kullanarak kolay bir iş akışı sağlar.
Mark Ch

SO kullanım pozisyonlarında cevaplara atıfta bulunmak önerilmez. Derecelendirme değiştikçe pozisyonlar değişir.
Bryan Ash

2
@BryanAsh Buradaki gibi değil. Gerçekten diğer cevaplara atıfta bulunmak yerine bir fıkra veriyorum. Mesaj şu ki, topluluğun sevdiği cevapları beğenmedim ve bu cevapların gerçekte ne içerdiğini değil. Ayrıca, ikinci ve üçüncü cevap arasındaki 900 oy boşluğu, yakın gelecekte bunu değiştirmeyi pek mümkün kılmamaktadır ve eğer değişmesi gerekiyorsa her zaman "o zaman cevapların en tepesi" diyerek düzenleyebilirim. Gerçekten, bu durumda bunun nasıl bir problem olduğunu anlamıyorum.
Jasper

23

Güncelleme (14.02.2015) - Şimdi .rej dosyaları yerine birleştirilmemiş çatışmalar olarak sunulması gereken çakışmaları daha iyi ele almak için betiği biraz yeniden yazdım.


@ Bukzor'un yaklaşımının tersini yapmayı daha sezgisel buluyorum. Yani, bazı değişiklikleri sahneye koymak ve daha sonra sadece bu aşamalı değişiklikleri saklamak.

Ne yazık ki, git git stash sunmuyor - sadece dizin veya benzeri, bu yüzden bunu yapmak için bir komut dosyası çırptı.

#!/bin/sh

# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`

# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`

# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`

# get back to a clean state with no changes, staged or otherwise
git reset -q --hard

# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to succeed
git cherry-pick -n $INDEXCOMMIT
git stash

# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT

CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
    # If there are no conflicts, it's safe to reset, so that
    # any previously unstaged changes remain unstaged
    #
    # However, if there are conflicts, then we don't want to reset the files
    # and lose the merge/conflict info.
    git reset -q
fi

Yukarıdaki komut dosyasını git-stash-indexyolunuzun herhangi bir yerinde kaydedebilir ve daha sonra git stash-index olarak çağırabilirsiniz.

# <hack hack hack>
git add <files that you want to stash>
git stash-index

Artık zulası yalnızca hazırladığınız değişiklikleri içeren yeni bir giriş içeriyor ve çalışma ağacınız hala değişmemiş değişiklikler içeriyor.

Bazı durumlarda, çalışma ağacı değişiklikleri dizin değişikliklerine bağlı olabilir, bu nedenle dizin değişikliklerini sakladığınızda çalışma ağacı değişikliklerinin çakışması olur. Bu durumda, git merge / git mergetool / etc ile çözebileceğiniz olağan birleştirilmemiş çakışmaları alırsınız.


Tavsiye pushdyerine cdve popdkomut başarılı eğer öyleyse senaryonun sonunda, kullanıcı çalıştırmadan önce aynı dizinde biter.
Nate

1
@Nate: bildiğim kadarıyla, sadece komut dosyası kaynaklanıyorsa kullanıcının dizinini değiştirmelidir. Komut dosyasını normal olarak (~ / bin / git-stash-index) veya git (git stash-index) aracılığıyla çalıştırırsanız, ayrı bir terminal oturumunda çalıştırılır ve bu oturumdaki herhangi bir çalışma dizini değişikliği kullanıcının terminal oturumunda çalışma dizini. Bu doğru olmadığında yaygın bir kullanım durumunun farkında mısınız? ("ortak" olarak değerlendirmeyeceğim senaryoyu kaynaklamaktan başka)
JesusFreke

20

Saklı değişikliklerinizle birlikte bir mesaj belirtmek istemiyorsanız, dosya adını çift kısa çizgiden sonra iletin.

$ git stash -- filename.ext

İzlenmemiş / yeni bir dosyaysa, önce onu yerleştirmeniz gerekir.

Bu yöntem git sürüm 2.13+ 'da çalışır


Bu cevap ayrıntılı, bu kısa ve öz. Birine yardım ederse, bırakacağım. Bu sayfadaki hiç kimse bu sözdiziminden ve sonuçtan bahsetmiyor - bunun yerine `` git stash push '' dan bahsediyorlar.
sealocal

Aradığım cevap buydu. Teşekkürler! +1
nicodp

19

Git'te şube oluşturmak önemsiz olduğundan, sadece geçici bir şube oluşturabilir ve tek tek dosyaları kontrol edebilirsiniz.


2
İşaretlenmemiş düzenlemeleri olan bir şube oluşturamazsınız. Tüm düzenlemeleri yeni bir dala (stash / stash pop) kolayca taşıyabilirsiniz , ancak sonra bir kareye geri dönersiniz: dalınızı, diğerlerini kaybetmeden sadece bu düzenlemelerin bazılarıyla nasıl test edersiniz?
bukzor

7
Sen olamaz geçiş yerel değişiklikleri varsa dalları. Ancak, yeni bir şube oluşturabilir ve seçmeli olarak dosya ekleyebilir / kaydedebilir ve daha sonra başka bir şube oluşturabilir ve aynısını yinelemeli olarak yapabilirsiniz ... sonra orijinal dalı kontrol edip seçici bir şekilde tekrar birleştirebilirsiniz. Sadece yaptım. Aslında özellik dalları oluşturduğunuz için, bir şeyler yapmanın doğal yolu gibi görünüyor.
Iain

3
@iain Yerel değişiklikleriniz varsa, birleştirme gerektirmedikleri sürece şubeleri değiştirebilirsiniz. Bakınız Örnek Gist . Bu en azından Git v2.7.0'dan itibaren geçerlidir.
Colin D Bennett

18

Bunu basitçe yapabilirsiniz:

git stash push "filename"

veya isteğe bağlı bir mesajla

git stash push -m "Some message" "filename"

1
Bu yeni bir şey eklemiyor. Git stash push zaten birden fazla
cevapta

12

Aşağıdaki kodu, örneğin adlı bir dosyaya kaydedin stash. Kullanımı stash <filename_regex>. Argüman, dosyanın tam yolu için normal ifadedir. Örneğin, a / b / c.txt stash a/b/c.txtveya stash .*/c.txtvb. Saklamak için .

$ chmod +x stash
$ stash .*.xml
$ stash xyz.xml

Dosyaya kopyalanacak kod:

#! /usr/bin/expect --
log_user 0
set filename_regexp [lindex $argv 0]

spawn git stash -p

for {} 1 {} {
  expect {
    -re "diff --git a/($filename_regexp) " {
      set filename $expect_out(1,string)
    }
    "diff --git a/" {
      set filename ""
    }
    "Stash this hunk " {
      if {$filename == ""} {
        send "n\n"
      } else {
        send "a\n"
        send_user "$filename\n"
      }
    }
    "Stash deletion " {
      send "n\n"
    }
    eof {
      exit
    }
  }
}

2
Harika bir yöntem. Bunu cevap olarak seçerdim. Gelecekteki okuyucular için ipucu: tam yolda eşleşmeniz gerekir. örneğin stash subdir /
foo.c

12

Her kullandığınızda değişiklikleri atmak istediğinizde git stash(ve geçici olarak saklamak için git stash kullanmayın), bu durumda

git checkout -- <file>

[ NOT ]

Bu git stash, dallanma ve bir şeyler yapmanın daha hızlı ve basit bir alternatifidir.


8

VonC'nin dosyaları Git deposunun dışına kopyalamanın `` ara '' çözümü ile ilgili sorun, yol bilgilerini kaybetmenizdir, bu da bir grup dosyayı daha sonra biraz güçlükle kopyalamayı sağlar.

Kopyalama yerine tar (benzer araçlar muhtemelen kullanacaktır) kullanımını daha kolay bulur:

  • tar cvf /tmp/stash.tar yol / / / bazı / dosya yolu / / bazı / diğer / dosya (... vb.)
  • git çıkış yolu / to / some / dosya yolu / to / some / other / file
  • git stash
  • tar xvf /tmp/stash.tar
  • vb. (bkz. VonC'nin `` ara '' önerisi)

checkout -fgerekli değil, checkout(olmadan -f) yeterli, cevabı güncelledim.
eleotlecram

8

Bazen işime başlamadan önce şubemde alakasız bir değişiklik yaptım ve onu başka bir şubeye taşımak ve ayrı olarak (usta gibi) işlemek istiyorum. Bunu yapıyorum:

git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...

İlkine dikkat edin stashve stash poportadan kaldırılabilir, tüm değişikliklerinizimaster ödeme yaparken şubeye , ancak yalnızca çakışma yoksa. Ayrıca kısmi değişiklikler için yeni bir dal oluşturuyorsanız, zulasa ihtiyacınız olacaktır.

Çatışma ve yeni şube olmadığı varsayılarak basitleştirebilirsiniz:

git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...

Stash'a bile gerek yok ...


8

Bu, SourceTree kullanılarak 3 adımda kolayca yapılabilir.

  1. Saklamak istemediğiniz her şeyi geçici olarak yapın.
  2. Git her şeyi ekleyip saklayın.
  3. Geçici sıfırdan önce taahhüdü hedefleyerek git reset komutunu çalıştırarak geçici taahhüdünüzü açın.

Tüm bunlar, eklemek istediğiniz dosyaları (hatta tek tek satırları) tıklayabileceğiniz SourceTree'de saniyeler içinde yapılabilir. Bir kez eklendiğinde, onları geçici bir taahhütte bulunmanız yeterli. Ardından, tüm değişiklikleri eklemek için onay kutusunu tıklayın, ardından her şeyi saklamak için saklamak'ı tıklayın. Saklanan değişiklikler ortadan kalktığında, taahhüt listenize bir göz atın ve geçici taahhüdünüzden önce taahhüdün karmasını not edin, ardından temel olarak dalınızı şubeye sıfırlayarak "git reset" hash_b4_temp_commit 'komutunu çalıştırın. ondan hemen önce taahhütte bulun. Şimdi, saklanmak istemediğiniz şeylerle kaldınız.


8

Kullanırdım git stash save --patch. İstenilen işlemi tüm dosyalara uygulamak için seçenekler olduğu için can sıkıcı bir etkileşim bulamıyorum.


3
Bu cevap için çok az destek olduğunu hayrete düşürdü, bir denemeye gerek kalmadan en iyi çözüm.
robstarbuck

Kesinlikle iyi yanıt, git stash -ptüm dosyayı hızlı bir şekilde saklamanıza ve daha sonra bırakmanıza izin verir.
Richard Dally

7

Buradaki her cevap çok karmaşık ...

Peki ya "saklamak":

git diff /dir/to/file/file_to_stash > /tmp/stash.patch
git checkout -- /dir/to/file/file_to_stash

Bu dosya değişikliği geri pop:

git apply /tmp/stash.patch

Bir dosyayı saklamak ve tekrar açmakla aynı davranış.


Denedim ama hiçbir şey olmuyor. Ben git applyhiçbir
hatam

/ Tmp içinde oluşturduğunuz yama dosyası muhtemelen silinmiştir. Fark ve uygulama arasında yeniden başlatma yapmış olabilirsiniz. Daha kalıcı başka bir yer deneyin. Çalışıyor. Ayrıca yama dosyasının içeriğini de kontrol edin.
Christophe Fondacci

4

Bunun ve benzer konuların cevaplarını ve yorumlarını inceledim. İzlenen / izlenmeyen belirli dosyaları saklamak amacıyla aşağıdaki komutların hiçbirinin doğru olmadığını unutmayın :

  • git stash -p (--patch): izlenmeyen dosyalar hariç, parçaları elle seç
  • git stash -k (--keep-index): izlenen / izlenmeyen tüm dosyaları saklayın ve çalışma dizininde saklayın
  • git stash -u (--include-untracked): izlenen / izlenmeyen tüm dosyaları sakla
  • git stash -p (--patch) -u (--include-untracked): geçersiz komut

Şu anda, belirli bir izlenen / izlenmeyen dosyaları saklamak için en makul yöntem:

  • Saklamak istemediğiniz dosyaları geçici olarak kesin
  • Ekle ve sakla
  • Geçici taahhüdü aç

Başka bir soruya yanıt olarak bu prosedür için basit bir komut dosyası yazdım ve burada SourceTree'de prosedürü gerçekleştirmek için adımlar var .


4

Çözüm

Yerel değişiklikler:

  • dosya_A (değiştirildi) sahnelenmedi
  • dosya_B (değiştirildi) sahnelenmedi
  • dosya_C (değiştirildi) sahnelenmedi

Yalnızca dosya_C'deki değişikliklerle bir "saklamam" oluşturmak için :

1. git add file_C
2. git stash save --keep-index temp_stash
3. git stash save my_stash
4. git stash pop stash@#{1}

Bitti.


açıklama

  1. dosya_C eklehazırlama alanına
  2. "temp_stash" adlı geçici bir depo oluşturmak ve değişiklikleri dosya_C'de saklamak
  3. yalnızca dosya_C'deki değişikliklerle aranan zulayı ("my_stash") oluşturun
  4. "temp_stash" (dosya_A ve dosya_B) değişiklikleri yerel kodunuza uygulayın ve zulayı silin

Neler olup bittiğini görmek için adımlar arasında git durumunu kullanabilirsiniz .


3

İki dal arasında geçiş yapmaya çalıştığınızda, bu durum oluşur.

Dosyaları " git add filepath" kullanarak eklemeyi deneyin .

Daha sonra bu satırı yürütün

git stash --keep-index


3

Tek bir dosyayı saklamak için kullanın git stash --patch [file].

Bu istem gidiyor: Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?. Sadece yazın a(bu iri ve daha sonraki tüm iri parçaları dosyaya saklayın) ve iyisiniz.


Eksik pusholarakgit stash push --patch [file]
Filipe Esperandio

@FilipeEsperandio pushsadece daha çalışır yeni sürümleri eskiden Git arasında save. Her iki durumda pushda veya saveşu çağrı ile ima edilir stash: "Herhangi bir argüman olmadan git stash çağrısı git stash push ile eşdeğerdir", docs
patrick

2

Benzer durum. Taahhüt ve tamam değil fark etti.

git commit -a -m "message"
git log -p

Cevaplara dayanarak bu bana yardımcı oldu.

# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push

2

Bu durumda git add -p(etkileşimli) git commit -m blahve sonra gerekirse kalanları saklıyorum.


2

Sadece SourceTree kullanarak, komut satırında nasıl yapacağımı bilmiyorum. Diyelim ki A dosyasını değiştirdiniz ve B dosyasında iki değişiklik ifadesi var. B dosyasında yalnızca ikinci iri saklamak ve diğer her şeye dokunulmadan bırakmak istiyorsanız, şunu yapın:

  1. Her şeyi sahnele
  2. Çalışma kopyanızda A dosyasındaki tüm değişiklikleri geri alan değişiklikler yapın (örn. Harici fark aracını başlatın ve dosyaları eşleştirin.)
  3. B dosyasını, yalnızca ikinci değişiklik uygulanmış gibi görünmesini sağlayın. (örn. harici fark aracını başlatın ve ilk değişikliği geri alın.)
  4. "Aşamalı değişiklikleri koru" seçeneğini kullanarak bir zulası oluşturun.
  5. Herşeyi bozun
  6. Bitti!

2
git add .                           //stage all the files
git reset <pathToFileWillBeStashed> //unstage file which will be stashed
git stash                           //stash the file(s)
git reset .                         // unstage all staged files
git stash pop                       // unstash file(s)

1
Bunu yapmamalısın. Cevap sorunun çözülmesini sağlamalıdır. Sadece kendi sorunuzu sorabilirsiniz.
L_J

bu çözüm, bu sorunun en kolay cevabından biridir. soruyu okuyun, tüm cevapları karşılaştırın ve o zaman bu cevabın ne uygulanabilir bir çözüm ne de soru hakkında yetersiz bilgi olduğuna dair herhangi bir şüpheniz varsa, tekrar konuşabiliriz.
celikz

Bu çalışmaz, çünkü üçüncü komut olan "git stash" aşamalı dosyaları onurlandırmaz. Hem aşamalı hem de eklenmemiş dosyalar zulasına gider. Sorular özellikle sadece bir dosyayı nasıl
saklayacağını

0

Karmaşık bir yol, önce her şeyi taahhüt etmek olacaktır:

git add -u
git commit // creates commit with sha-1 A

Orijinal işleme geri dönün, ancak yeni işleme alınan the_one_file dosyasına bakın:

git reset --hard HEAD^
git checkout A path/to/the_one_file

Şimdi the_one_file dosyasını saklayabilirsiniz:

git stash

Özgün içeriği geri yüklerken kaydedilen içeriği dosya sisteminize kaydederek temizleme:

git reset --hard A
git reset --soft HEAD^

Evet, biraz garip ...


0

İhtiyacım olan şey için cevap bulamadım ve bu kadar kolay:

git add -A
git reset HEAD fileThatYouWantToStash
git commit -m "committing all but one file"
git stash

Bu tam olarak bir dosyayı saklar.


0

Hızlı cevap


Git'te belirli bir değiştirilmiş dosyayı geri almak için aşağıdaki satırı yapabilirsiniz:

git checkout <branch-name> -- <file-path>

İşte gerçek bir örnek:

git checkout master -- battery_monitoring/msg_passing.py


0

Eğer bazı değiştirilmiş dosyaları saklamak istiyorsanız,

Saklamak istemediğiniz dosyaları Sahne Alanı'na ekleyin, ardından yürütüngit stash save --keep-index

Değişmeyen tüm değiştirilmiş dosyaları saklar

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.