2015-07-23 15 views
7

Stavo lavorando su una vasta serie di modifiche a un codice base. Alcuni dei cambiamenti erano stati messi in scena e altri no. Avevo bisogno di passare a un altro ramo, ma non ero pronto per eseguire un commit, quindi ho nascosto il mio stato corrente usando git stash.Git stash con file staged. Stash converte i file staged convertiti in nonstage?

Successivamente, sono andato a applicare la mia scorta con, git stash apply. Quindi ho eseguito git status. Ho notato che i miei cambiamenti graduali non sono più visualizzati come "messi in scena", e invece sembrano essere inclusi come "Modifiche non messe in scena per il commit". Ho ragione nella mia comprensione del fatto che nessun dato è stato effettivamente perso, ma i dati "messi in scena" ora sono semplicemente convertiti in dati "non"?

MODIFICA: Devo aggiungere che alcuni dei file in questione erano versioni a fasi e versioni nonstate al momento della memorizzazione. Ad esempio, il file A ha apportato alcune modifiche, che sono state organizzate. Quindi, sono state apportate alcune modifiche al file A, che non era ancora stato messo in scena. Quindi, è stata creata una scorta.

risposta

9

La risposta alla domanda come chiesto ("fa scorta convertito in scena i file non è stato classificato") è sì e no.

Se hai applicato con git stash apply (vs git stash pop), sei in ottima forma perché lo stash è ancora presente. Ma torniamo un po 'indietro e guardiamo al meccanismo sottostante, dato che conta qui.

Quando si esegue git stash save (o semplice git stash che fa un save), git fa due commit che non sono su ogni ramo. Un commit mantiene lo stato dell'indice, cioè qualsiasi cosa tu abbia messo in scena. Il secondo commit mantiene lo stato dell'albero di lavoro, cioè tutto il resto.

Più tardi, quando si utilizza git stash apply, git smushes i cambiamenti insieme in modo che nulla è messo in scena, a meno si aggiunge --index all'operazione apply, nel qual caso si ripristina (se possibile) il vostro accordo precedente messo in scena vs non messo in scena.

Quando si utilizza apply, lo script scorta mantiene la scorta impegna intorno come bene, quindi se l'applicazione non va il modo in cui si voleva, tra cui se avete dimenticato --index o errata (vedi nota 2): l'utente può git reset --hard (presumendo che tu avessi tutto in uno stato pulito quando hai iniziato, comunque) e rifai lo apply.

Se hai usato pop, però, e git pensa che l'applicazione ha funzionato, quindi lascia la scorta. In genere raccomando di usare apply e drop separati solo per questo motivo.


Con -u o -a, che non salva solo messo in scena e file unstaged intestano anche ignorato e/o tutti i file, lo script scorta rende tre commit. Senza questi flag, tuttavia, questi file non entrano in nessuna parte della memoria.

Confusamente, lo script scorta ha anche una bandiera --keep-index, che consente di specificare per apply operazioni, ma non ha alcun significato lì. Invece, --keep-index influisce su cosa fa stash dopo aver eseguito il commit speciale. Occasionalmente ho fatto accidentalmente git stash apply --keep-index invece di git stash apply --index, dopo aver mescolato le due opzioni.

+1

Grazie per la risposta dettagliata torek. Ora ho una migliore comprensione di cosa sta succedendo. –

2

Sì, il tuo pensiero è corretto. E 'descritto nelle seguenti sezioni del man git-stash:

Use git stash when you want to record the current state of the working 
directory and the index, but want to go back to a clean working 
directory. The command saves your local modifications away and reverts 
the working directory to match the HEAD commit. 

(...) 

pop [--index] [-q|--quiet] [<stash>] Remove a single stashed 
      state from the stash list and apply it on top of the 
      current working tree state, i.e., do the inverse operation 
      of git stash save. The working directory must match the 
      index. 

      (...) 

      If the --index option is used, then tries to reinstate not 
      only the working tree’s changes, but also the index’s 
      ones. 

(...) 

apply [--index] [-q|--quiet] [<stash>] 
      Like pop, but do not remove the state from the stash list. 
2

NO, sono andati perduti nessuna modifica.

Acc. a documentation:

Git modifica nuovamente i file non salvati quando si è salvato lo stash. In questo caso, hai avuto una directory di lavoro pulita quando hai provato ad applicare lo stash e hai provato ad applicarlo sullo stesso ramo da cui lo hai salvato; ma avere una directory di lavoro pulita e applicarla sullo stesso ramo non è necessario per applicare correttamente una scorta. È possibile salvare una scorta su un ramo, passare a un altro ramo in un secondo momento e provare a riapplicare le modifiche. Puoi anche avere file modificati e senza commit nella tua directory di lavoro quando applichi una scorta - Git ti dà conflitti di fusione se qualcosa non funziona più correttamente.

Le modifiche ai file sono state applicate nuovamente, ma il file che è stato messo in scena prima non è stato ripristinato. Per fare ciò, è necessario eseguire il git stash, applicare il comando con un'opzione --index per dire al comando di provare a riapplicare le modifiche graduali. Se tu avessi eseguire che invece, avreste ottenuto tornare alla posizione originale:

$ git stash apply --index 
# On branch master 
# Changes to be committed: 
# (use "git reset HEAD <file>..." to unstage) 
# 
#  modified: index.html 
# 
# Changes not staged for commit: 
# (use "git add <file>..." to update what will be committed) 
# 
#  modified: lib/simplegit.rb 
# 
+0

Grazie Pankaj. L'ho letto, ma non ero sicuro di averlo capito perfettamente. Grazie per la conferma. –