Perché non è possibile applicare lo stash alla directory di lavoro?


96

Non riesco ad applicare lo stash alla directory di lavoro.

Piccola storia:

Per prima cosa ho provato a eseguire il push di alcune modifiche impegnate, ma diceva: "no non puoi, tirare prima" ... OK, allora, prenderò le cose da GitHub e poi spingerò le mie modifiche. Quando ho provato a eseguire il pull, è stato detto che avevo modifiche che sarebbero state sovrascritte e che avrei dovuto nascondere le mie modifiche. OK, ho nascosto le modifiche ... ho fatto il pull e ho spinto le modifiche confermate. Ma ora, non posso ripristinare le modifiche non salvate su cui stavo lavorando.

Questo è l'errore:

MyPath/File.cs already exists, no checkout
Could not restore untracked files from stash

Di sicuro non ho ancora capito tutti i concetti di git, mi confondono un po '... forse ho fatto qualcosa di sbagliato.

Sarebbe fantastico se qualcuno mi aiutasse a risolvere questo problema ... Ho cercato su Google e tutto il resto da più di un'ora ormai, e non sono ancora arrivato a una soluzione.

L'aiuto è molto apprezzato. Grazie!

Risposte:


74

Sembra che la tua scorta includa un file non tracciato che è stato successivamente aggiunto al repository. Quando provi a controllarlo, git rifiuta giustamente perché sovrascriverebbe un file esistente.

Per risolvere il problema, potresti fare qualcosa come eliminare quel file (va bene, è ancora nel repository), applicare il tuo stash e quindi sostituire la versione nascosta del file con la versione in-repo come appropriato.

Modifica: è anche possibile che il file sia stato creato solo nell'albero di lavoro senza essere stato aggiunto al repository. In questo caso, non eliminare semplicemente il file locale, ma piuttosto:

  1. spostalo da qualche altra parte
  2. applica la scorta
  3. unire manualmente le due versioni di file (albero di lavoro vs. spostato).

2
C'è un modo in cui posso evitare di dover mettere da parte le cose in futuro ... Vengo da SVN, e sembra così avanti ... devi solo aggiornare, risolvere i conflitti e poi eseguire il commit. Git non può essere così difficile, che devo aggiungere 2 passaggi nel ciclo. Grazie ancora!
Miguel Angelo

2
@Miguel: Stashing non è un ostacolo. È uno strumento aggiuntivo fornito da Git che ti consente di migliorare il tuo flusso di lavoro ed evitare conflitti e commit impuri. git-scm.com/docs/git-stash
Koraktor

8
Sebbene la risposta sia valida, non sono davvero sicuro che git sia "corretto" su questo. I file si trovano nel repository, quindi non c'è pericolo di perdita di dati. perché non applicare le modifiche? Vedi questo thread - git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html
studgeek

5
Penso che questa risposta non sia la più utile. git stashdovrebbe aiutare a eseguire rapidamente il backup delle modifiche locali. L'eliminazione manuale di una serie di file per ripristinarla interrompe il flusso. L' git stash branchapproccio nell'altra risposta suona meglio, ma comunque molto più manuale del desiderato.
bentolor

Questa risposta ha funzionato meglio per me quando nella stessa situazione. Dopo aver estratto la scorta, sono passato attraverso una fusione come mi sarei aspettato dall'inizio.
Billy Lazzaro

58

Il modo più sicuro e più semplice sarebbe probabilmente riporre di nuovo le cose:

git stash -u             # This will stash everything, including unstaged files
git stash pop stash@{1}  # This will apply your original stash

Successivamente, se sei soddisfatto del risultato, puoi chiamare

git stash drop

per rimuovere la tua scorta "sicura".


2
Grazie per questo, mi hai salvato da tanto dolore e sofferenza!
danjarvis

9
pop stash si applicherà e lascerà cadere la tua scorta originale. Solo per essere un uso sicuro applyinvece di pop.
Hilbrand Bouwkamp

2
In effetti popè una combinazione di applye drop, ma lo farà solo dropse funzionerà applysenza conflitti. Ma sì, di applysolito è più sicuro.
Koraktor

2
Ciò presuppone che non siano presenti altre modifiche nella directory di lavoro che si desidera mantenere. Per questa particolare domanda egli implica (ma non dice esplicitamente) che è in uno stato pulito, ma volevo farlo notare per gli altri che vengono qui con cambiamenti locali.
studgeek

1
Questo risolve il problema solo se i problemi in conflitto non sono stati commessi . Ricevi lo stesso identico messaggio quando sono stati impegnati (ad esempio con un checkout pulito) e quindi questo non cambierà nulla ...
Jasper

56

Come accennato da @bentolo, puoi eliminare manualmente i file di cui si lamenta, cambiare ramo e quindi aggiungerli di nuovo manualmente. Ma personalmente preferisco rimanere "all'interno di git".

Il modo migliore per farlo è convertire la scorta in un ramo. Una volta che è un ramo, puoi lavorare normalmente in git usando le normali tecniche / strumenti correlati ai rami che conosci e ami. Questa è in realtà una tecnica generale utile per lavorare con gli stash anche quando non si dispone dell'errore elencato. Funziona bene perché una scorta è davvero un impegno nascosto (vedi PS).

Conversione di una scorta in un ramo

Quanto segue crea un ramo basato su HEAD quando lo stash è stato creato e quindi applica lo stash (non lo esegue il commit).

git stash branch STASHBRANCH

Lavorare con il "ramo stash"

Quello che fai dopo dipende dalla relazione tra la scorta e dove si trova il tuo ramo di destinazione (che chiamerò ORIGINALBRANCH).

Opzione 1 - Rebase ramo stash normalmente (molte modifiche rispetto allo stash)

Se hai apportato molte modifiche al tuo ORIGINALBRANCH, probabilmente stai trattando meglio STASHBRANCH come qualsiasi filiale locale. Effettua il commit delle modifiche in STASHBRANCH, riformulalo su ORIGINALBRANCH, quindi passa a ORIGINALBRANCH e riassegna / unisci le modifiche STASHBRANCH su di esso. Se ci sono conflitti, gestiscili normalmente (uno dei vantaggi di questo approccio è che puoi vedere e risolvere i conflitti).

Opzione 2 - Reimposta il ramo originale in modo che corrisponda allo stash (modifiche limitate dallo stash)

Se ti sei semplicemente nascosto mantenendo alcune modifiche in fasi, poi hai eseguito il commit, e tutto ciò che vuoi fare è ottenere le modifiche aggiuntive che non erano state messe in scena quando hai nascosto, puoi fare quanto segue. Tornerà al ramo e all'indice originali senza modificare la copia di lavoro. Il risultato finale saranno le modifiche aggiuntive alla tua copia di lavoro.

git symbolic-ref HEAD refs/heads/ORIGINALBRANCH
git reset

sfondo

Gli stash sono commit come rami / tag (non patch)

PS, si è tentati di pensare a una scorta come una patch (proprio come si è tentati di pensare a un commit come una patch), ma una scorta è in realtà un commit contro l'HEAD quando è stata creata. Quando applichi / pop, stai facendo qualcosa di simile a selezionarlo con cura nel tuo ramo attuale. Tieni presente che rami e tag sono in realtà solo riferimenti a commit, quindi per molti versi stash, branch e tag sono solo modi diversi di puntare a un commit (e alla sua cronologia).

A volte è necessario anche quando non sono state apportate modifiche alla directory di lavoro

PPS, potresti aver bisogno di questa tecnica dopo aver usato stash con --patch e / o --include-untracked. Anche senza modificare le directory di lavoro, queste opzioni a volte possono creare una scorta che non puoi semplicemente applicare indietro. Devo ammettere di non capire appieno il motivo. Vedi http://git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html per qualche discussione.


5
Questa risposta dovrebbe essere contrassegnata come soluzione in quanto fornisce i suggerimenti più utili su come risolvere una "scorta bloccata" nel modo più efficace. Forse miglioralo menzionando prima la "soluzione di eliminazione semplice" e la soluzione del ramo come seconda opzione.
bentolor

8
"git stash branch STASHBRANCH" non sembra funzionare se ti trovi di fronte a questo scenario (esattamente lo stesso messaggio di errore si verifica con pop). Potrebbe essere necessario eseguire alcuni reset di git in anticipo.

+1 Mi sono ritrovato in un pasticcio di spaghetti con impegni, modifiche e scorte ecc. Ecc. Questo mi ha tirato fuori da tutto facendo esplodere la scorta in un ramo grazie studgeek
RobbZ

Grazie per il chiarimento su come le scorte non sono patch e su come sono legate alla TESTA (al momento dell'archiviazione). Questo ha molto senso. - Quindi ... suppongo che ci siano casi in cui è più flessibile / portatile / conveniente creare una patch piuttosto che una scorta (come hai detto: quando si hanno molte modifiche), in modo che possa essere applicata ovunque (ed è solo una questione di risoluzione dei conflitti). Forse git stash show -psta aiutando a fare scorta -> * patch *.
Kamafeather

39

La soluzione: è necessario eliminare il file in questione, quindi provare a memorizzare pop / applicare di nuovo e dovrebbe andare avanti. Non eliminare altri file, solo quelli menzionati dall'errore.

Il problema: Git a volte fa schifo. Quando è in esecuzione git stash -uinclude file non tracciati (fantastico!) Ma non rimuove quei file non tracciati e non sa come applicare i file non tracciati nascosti sopra gli avanzi (non bello!), Il che rende davvero l' -uopzione abbastanza inutile.


3
Avrei accettato questa risposta se fosse stata la mia domanda. Grazie @qwertzguy, la tua risposta ha risolto il mio problema,
Kobus Myburgh

Mi sono imbattuto nello stesso problema, git stash pop non si applicava fino a quando non ho eliminato i file in questione, quindi sono incappato in un conflitto con un file che ha causato il rifiuto della scorta. Ma piuttosto che rimuovere i file non git stash -u
tracciati

Cattivo consiglio se hai bisogno di parti da entrambe le versioni dei file interessati.
Walf

2
"non rimuove quei file non tracciati" ... e non li elenca in git stash show. Questa risposta ha fatto accendere la lampadina.
jsc

2
più uno per Git a volte fa schifo.
Harish,

29

Per applicare invece le differenze di codice nella scorta come una patch, utilizzare il seguente comando:

git stash show --patch | patch -p1

11
Di solito è meglio spiegare una soluzione invece di pubblicare solo alcune righe di codice anonimo. Puoi leggere Come scrivo una buona risposta e anche Spiegare risposte interamente basate su codice .
Massimiliano Kraus

Questo funziona per me poiché la patch di git stash show --patchnon contiene i file non tracciati.
Steven Shaw

Questa risposta mi ha aiutato molto dal momento che non sono stato in grado di aprire la mia scorta a causa di molti cambiamenti nel mio repository da quando la scorta era stata spinta.
Erik Finnman

1

Questo mi è successo numerose volte, ho nascosto file non tracciati con git stash -u quali finiscono per essere aggiunti al repository e non posso più applicare le modifiche nascoste.

Non sono riuscito a trovare un modo per forzare la git stash pop/applysostituzione dei file, quindi rimuovo prima le copie locali dei file non tracciati che erano nascosti ( fai attenzione perché cancellerà tutte le modifiche che non sono state salvate ) e poi applico le modifiche nascoste :

rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

Infine, io uso git status, git diffe altri strumenti per controllare e aggiungere nuovamente le parti dai file rimossi se c'è qualcosa che manca.


Se hai modifiche non salvate che desideri mantenere, puoi prima creare un commit temporaneo:

git add --all
git commit -m "dummy"
rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

Usa tutti gli strumenti adatti a te per unire le modifiche precedentemente salvate nei file locali e rimuovere il commit fittizio:

git reset HEAD~1

0

La mia operazione pop allo stesso modo bloccata è stata perché i file rimasti ignorati (vedere il file .gitignore). Lo stato di Git mi ha mostrato tracciato e non tracciato, ma le mie attività non hanno ripulito i file ignorati.

Dettagli: avevo usato git stash save -a, controllato il master per compilare e vedere il comportamento originale, quindi ho provato a rimettere tutto a posto per continuare a modificare. Quando ho controllato il mio ramo e ho cercato di aprire, i miei file ignorati erano ancora lì prima del salvataggio delle scorte. Questo perché il checkout del master ha interessato solo i file salvati, non ha cancellato i file ignorati. Quindi il pop non è riuscito, essenzialmente dicendo che non voleva ripristinare i miei file ignorati nascosti sopra i file che erano ancora lì. È un peccato che non sia riuscito a trovare un modo per avviare una sessione di unione con loro.

Alla fine, ho usato git clean -f -d -xper rimuovere i file ignorati. È interessante notare che, dei miei ~ 30, 4 file rimanevano ancora dopo la pulizia (sepolti nelle sottodirectory). Dovrò capire in quale categoria si trovano, che dovevano essere eliminati manualmente.

Poi mio padre è riuscito.



-1

Altra soluzione:

cd to/root/your/project

# Show what git will be remove
git clean -n

# If all is good
git clean -f

# If not all is good, see
git clean --help

# Finish
git stash pop

L'errore menzionato nella domanda è causato da un file che esiste sia nello stack che nella directory di lavoro. La pulizia lo risolve solo se questo file non è tracciato, il che non è certamente sempre il caso (e non il caso dell'OP, dato che ha ottenuto il file da un pull).
Xavier Poinas

-1

Con Git 2.14.x / 2.15 (Q3 2017), la soluzione di qwertzguy del 2014 non sarà più necessaria.

Prima del terzo trimestre del 2017, dovevi eliminare il file in questione, quindi provare a riporre / applicare di nuovo.
Con la prossima versione di Git, non dovrai farlo.

Vedere commit bbffd87 (11 agosto 2017) di Nicolas Morey-Chaisemartin ( nmorey) .
(Fuso da Junio ​​C Hamano - gitster- in commit 0ca2f32 , 23 agosto 2017)

stash: pulisce i file non tracciati prima del ripristino

Se si richiama git stash -uun repository che contiene un file che non viene più ignorato a causa di una modifica corrente del gitignorefile, questo file viene nascosto ma non rimosso dall'albero di lavoro.
Ciò è dovuto alla git-stashprima esecuzione di un reset --hardcomando che cancella la .gitignoremodifica del file e quindi alla chiamata git clean, lasciando il file intatto.
Ciò causa un git stash poperrore a causa del file esistente .

Questa patch cambia semplicemente l'ordine tra pulizia e ripristino e aggiunge un test per questo caso d'uso.


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.