Come decomprimere solo determinati file?


387

Ho nascosto le mie modifiche. Ora voglio decomprimere solo alcuni file dalla scorta. Come posso fare questo?


4
Penso che devi applicare l'intera scorta, ma poi puoi reinserire selettivamente.
Richard

4
@AbdouTahiri Cosa c'è che non va nella scorta?
alex

32
@AbdouTahiri Uhhhh .. git stash è una funzione legittima ed estremamente utile. Lo uso quotidianamente. Supponiamo che un collega abbia bisogno che riveda qualcosa ma sono nel mezzo di un complesso set di modifiche. Non commetterò un mucchio di codice rotto solo per poter cambiare ramo. Ho intenzione di nascondere, cambiare ramo, rivedere, tornare indietro, decomprimere. Ti interessa approfondire chi o perché presumibilmente git stash è "sconsigliato"? Solo perché la tua storia di git stash è confusa e difficile da leggere non significa che tutti gli altri lo siano. Un disordinato set di git è solo un cattivo flusso di lavoro, non un difetto di Git.
Dudewad,

6
@alex Nothing. Niente di sbagliato in git stash. Continua ad usarlo.
Dudewad,

Risposte:


462

Come menzionato di seguito , e dettagliato in " Come estrarre un singolo file (o le modifiche a un file) da un git stash? ", È possibile applicare l'uso git checkouto git showripristinare un file specifico.

git checkout stash@{0} -- <filename>

Ciò sovrascrive filename : assicurati di non avere modifiche locali, oppure potresti voler unire il file nascosto .

(Come commentato da Jaime M. , di certo shell come tcsh in cui è necessario fuggire i caratteri speciali, la sintassi sarebbe: git checkout 'stash@{0}' -- <filename>)

o per salvarlo con un altro nome file:

git show stash@{0}:<full filename>  >  <newfile>

(nota che qui <full filename>c'è il percorso completo di un file relativo alla prima directory di un progetto (pensa: relativo a stash@{0})).

yucer suggerisce nei commenti :

Se si desidera selezionare manualmente quali modifiche si desidera applicare da quel file:

git difftool stash@{0}..HEAD -- <filename>

Vivek aggiunge nei commenti :

Sembra che " git checkout stash@{0} -- <filename>" ripristini la versione del file al momento dell'esecuzione dello stash - NON applica (solo) le modifiche stash per quel file.
Per fare quest'ultimo:

git diff stash@{0}^1 stash@{0} -- <filename> | git apply

(come commentato da peterflynn , | git apply -p1in alcuni casi potrebbe essere necessario rimuovere una ( p1) barra iniziale dai percorsi diff tradizionali)


Come commentato: "unstash" ( git stash pop), quindi:

  • aggiungi ciò che vuoi conservare all'indice ( git add)
  • nascondi il resto: git stash --keep-index

L'ultimo punto è ciò che ti consente di conservare alcuni file mentre ne riponi altri.
È illustrato in " Come eliminare solo un file da più file che sono stati modificati ".


5
Questo non funziona se non è possibile a git stash popcausa di conflitti tra file. La risposta di Balamurugan A mi ha aiutato in questo caso.
Andrey,

1
Se si desidera selezionare manualmente quali modifiche si desidera applicare da quel file, è possibile utilizzare git difftool stash @ {0} .. HEAD - <nomefile>
yucer

5
Sembra che "git checkout stash @ {0} - <nomefile>" ripristina la versione del file al momento dell'esecuzione dello stash - NON applica (solo) le modifiche nascoste per quel file. Per fare questo: "git diff stash @ {0} ^ 1 stash @ {0} - <filename> | git apply"
Vivek

1
@JaimeM. Grazie. Ho incluso il tuo commento nella risposta per una maggiore visibilità.
VonC,

1
Supponendo che ciò unstashsignifichi pop, come mi sembra che probabilmente nella maggior parte dei casi, questo risponde solo parzialmente alla domanda. Come si rimuovono quindi i pezzi applicati in modo selettivo dalla scorta per evitare conflitti e / o confusione successivi quando si aprono le modifiche rimanenti?
DylanYoung,

115
git checkout stash@{N} <File(s)/Folder(s) path> 

Per esempio. Per ripristinare solo il file ./test.c e la cartella ./include dall'ultimo nascosto,

git checkout stash@{0} ./test.c ./include

12
Questa è la risposta corretta! Comando a riga singola per applicare solo modifiche nascoste da file specifici, funziona come un incantesimo!
livelli

1
Per applicare (solo) le modifiche nascoste per il file: "git diff stash @ {N} ^ 1 stash @ {N} - <nomefile> | git apply"
Vivek

Questo funziona anche per me. Basta selezionare in modo selettivo i file necessari per l'uso da stash e il gioco è fatto. Ero bloccato in questo a avevo usato la -abandiera durante la creazione della scorta.
Rajeev Ranjan,

1
@ 4levels Penso che "applica modifiche nascoste" non è quello che succede, giusto? Penso che "sovrascrivi qualunque cosa tu abbia con la copia da stash" è ciò che accade.
msouth,

35

Penso che la risposta di VonC sia probabilmente quello che vuoi, ma ecco un modo per fare un "git apply" selettivo:

git show stash@{0}:MyFile.txt > MyFile.txt

4
Questo potrebbe essere quello che vuoi in alcuni casi, ma fai attenzione che questo comando sovrascriverà piuttosto che fondersi con qualsiasi modifica della directory di lavoro.
Rabarbaro

Questo funziona per me, dal momento che volevo solo copiare un file che esiste solo nella scorta e non mi importava checkoutnulla.
Tom Russell,

1
Per Windows PowerShell: git show stash@`{0`}:Path/To/MyFile.txt |sc Path/To/MyFile.txt- i backtick sono necessari affinché PS non interpreti in modo speciale le parentesi graffe, e ciò scè necessario perché l' >operatore di PS imposta automaticamente UTF-16 (in realtà UCS-2) che probabilmente non è quello che desideri. La risposta di @Balamurugan A non soffre di questi problemi.
Ian Kemp,

19

Prima elenca tutti gli stash

git stash list

stash@{0}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{1}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{2}: WIP on master: 7e450c81 Merge branch 'Offlineseite'

Quindi mostra quali file si trovano nella scorta (selezioniamo la scorta 1):

git stash show 1 --name-only

//Hint: you can also write
//git stash show stash@{1} --name-only

 ajax/product.php
 ajax/productPrice.php
 errors/Company/js/offlineMain.phtml
 errors/Company/mage.php
 errors/Company/page.phtml
 js/konfigurator/konfigurator.js

Quindi applica il file che ti piace:

git checkout stash@{1} -- <filename>

o intera cartella:

git checkout stash@{1} /errors

Funziona anche senza, --ma si consiglia di usarli. Vedi questo post.

È anche convenzionale riconoscere un doppio trattino come segnale per interrompere l'interpretazione delle opzioni e trattare letteralmente tutti i seguenti argomenti.


1
Questo è più chiaro con questa modifica. +1
VonC,

1
Ho provato molti modi e questo era quello di cui avevo bisogno. Ho riscontrato un problema che git stash popgenerava un errore per i file non tracciati. grazie.
Ramin Firooz,

10

Se tu git stash pop(senza conflitti) rimuoverà lo stash dopo che è stato applicato. Ma se git stash applyapplicherai la patch senza rimuoverla dall'elenco di stash. Quindi è possibile ripristinare le modifiche indesiderate congit checkout -- files...


2
Per chiarire i conflitti parte di questo post, se tu git stash pope ci SONO conflitti, dovrai risolverli manualmente e lo stash NON verrà rimosso.
Thomas McCabe,

6

Un altro modo:

git diff stash@{N}^! -- path/to/file1 path/to/file2  | git apply -R

2
Questa è l'unica risposta corretta IMO. L'uso checkouto showsovrascriverà ciecamente il tuo file invece di applicare solo le modifiche. "Un altro modo" è un eufemismo.
generoso

1
Non sto ottenendo il path/to/file2come si desidera diff sullo stesso file nell'area di lavoro. Lasciare il secondo percorso funziona bene per me. - E ricevo un messaggio di errore usando l' -Ropzione ("applica la patch al contrario", provando a correggere la versione nascosta ?!). Quindi la mia versione funzionante sembra git diff stash@{N}^! -- path/to/file | git apply -.
ThomasH

"patch fallita"? Prova un'unione a 3 vie. ...| git apply -3 -
John Mee,

6

Per utenti Windows: le parentesi graffe hanno un significato speciale in PowerShell. Puoi circondare con virgolette singole o scappare con il backtick. Per esempio:

git checkout 'stash@{0}' YourFile

Senza di essa, potresti ricevere un errore:

Unknown switch 'e'


3
Pieni voti a PowerShell per il messaggio utente meno utile che ho visto questo mese.
holdenweb,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.