2015-01-28 22 views
17

ho una serie di file in una scorta (stash{0}) e vorrei git applysolo alcune parti/grossi pezzi di questi file (comunemente noto come modalità Interattiva).'git scorta applicare' con modalità interattiva

È possibile?

ho visto che è possibile eseguire un

git stash save -p 'Stash name' 

ma non sembra possibile fare

git stash apply -p 'Stash name' 

Sai un modo per raggiungerlo?

risposta

19

È possibile?

Sì, lo è!

git checkout -p [email protected]{0} 

Dove è possibile sostituire il 0 in [email protected]{0} con l'indice della scorta che si desidera applicare.

Utilizzare git stash list e git show -p [email protected]{n} se non è sicuro quale n è lo stash che si desidera applicare.

Non dimenticarti di git stash drop [email protected]{n} quando sai che non hai più bisogno di quella scorta, dal momento che git checkout ovviamente non farà cadere la scorta per te.

Perché funziona?

La chiave è capire che gli stash sono, in pratica, references a commits, proprio come tag e rami.

Infatti, sono memorizzati in .git/refs/stash, una riga per hash stash.

Avvertenze

Come @mgadda menzionati int commenti qui sotto, git checkout -p cerca di applicare tutta la differenza tra un impegno e di lavoro corrente.

Nel caso di una scorta git, se la scorta si sta cercando di applicare è stato fatto nei confronti di un diverso commit, quindi git checkout -p [email protected]{n} cercherà di applicare in modo interattivo tutte le differenze tra le [email protected]{n}e tutto è genitore commette e la corrente spazio di lavoro.

Ad esempio, se si sta cercando di applicare una scorta che è stato salvato "molti commit fa," nello spazio di lavoro corrente, git checkout -p [email protected]{n} cercherà di applicare non solo i cambiamenti nella scorta adeguata, ma cercherà anche di revert tutte le modifiche avvenute tra il commit su cui si basa lo stash e il commit corrente.

Allo stesso modo, se si sta tentando di applicare una memoria "dal futuro", ad esempio in un ramo che è un numero di commit prima del commit su cui è basata la memoria, allora git checkout -p [email protected]{n} tenterà di applicare anche tutti le altre modifiche che si sono verificate tra il commit corrente e il commit dal futuro, oltre alle modifiche dallo stash stesso.

(Nel caso vi stiate chiedendo, git checkout -p [email protected]{n} una scorta da un ramo parallelo cercherà di annullare tutte le modifiche tra la corrente commettono e il punto di diramazione originale e applicano anche tutte le modifiche tra il punto di diramazione e l'altro ramo, oltre al cambio nella scorta).

Ci sono un paio di soluzioni alternative, nessuno di loro perfetti sono perfetti per ogni situazione:

  1. essere molto attenti con le patch si accetta quando si fanno git checkout -p [email protected]{n}

  2. fare un git stash pop, poi git stash di nuovo prima di fare git checkout -p .... Ma se volessi fare una parziale applicazione della tua scorta per evitare conflitti, questo non sarebbe di grande aiuto.

  3. Se si dispone di uno strumento di diff grafica supportata da git (come meld), è possibile utilizzare git difftool e "sinistra" si applicano tutte le modifiche che ti interessa.

+0

Qui c'è un avvertimento che deve essere menzionato: poiché le operazioni di stash sono solo commit, significa che hanno anche commit padre che non sono garantiti per essere lo stesso commit padre di quello a cui si desidera applicare le modifiche interattive. Regola empirica: se si nascondono da altri commit rispetto al commit attualmente estratto, questa tecnica non farà ciò che si aspetta. Soluzione: applica l'intero set di modifiche dalla tua scorta (con git stash pop), quindi riponi di nuovo (git stash). Ora puoi fare il checkout -p come desideri. – mgadda

+0

@mgadda, grazie. Ho aggiunto una sezione "avvertimenti". – LeoRochael

1

Non penso che ci sia un modo per applicare le modifiche in hunks (o anche in file). Dovrai applicare la scorta, quindi memorizzare le modifiche che non vuoi interattivamente (con git stash save -p). Se sei preoccupato per i conflitti, puoi prima sistemare qualsiasi modifica non vincolante, applicare la tua scorta, mettere da parte qualsiasi hunk in conflitto e quindi applicare l'altra scorta.

+0

Sì, mi sto chiedendo principalmente perché voglio evitare i conflitti. Lo scopo è quello di ottenere alcune modifiche da (diciamo) * branch_A * ed essere in grado di metterle su * branch_B *, essendo in grado di evitare direttamente i conflitti che questi due rami potrebbero avere. La tua soluzione funziona, ma è esattamente il modo "complicato" che volevo evitare ;-P – Kamafeather

+0

L'approccio inverso, al solo 'git stash save' interattivo i blocchi che * voglio * e poi ripristinarlo sul ramo desiderato, invece di 'git stash apply 'interattivamente i blocchi che * voglio *, sembra l'approccio migliore. – Kamafeather