Git'te yalnızca aşamalandırılmamış değişiklikleri saklamak


230

Aşağıdaki iş akışını yapmak istiyorum:

  1. Sahneye değişiklikler ekleyin.
  2. Hazırlanmayan tüm diğer değişiklikleri saklayın.
  3. Sahnedeki şeylerle bazı şeyler yapın (örn. Derleme, çalıştırma testleri vb.)
  4. Zulayı uygulayın.

2. adımı yapmanın bir yolu var mı?

Misal

 echo "123" > foo
 git add foo # Assumes this is a git directory
 echo "456" >> foo
 git stash
 cat foo # Should yield 123

Neden değişikliklerinizi sahneledikten sonra yapmıyorsunuz?
Shizzmo

3
Yapar --keepindex IIRC tam olarak
sehe

4
Çünkü, eğer yapı başarısız olursa, bunun bir taahhüdüne sahip olmak istemiyorum. Taahhüdü silebileceğimi biliyorum, ancak mümkünse bunu taahhüt olmadan yapmak istiyorum.
Unapiedra

Sehe, teşekkürler. Bu çalışmayı onaylayabilirim. Gee, linux.die.net/man/1/git-stash adresindeki el kitabına baktım . man git stashdaha iyi.
Unapiedra

--keep-endeksi, fwiw.
jaf0

Yanıtlar:


289

git stash save--keep-indextam olarak ihtiyacınız olanı yapan bir seçeneğe sahiptir.

Yani koş git stash save --keep-index.


9
Doğru. Ben kullanmaya devam saveile git stash. Belki de simetriye uygula / pop ile onurlandırma konusunda ısrarcı olan programcıdır. :)
vhallac

105
Not: bu yine de tüm değişikliklerinizi saklar ; normalden tek fark, git stash saveçalışma kopyasında önceden hazırlanmış değişiklikleri de bırakmasıdır. Yukarıdaki iş akışında bu, zulayı zaten değişikliklerin yarısının bulunduğu yerel bir kopyanın üstüne uyguladığınız için iyi çalışır (git, yoksaymak için yeterince akıllıdır). Ancak, zulayı yeniden uygulamadan önce kodu düzenlerseniz, uygulamaya gittiğinizde birleştirme çakışmalarını görebilirsiniz. Bilginize.
peterflynn

2
@ytpete Bu beni birçok kez ısırdı. Gerçekten gitmemek için sakladığınız şeyleri saklamak için bir yol olsaydı ... Sık sık bir şeyler taahhüt ederim, sonra tam git git saklamak, git commit --ammendtaahhüt ettiğim şeylerde sorun varsa yapabileceğimi bilerek .
rjmunro

1
--amend(yerine --ammend)
Rhubbarb

19
Peterflynn tarafından tanımlanan sorunlar nedeniyle bu çözüm benim için çalışmıyor. Bu soruya iyi bir cevap değildir, çünkü yine de aşamalı değişiklikleri saklar. Daha iyi bir çözümü olan var mı?
user643011 18:17

43

Bu 3 adımda yapılabilir: aşamalı değişiklikleri kaydedin, diğer her şeyi saklayın, aşamalı değişikliklerle dizini geri yükleyin. Temel olarak:

git commit -m 'Save index'
git stash push -u -m 'Unstaged changes and untracked files'
git reset --soft HEAD^

Bu tam olarak ne istediğinizi yapacak.


3
Not: -uayrıca izlenmeyen dosyaları saklar.
ma11hew28

Bu yaklaşım, esasen git stash save --keep-indexçok daha fazla iş ile ne yaptığını çoğaltır . Hiçbir avantaj görmüyorum.
Inigo

1
@vas Hayır, yaklaşım bunu tekrarlamaz. Bkz. Peterflynn'un kabul edilen cevaba yaptığı yorum.
Alexander Klauer

28
git stash save --keep-index

Ayrıca, Re:

Neden değişikliklerinizi sahneledikten sonra yapmayasınız? - İncik

C: Çünkü her zaman test edilmiş kodu kontrol etmelisiniz :) Bu, testleri yalnızca taahhüt etmek üzere olduğunuz değişikliklerle çalıştırmanız gerektiği anlamına gelir

Bütün bunlar, elbette, deneyimli bir programcı olarak, sadece bu değişiklikleri test etmek ve gözden geçirmek için doğuştan gelen dürtü sahibi olmanız dışında - sadece kısmen şaka yapıyor


14

Sizinle git version 2.7.4şunları yapabilirsiniz:

git stash save --patch

gitEğer stash içine değişiklikleri eklemek veya değil isteyecektir.
Ve sonra cevap veriyorsun yya dan

Çalışma dizinini her zaman yaptığınız gibi geri yükleyebilirsiniz:

git stash pop

veya kaydedilmiş değişiklikleri saklamak istiyorsanız:

git stash apply

Bu harika. Biraz emek yoğun, ancak en azından atlayıp tüm dosyaları ekleyebilirsiniz.
Dustin Oprea

5

Önceki yanıtları genişlettiğimde, bazen karmaşık bir dizi değişiklik var, ancak önce ayrı bir değişiklik yapmak istiyorum. Örneğin, aşamalı değişikliklerden önce düzeltmek istediğim bir hata veya başka bir yanlış kod tespit etmiş olabilirim. Olası bir yol şudur:

ilk önce her şeyi saklayın, ancak aşamalı değişiklikleri olduğu gibi bırakın

$ git stash save --keep-index [--include-unracked]

şimdi aşamalı değişiklikleri ayrı ayrı saklayın

$ git stash kaydet

düzeltme için değişiklik yapma; ve test edin; taahhüt edin:

$ git add [- etkileşimli] [--patch]

$ git commit -m "düzeltme ..."

şimdi önceden hazırlanmış değişiklikleri geri yükleyin:

$ git stash pop

herhangi bir çatışma ve anlaşmazlıklar olsaydı, git uygulanır ama olacak o notu çözmek değil bu üst zulası girişini düştü.

(... Sonra aşamalı değişiklikleri yapın ve diğer tüm değişikliklerin saklanmasını geri yükleyin ve devam edin ...)


4

Etiketlenmemiş (kesinleştirme için eklenmemiş) dosyaları stash'a eklemek için aşağıdaki komutu çalıştırın:

git stash -k

Ardından aşamalı dosyaları uygulayabilirsiniz. Bundan sonra komutu kullanarak son saklanan dosyaları geri alabilirsiniz:

git stash pop

4

Git'te yalnızca çalışma ağacını (sabit olmayan değişiklikler) saklamak olması gerekenden daha zordur. Kabul edilen cevap, değişmemiş değişiklikleri saklar, ancak aynı zamanda aşamalı değişiklikleri de saklar (ve aynı zamanda aşamalı bırakır), bu da nadiren istediğiniz şeydir.

Bu takma ad iyi çalışıyor:

stash-working = "!f() { \
  git commit --quiet -m \"temp for stash-working\" && \
  git stash push \"$@\" && \
  git reset --quiet --soft HEAD~1; }; f"

Aşamalı değişiklikleri geçici olarak gerçekleştirir, kalan değişikliklerden bir yığın oluşturur (ve diğer değişkenler gibi --include-untrackedve ek argümanların --messageiletilmesine izin verir ) ve sonra aşamalı değişiklikleri geri almak için geçici taahhüdü sıfırlar.

Bu @Simon Knapp'ın benzer cevap , ancak birkaç küçük farklılıklar ile - kullandığı --quietalınan geçici eylemlere ve saklamak için herhangi bir sayıda parametre kabul eder pushziyade sabit olarak kodlamak yerine, -mve o eklese --softfinale dizinin başlatıldığı gibi kalması için sıfırlayın.

Saklamanın zıt problemi için sadece aşamalı değişiklikler (takma ad stash-index) bu cevaba bakınız .


2

Soru ile ilgili başka bir ipucu:

Kullanılmayan değişikliklerinizi etkili bir şekilde

$ git stash save --keep-index

stash'a bir mesaj vermek isteyebilirsiniz, böylece bunu yaptığınızda, git stash listdaha önce sakladığınız şey daha açıktır, özellikle bu saklamak işlemini daha fazla tasarrufla takip ederseniz. Örneğin

$ git stash save --keep-index "değişiklikler henüz sahnelenmedi"

(aslında diğer yanıtlarda belirtildiği gibi tüm değişiklikleri içerir).

Örneğin, yukarıdakilerin hemen ardından şunlar gelebilir:

$ git stash save "X özelliği için aşamalı değişiklikler"

Bunu, olsa da, dikkat edemez sonra kullanmak

$ git stash uygulamak "stash @ {1}" ### ✘ ne istersen onu yapmaz

sadece değişmemiş değişiklikleri geri yüklemek için.


2

Git'in yalnızca işaretlenmemiş değişikliklerinizi saklayan bir komutu yoktur.

Ancak Git, hangi dosyaları saklamak istediğinizi belirtmenize izin verir.

git stash push --message 'Unstaged changes' -- app/controllers/products_controller.rb test/controllers/products_controller_test.rb

Bu dosyalarda yalnızca belirli değişiklikleri saklamak istiyorsanız, --patchseçeneği ekleyin .

git stash push --patch --message 'Unstaged changes' -- app/controllers/products_controller.rb test/controllers/products_controller_test.rb

Bu --include-untrackedseçenek, izlenmeyen dosyaları saklamanızı sağlar.

git stash push --include-untracked --message 'Untracked files' -- app/controllers/widgets_controller.rb test/controllers/widgets_controller_test.rb

Daha fazla bilgi için çalıştırın git help stash(veya man git-stash).

Not: Değişmemiş değişiklikleriniz oldukça dağınıksa, @ alesguzik'in cevabı muhtemelen daha kolaydır.


0

Bu komutun modern biçimi git stash push [--] [<pathspec>...]Git 2.16+ ( git stash savekullanımdan kaldırılmıştır )

Bunu bir joker karakter formuyla birleştirebilirsiniz, örneğin:

git stash push --all --keep-index ':(glob)**/*.testextension' 

Ancak bu, Git 2.22 (Q2 2019) olana kadar Windows için Git ile iyi çalışmaz, bkz. 2037 , git stashC'de (kabuk komut dosyası yerine) yeniden uygulandı

Bakınız Thomas Gummerer ( ) tarafından 7db9302 (11 Mar 2019) taahhüdütgummerer .
Bkz. Taahhüt 1366c78 , taahhüt 7b556aa (07 Mart 2019) Johannes Schindelin ( dscho) .
(Göre Birleştirilmiş - Junio Cı Hamano gitster- içinde 0ba1ba4 tamamlama 2019 22 Apr)

yerleşik stash: :(glob)pathspec'leri tekrar işleyin

Örneğin yol yollarının bir listesini iletirken yol yollarının git addayrıştırılmış formunu değil, orijinal formu kullanmaya dikkat etmeliyiz.

Bu, örneğin arama yaparken bir fark yaratır

git stash -- ':(glob)**/*.txt'

burada orijinal form :(glob)önek içerirken ayrıştırılmış form içermez.

Ancak, yerleşik olarak git stash, ayrıştırılmış (yani yanlış) formu geçtik git addve hata mesajıyla başarısız oluruz :

fatal: pathspec '**/*.txt' did not match any files

gerçekten başarıyla güncellenmiş git stasholsa bile, çalışma ağacındaki değişiklikleri bıraktığı aşamada refs/stash.


0

Ben stash girişine bir ileti olarak kullanmak için bir dize kabul bir takma ad kullanın.

mystash = "!f() { git commit -m hold && git stash push -m \"$1\" && git reset HEAD^; }; f"

Hangi:

  • dizindeki her şeyi taahhüt eder,
  • çalışma ağacında nelerin değiştiğini saklar (elbette ekleyebilir -uveya -a),
  • son taahhüdü çalışma denemesine geri döndürür ( --softdizinde tutmak için kullanmak isteyebilirsiniz ).
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.