2012-02-04 18 views
45

Questa è una pipeline sul ramo frontend nelle ultime due settimane.Come combinare più stash in git

| [email protected]{3} è tutto il codice dal [email protected]{1} (esclusi i due piccoli commit)
| Tiny Commit
| Tiny commit
| Il grosso ingaggio si è impegnato due settimane fa, ora è stato ridefinito e spostato a [email protected]{1}

Il mio albero di lavoro è attualmente pulito.
[email protected]{1} è il contenuto di un commit in blocco di codice di sviluppo generale due settimane fa (questo dovrebbe essere stato nascosto in primo luogo). Questo commit è stato annullato e spostato in stash.
[email protected]{3} è il lavoro più recente su quell'albero dal [email protected]{1} (meno un paio di modifiche che sono state commesse).

Ho bisogno di combinare questi due pacchetti insieme nel mio albero di lavoro in modo da poter fare una serie di commit da questo enorme bacino di lavoro.

ho corse git stash apply [email protected]{1} poi ho provato:

git stash apply [email protected]{3}
git stash show -p | git stash apply [email protected]{3}

ma ottengo 'albero di lavoro sporco' in entrambi i casi. Come posso unire questo lavoro insieme? Perché [email protected]{3} è più recente, voglio sostituirlo a [email protected]{1} ovunque ci siano conflitti.

risposta

35

È possibile applicare una scorta se non ci sono conflitti con i file modificati nell'albero di lavoro, quindi, in primo luogo, assicurarsi che non vi siano file modificati in git status, se ce ne sono, confermarli. Quindi:

git stash apply [email protected]{1} 
git commit -a 
# Enter your commit message 
git stash apply [email protected]{3} 

Quindi è possibile effettuare un nuovo commit o modificare quello precedente per combinarli. Potrebbe essere necessario risolvere i conflitti di fusione dopo ogni applicazione.

Inoltre, se si decidesse di utilizzare git stash pop piuttosto che apply, notare che [email protected]{3} sarebbe diventato [email protected]{2} dal momento che il primo è stato spuntato fuori.

+0

I due nascondigli sono grandi e contengono un sacco di lavoro si sovrappongono, che è il motivo per cui ho voluto evitare i commit. È possibile combinarli semplicemente nell'albero di lavoro, o sono obbligato a commettere questi grossi pezzi e quindi combinare 2 commit di merda e dividerli in ~ 10 buoni commit in vim? – sscirrus

+0

L'altra cosa è: _Non voglio impegnare tutto questo codice_. Pezzi significativi di esso sono ancora solo per lo sviluppo. – sscirrus

+7

Qual è la differenza tra combinarli nell'albero di lavoro e modificare? O facendo un 'git reset HEAD ^' dopo l'applicazione del secondo stash? Non è possibile applicare una scorta su un albero di lavoro sporco, quindi è necessario * commit * prima di applicarne uno, ma ciò non significa che non è possibile annullare quel commit dopo averlo applicato. –

2

Ho avuto un problema simile e l'ho risolto in questo modo.

Utilizzare git stash pop per applicare una delle finestre. Quindi creare una patch di questa scorta con git diff -p > ../stash.diff. È quindi possibile ripristinare la struttura di lavoro (o riporre di nuovo le modifiche) e inserire l'altra sequenza con git stash pop [email protected]{1}. Se si applica la patch in questo momento è possibile 'unire' le due diverse.

Probabilmente avrete alcuni conflitti da risolvere. Se tutto va bene, puoi quindi eliminare le modifiche nascoste.

+0

Oppure basta tirare lo stash @ {1} come diff e applicarlo localmente (ad esempio la risposta e i commenti di siride) ma anche questo funziona, grazie! – rogerdpack

9

Un modo migliore è utilizzare solo git stash show -p [email protected]{whatever} > stash-{whatever}.diff e quindi utilizzare git apply per ognuno.

+0

Questo è di gran lunga il più semplice se le modifiche non si sovrappongono. Mi sento sciocco dover fare commit solo per unire il contenuto. –

+1

@MarceloDiniz: deve esserci sempre un commit se il contenuto cambia. Non è affatto sciocco. – siride

+0

L'applicazione di una patch come patch funzionerà se la memoria è abbastanza banale ma non funzionerà se ci sono state modifiche intermedie o non banali dello spazio bianco o cambiamenti nei percorsi dei file – Kirby

74

E 'un po' coinvolto, ma questo funziona quasi sempre:

  1. Pop la prima scorta

    $ git stash pop 
    
  2. temporaneamente il commit delle modifiche dalla prima scorta

    $ git add . && git commit -am 'WIP' 
    
  3. Pop il secondo stash

    $ git stash pop 
    
  4. Annulla l'temporanea commit, mantenendo i cambiamenti che ha introdotto

    $ git reset --soft HEAD^ 
    
+4

Mi ci è voluto un po 'per apprezzare la bellezza di questo. Funziona molto meglio di provare ad applicare una patch, che spesso fallisce a causa di cambiamenti di spazio o file. – Kirby

+0

Non dimenticare di reimpostare il file dopo di esso per vedere la modifica unificata in 'git diff', perché al momento la modifica viene resettata e visto separatamente come 'git diff --staged'. – Nakilon

+0

Questa sembra la soluzione migliore, ma non riesco ancora a capire perché non possiamo semplicemente inserire una sequenza esistente mentre abbiamo modifiche non previste. Ad esempio, sarebbe bello semplicemente eseguire 'git stash pop' seguito da' git stash pop'. Forse mi manca qualcosa sugli interni di git stash. – modulitos