Soru Git ile değiştirilen birden fazla dosyadan sadece bir dosya sakla?


Şubemde birden çok değiştirilmiş dosyadan sadece birini nasıl saklayabilirim?


2446
2018-06-14 20:52


Menşei


@ Bukzor'un kabul ettiği cevabın, sorulan soruya doğru bir cevap olduğunu düşünmüyorum. git stash --keep-index endeksi koruyor ama saklıyor her şey - hem endekste hem de dışarıda. - Raman
@Antonio Bana göre bu soru aslında aslında ayrı bir soru olmalı, çünkü asıl sorunun TortoiseGit ile özel bir ilgisi yok. - JesusFreke
@JesusFreke Yep, sonuç verdikten sonra 50 rep'yi kaldırabiliyordum :) Bu sadece “parsiyel stash tortoisegit” i aramaya kalkarsanız yeniden yönlendirilecek sorudur. Tortoisegit burada popüler bir konu gibi görünmüyor stackoverflow.com/questions/tagged/tortoisegit - Antonio
>>>>>>>>> git diff -- *filename* > ~/patch sonra git checkout -- *filename* ve daha sonra yamayu yeniden uygulayabilirsiniz git apply ~/patch - neaumusic
Aşağıdaki mevcut cevapların çoğu güncel değil. Git 2.13'ten (Q2 2017) beri destekleniyor git stash push [--] [<pathspec>...]. - Ohad Schneider


Cevaplar:


Uyarı

Yorumlarda belirtildiği gibi, bu her şeyi sahneleniyor, hem sahnelenmiş hem de sahtekar. --Keep-index sadece stoğun yapılmasından sonra endeksi yalnız bırakır. Bu, daha sonra stash açılırsa, birleştirme çakışmalarına neden olabilir.


Bu, daha önce eklemediğiniz her şeyi saklar. Sadece git add saklamak istediğin şeyleri, sonra çalıştır.

git stash --keep-index

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

  1. git rebase -i <last good commit>
  2. Bazı değişiklikleri şu şekilde işaretle: edit.
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. Gerektiği gibi düzeltin. Unutma git add herhangi bir değişiklik.
  7. git commit
  8. git stash pop
  9. Gerekirse # 5'den tekrarlayın.
  10. git rebase --continue

1218
2017-11-30 21:28



Bu yaklaşımı çok daha basit buluyorum: stackoverflow.com/a/5506483/457268 - k0pernikus
Bunun neden buralarda olduğundan emin değilim. Herkes benden farklı bir beklentiye sahip olmalı. Orijinal yazı, "kabul edilmeyen değişikliklerin sadece bir kısmını nasıl saklarım?" Kullandigimda git stash save -k, evet indeks (yeşil git stat) korunur, ancak tüm changeset (hem yeşil hem kırmızı) stoğa gider. Bu OP'nin talebini ihlal ediyor, "sadece bazı değişiklikler sakla". Kırmızıdan bazılarını saklamak istiyorum (gelecekteki kullanım için). - Pistos
@Pistos (benim olduğum gibi) tarafından sorulan soruya daha fazla ilgi duyuyorsanız, o zaman buraya bakın: stackoverflow.com/questions/5506339/... - Raman
@Raman: Mükemmel! git stash -p tam olarak aradığım şey. Bu anahtarın sadece yeni eklenmiş olup olmadığını merak ediyorum. - Pistos
UYARI: git stash --keep-index kırılmış, bozulmuş. Daha fazla değişiklik yaparsanız git stash pop Daha sonra birleşme çakışmaları olur, çünkü saklanmak sadece saklayamadığınız değil, değiştirdiğiniz dosyaları içerir. Örneğin: A ve B dosyalarını değiştirdim, sonra B'yi saklıyorum, çünkü A'daki değişiklikleri test etmek istiyorum; Daha sonra düzelteceğim bir sorunla karşılaşıyorum; Ben A; Şimdi alamıyorum çünkü A'nın eski bir versiyonu, bir birleşme çatışmasına neden olan iyi bir nedenden ötürü saklı. Uygulamada A ve B birçok dosya, belki de ikili görüntüler veya bir şey olabilir, bu yüzden temelde pes etmem ve kaybetmem gerek. - rjmunro


Ayrıca kullanabilirsiniz git stash save -p "my commit message". Bu sayede haneye hangi hunks ekleneceğini seçebilir, tüm dosyalar da seçilebilir.

Her iri 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

2619
2017-07-31 11:59



Bu, en basit yaklaşımla soruyu doğrudan yanıtladığı için en üstte olmalıdır. Keşke eklemek için bir bütün dosya ve tamamen dışlamak için başka bir dosya vardı gibi keşke "a" / "d" seçenekleri (ve denemeden önce bu cevabı tamamen okuyun) gördüm. Yine de benim için iyi çalıştı; Çok fazla hunks yoktu. (Bu soru orijinal olarak gönderildiği sırada 2010'da hiç kimse tarafından önerilmiyordu çünkü bu özellik bu zamanda gitmiyordu.) - Liam
Değildi. Darcs'tan yaklaşık 7 yıl sonra ödünç alındı. - nomen
Ben bir TortoiseGit bağımlısıyım. Ancak TortoiseGit desteklemiyor stash -p. Bu cevabı verdim çünkü en etkileşimli / kullanıcı dostu olmaya devam ediyor. - Antonio
eklemek isteyebilirsiniz: git stash save -p my stash message; Argümentasyonun düzeni çok sezgisel olmadığından ... - Chris Maes
Bu ve git log -p, Bence -p bayrak "istediğim havalı şeyi yapmak ama nasıl ifade edeceğini bilmemek" anlamına gelmelidir. - Kyle Strand


Git temelde tüm bir depo yönetme hakkında içerik ve dizin (ve bir veya birkaç dosya değil), git stash fırsatlar şaşırtıcı değil, tüm çalışan dizini ile.

Aslında, Git 2.13'ten (Q2 2017) beri, tek tek dosyaları saklayabilirsiniz:

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

Görmek "Stash belirli dosyalarda değişir" daha fazlası için.


Orijinal cevap (aşağıda, Haziran 2010), saklamak istediğiniz şeyi elle seçmekle ilgiliydi.

Casebash yorumlar:

Bu (the stash --patch orijinal çözüm) güzel, ama genellikle bir sürü dosya değiştirdim, bu yüzden yama kullanmak sinir bozucu

bukzor'ler Cevap (Kasım 2011'de açıklandı), daha pratik bir çözüm önerdi.
git add + git stash --keep-index.
Git cevabını gör ve cevabını ver, resmi olan (benimki yerine).

Bu seçenek hakkında chhh Yorumlarda alternatif bir iş akışını işaret eder:

malısın "git reset --soft"temiz bir sahneyi geri almak için böyle bir stashdan sonra:
  Orijinal bir duruma ulaşmak için - ki bu net bir sahneleme alanı ve sadece bazı seçilmemiş kademeli modifikasyonlar ile, indeksi (sizin gibi bir şey yapmadan - bukzor yapmak) yumuşak bir şekilde sıfırlayabiliyordu.


(Orijinal cevap Haziran 2010: el kitabı)

Ancak git stash save --patch sonra kısmi stashing elde etmek için izin verebilir:

İle --patch, HEAD ve saklanacak çalışan ağaç arasındaki farkın içinden hunks'i etkileşimli olarak seçebilirsiniz.
  Stash girdisi, dizin durumunun deponuzun dizin durumuyla aynı olacak şekilde yapılandırılır ve onun worktree'si yalnızca etkileşimli olarak seçtiğiniz değişiklikleri içerir. Seçilen değişiklikler daha sonra çalışma tablonuzdan geri alınır.

Ancak bu, tam dizini (önceden dizine eklenmiş olan diğer dosyaları içerebileceğinden, istediğiniz gibi olmayabilir) ve kısmi bir çalışma notunu (saklamak istediğiniz gibi görünebilir) kaydedecektir.

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

daha iyi bir uyum olabilir.


Eğer --patchçalışmaz, manuel bir işlem olabilir:

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

  • onları Git repo dışında kopyala
    (Aslında, eleotlecram bir teklif ilginç alternatif)
  • git stash
  • onları geri kopyala
  • git stash # bu sefer sadece istediğin dosyalar saklanmış
  • git stash pop stash@{1} # tüm dosya değişikliklerini yeniden uygulayın
  • git checkout -- afile # yerel modifikasyonlardan önce dosyayı HEAD içeriğine sıfırlayın

Bu oldukça hantal bir süreç sonunda, sadece bir veya birkaç dosyaya sahip olacaksınız.


238
2018-06-14 21:23



Bu güzel, ama genellikle bir sürü dosyayı değiştirdim, bu yüzden yama kullanmak sinir bozucu. - Casebash
@VonC: Her Cevap için tek bir cevabın olması iyi bir stil. Ayrıca, başkalarının cevaplarını kendi başınıza kopyalayıp yapıştırmak kötü bir davranış. - bukzor
@bukzor: Düzenlenmiş cevabım uygunsuz görünüyorsa özür dilerim. Tek amacım cevabınızı daha fazla görünürlük sağlamaktı. Bu niyetimi daha net hale getirmek için gönderimi tekrar düzenledim. - VonC
@Kal: true, stackoverflow.com/a/13941132/6309 önerir git reset (karışık) - VonC
git is fundamentally about managing a all repository content and index and not one or several files - Bu, çözülmekte olan problemi gölgeleyen uygulama; Bu bir açıklama, ama bir gerekçe değil. Herhangi bir kaynak kontrol sistemi "birkaç dosyayı yönetme" hakkında. Sadece en çok hangi yorumların alındığına bakın. - Victor Sergienko


Ne zaman git stash -p (veya git add -p ile stash --keep-index) çok hantal olurdu, kullanımı daha kolay buldum diff, checkout ve apply:

Yalnızca belirli bir dosya / dizin için "saklamak":

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

Sonradan

git apply stashed.diff

76
2018-02-12 13:44



İlginç bir alternatif git add -p Yukarıda kendi cevabımda bahsettim. +1. - VonC
İkili dosyalarınız varsa (PNG'ler gibi), bunlar diff dosyasına gönderilmeyecektir. Yani bu% 100 bir çözüm değil. - void.pointer
@RobertDailey: Bu benim için ilginç bir nokta git diff > file.diff ve git apply her zamanki kısmi stash araçlarım. Geçiş yapmayı düşünebilirim git stash -p daha büyük değişiklikler için. - thekingoftruth
@thekingoftruth İşte yama dosyalarını oluşturmak için kullandığım takma ad ve yapar destek ikilileri: patch = log --pretty=email --patch-with-stat --reverse --full-index --binary. Bununla birlikte, bu, düzeltme ekinin işlenmesini gerektirir. - void.pointer
Bu dosyayı saklamak için bir şey gibi olsaydı benim için temiz çalışma değildi ../../foo/bar.txt. Düzeltme paketi tamam, ancak daha sonra uygulamak için yama almak için depo köküne taşımak gerekir. Bu nedenle sorun yaşıyorsanız, bunu depo kök dizinden yaptığınızdan emin olun. - Michael Anderson


Diyelim ki 3 dosya var

a.rb
b.rb
c.rb

ve sadece b.rb ve c.rb'yi saklamak istiyorsun ama a.rb’i 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 sen bitti! HTH.


43
2017-10-31 07:10





kullanım git stash push, bunun gibi:

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

Örneğin:

git stash push -- my/file.sh

Bu, 2017 baharında piyasaya sürülen Git 2.13'ten beri kullanılabilir.


34
2017-08-15 13:10



Ama ben bahsetmiyorum git stash push zaten Yukarıdaki cevabım Geçen Mart, 5 ay önce. Ve bu yeni Git 2.13 komutunu burada ayrıntılı olarak anlattım: stackoverflow.com/a/42963606/6309. - VonC
Git'in çok hızlı ilerlediği için mutluyum, uzun bir süre bu mümkün değildi ve 2.13 yayınlandı ve aniden basit bir çözüm mevcut! - sandstrom


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">

Bu sayfaya geldikten sonra (bir kez daha) bu sayfaya geldim ve ilk iki cevabı beğenmedim (ilk cevap sadece soruya cevap vermiyor ve ben de -p etkileşimli mod).

Bu fikir, @VonC'nin deponun dışındaki dosyaları kullanarak önerdiği ile aynıdır, bir yerde istediğiniz değişiklikleri kaydedersiniz, saklanmalarınızda istemediğiniz değişiklikleri kaldırırsınız ve ardından yoldan çıktığınız değişiklikleri yeniden uygularsınız. Bununla birlikte, git stash'ı “bir yer” olarak kullandım (ve sonuç olarak, sonunda bir adım daha var: stasına koyduğunuz çentiklerin çıkarılması, çünkü bunları yoldan çıkardınız).


25
2018-02-05 10:16



Bu yaklaşımı en çok tercih ederim. Tortoisegit'te sadece stash ve revers komutlarını kullanarak kolay bir iş akışı sağlar. - Mark Ch
SO kullanımı ile ilgili cevaplara başvurmak tavsiye edilmez. Reytingler değiştikçe pozisyonlar değişir. - Bryan Ash
@BryanAsh Eh, burada önemli değil. Diğer cevaplara atıfta bulunmak yerine bir anekdot veriyorum. Mesaj, topluluğun sevdiği cevapları beğenmedim ve bu cevapların gerçekte ne içerdiğini değil. Ayrıca, ikinci ve üçüncü cevaplar arasındaki 900 oy farkı, yakın gelecekte bu değişimin değişmesini imkânsız kılıyor ve eğer değişmesi gerekiyorsa, her zaman "o zamana kadar cevapların en üst noktası" olarak düzenleyebilirim. Gerçekten, bu durumun nasıl bir sorun olduğunu göremiyorum. - Jasper


Güncelleme (2/14/2015) - Komut dosyalarını yeniden yazdım, çatışma durumlarını daha iyi ele alabilmek için .rej dosyaları yerine artık birleşik anlaşmazlıklar olarak sunulmalıdır.


Sık sık, @ bukzor'un yaklaşımının tersini yapmak için daha sezgisel buluyorum. Yani, bazı değişiklikler yapmak ve daha sonra sadece sahnelenen değişiklikleri saklamak.

Ne yazık ki, git git stash --only-index veya benzer bir teklif sunmuyor, bu yüzden bunu yapmak için bir betik çırpmıştım.

#!/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ı aşağıdaki gibi kaydedebilirsiniz: git-stash-index Yolunuzda bir yerde ve daha sonra git stash-index olarak çağırabilir

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

Stash, yalnızca sahnedeki değişiklikleri içeren yeni bir giriş içeriyor ve çalışan ağacınızda hala herhangi bir değişiklik yapılmamış değişiklik var.

Bazı durumlarda, çalışan ağaç değişiklikleri, dizin değişikliklerine bağlı olabilir; bu nedenle, dizin değişikliklerini sakladığınızda, çalışan ağaç değişiklikleri bir çakışma olur. Bu durumda, git birleştirme / git mergetool / etc ile çözebileceğiniz olağandışı uyuşmazlıkları elde edersiniz.


22
2018-06-16 21:00



Tavsiye etmek pushd yerine cd ve popd komut dosyasının sonunda, komut başarılı olursa, kullanıcı, çalıştırılmadan önce olduğu gibi aynı dizinde biter. - Nate
@Nate: Bildiğim kadarıyla, yalnızca komut dosyasının kaynağı olup olmadığını kullanıcı için dizini değiştirmelidir. Komut dosyasını normal olarak çalıştırırsanız (~ / bin / git-stash-index) veya git (git stash-index) ile ayrı bir terminal oturumunda çalışır ve bu oturumda çalışan herhangi bir dizin değişir. Kullanıcının terminal oturumunda çalışma dizini. Bunun doğru olmadığı durumlarda yaygın bir kullanım durumunun farkında mısınız? ("ortak" olarak düşünemediğim betiği kaynaklamaktan başka) - JesusFreke


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


16
2018-06-28 12:07



Eleştirilmemiş düzenlemeleri olan bir şube oluşturamazsınız. Kolayca taşıyabilirsiniz herşey yeni bir şubeye (stash / stash pop) ilişkin düzenlemeler yapıldıktan sonra bire bir geri döndüğünüzde: dalınızı başkalarını kaybetmeden yalnızca bu düzenlemelerden yalnızca bazılarıyla nasıl test edersiniz? - bukzor
Sahte düzenlemeler içeren bir şube oluşturdum. - shangxiao
Yapamazsın şalter yerel değişiklikleriniz varsa şubeleri. Bununla birlikte, yeni bir şube oluşturabilir ve seçmeli olarak dosya ekleyebilir / ekleyebilir, sonra da başka bir dal oluşturabilir ve aynı özyinelemeyi yapabilir ... daha sonra orijinal şubeyi kontrol edebilir ve seçici olarak tekrar bir araya getirebilirsiniz. Aslında, özellik dallarını oluştururken aslında işleri yapmanın doğal yolu gibi görünüyor. - iain
@iain Birleştirme gerektirmedikleri sürece yerel değişiklikleriniz varsa dalları değiştirebilirsiniz. Görmek Örnek Gist. Bu en az Git v2.7.0'dan itibaren geçerlidir. - Colin D Bennett