git stash -> unisce le modifiche nascoste alle modifiche correnti


187

Ho apportato alcune modifiche al mio ramo e mi sono reso conto che avevo dimenticato di aver nascosto alcune altre modifiche necessarie a quel ramo. Quello che voglio è un modo per unire le mie modifiche nascoste alle modifiche correnti.

C'è un modo per fare questo?

È più per comodità, alla fine ho rinunciato e impegnato prima i miei cambiamenti attuali, poi i miei cambiamenti nascosti, ma avrei preferito farli entrare in un colpo solo.


Probabilmente il duplicato della stackoverflow.com/q/1360712/72178
ks1322

La risposta di Giosuè dovrebbe essere la risposta accettata. Questo post di StackOverflow è il primo link di Google per questa domanda, dai la risposta giusta a Internet!
Jérôme,

Risposte:


272

Ho appena scoperto che se le tue modifiche non confermate vengono aggiunte all'indice (cioè "messe in scena", usando git add ...), allora git stash apply(e, presumibilmente, git stash pop) si fonderanno effettivamente. Se non ci sono conflitti, sei d'oro. In caso contrario, risolverli come al solito con git mergetoolo manualmente con un editor.

Per essere chiari, questo è il processo di cui sto parlando:

mkdir test-repo && cd test-repo && git init
echo test > test.txt
git add test.txt && git commit -m "Initial version"

# here's the interesting part:

# make a local change and stash it:
echo test2 > test.txt
git stash

# make a different local change:
echo test3 > test.txt

# try to apply the previous changes:
git stash apply
# git complains "Cannot apply to a dirty working tree, please stage your changes"

# add "test3" changes to the index, then re-try the stash:
git add test.txt
git stash apply
# git says: "Auto-merging test.txt"
# git says: "CONFLICT (content): Merge conflict in test.txt"

... che è probabilmente quello che stai cercando.


tl; dr

Esegui per git addprimo.


8
Un tale hack, ma ehi, funziona e sembra essere l'unico modo per farlo. Vorrei che ci fosse git stash apply --forceo qualcosa del genere.
Matt Kantor,

13
In realtà, non è un hack: è un miglioramento rispetto a ciò che desideri, poiché puoi facilmente ripristinare le modifiche all'indice.
hoffmanc,

2
Wow, questo comportamento è davvero inteso da git?
edi9999,

9
Non penso che ci sia mai qualcosa di "inteso" da Git. Il mio sospetto è ormai che qualsiasi cosa git lo faccia per caso.
Profpatsch,

5
Questa è la soluzione perfetta. Ho appena fatto git add ., git stash applyquindi git resetapplicare la scorta ai miei cambiamenti di lavoro e unirmi senza dover impegnare.
Stephen Smith

70

In esecuzione git stash popo git stash applyè essenzialmente un'unione. Non avresti dovuto eseguire il commit delle modifiche correnti a meno che i file modificati nello stash non vengano modificati anche nella copia di lavoro, nel qual caso avresti visto questo messaggio di errore:

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

In tal caso, non è possibile applicare lo stash alle modifiche correnti in un solo passaggio. È possibile eseguire il commit delle modifiche, applicare nuovamente lo stash, eseguire nuovamente il commit e annullare quei due commit utilizzando git rebasese in realtà non si desidera eseguire due commit, ma potrebbe essere più un problema che valga la pena.


1
Ho ricevuto quel messaggio - le modifiche non sono in conflitto ma condividono gli stessi file, usando in giro stash / apply's?
Bemis,

1
Scusate, questo è ciò che intendevo per "unire conflitti", ma quella era una scelta sbagliata. Penso che il messaggio di errore sia piuttosto definitivo: se i file modificati nella copia di lavoro vengono modificati anche nello stash, non è possibile applicare lo stash. Ho aggiornato la mia risposta con una possibile soluzione alternativa.
Brandan,

3
Non la considero una risposta in tutti i casi. Potresti aver nascosto solo una parte di una serie di modifiche in un file specifico perché volevi testare qualcosa durante lo sviluppo. E potresti non voler impegnare il contenuto corrente del file in questo momento (o per niente) in quanto è WIP. È un vero problema con Git che i cambiamenti nascosti non possono essere uniti nel tuo ramo attuale
Thomas Watson,

21
La risposta di Joshua Warner dovrebbe essere quella contrassegnata come corretta. Per unire una scorta, mettere in scena le modifiche, applicare la scorta, gestire eventuali conflitti e quindi (se lo si desidera) mettere in scena le modifiche.
Vroo,

4
"Puoi eseguire il commit delle modifiche, applicare lo stash, eseguire nuovamente il commit e schiacciare quei due commit usando git rebase se davvero non vuoi due commit, ma potrebbe essere più un problema che valga la pena." Invece di questo puoi fare: eseguire il commit delle modifiche, applicare lo stash e quindi git commit --amend.
gabella

27

Quello che voglio è un modo per unire le mie modifiche nascoste alle modifiche correnti

Ecco un'altra opzione per farlo:

git stash show -p|git apply
git stash drop

git stash show -pmostrerà la patch dell'ultima scorta salvata. git applylo applicherà. Al termine dell'unione, è possibile eliminare lo stash unito git stash drop.


1
Grazie per questo - non so perché git stash popnon lo faccia solo nei casi in cui l'unione si applica in modo pulito ...
Iguananaut

Versione estesa: git stash show -p --no-color | git apply --3way( --3way= fallback sull'unione a 3 vie se la patch fallisce).
DmitrySandalov il

Ma git stash show -pcrea una differenza tra il contenuto nascosto e il commit indietro quando la voce di scorta è stata creata per la prima volta . Quindi questo sovrascriverebbe le modifiche al file di lavoro fatte dall'OP.
Paul F. Wood,

Perché sovrascrivere? Il diff prodotto con git stash show -pverrà unito da git apply, se è possibile fare a meno dei conflitti.
ks1322,

1

Il modo in cui lo faccio è git addprima di tutto questo git stash apply <stash code>. È il modo più semplice.


4
In che modo questa non è una copia esatta del testo della risposta accettata?
Romain Valeri

0

Come suggerito da @Brandan, ecco cosa dovevo fare per spostarmi

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

Segui questo processo:

git status  # local changes to `file`
git stash list  # further changes to `file` we want to merge
git commit -m "WIP" file
git stash pop
git commit -m "WIP2" file
git rebase -i HEAD^^  # I always use interactive rebase -- I'm sure you could do this in a single command with the simplicity of this process -- basically squash HEAD into HEAD^
# mark the second commit to squash into the first using your EDITOR
git reset HEAD^

E rimarrai con le modifiche locali completamente unite file, pronte a fare ulteriore lavoro / pulizia o fare un unico buon impegno. Oppure, se sai che i contenuti uniti di filesaranno corretti, potresti scrivere un messaggio appropriato e saltare git reset HEAD^.


0

Può essere, non è la peggior idea di unire (via difftool) da ... sì ... un ramo!

> current_branch=$(git status | head -n1 | cut -d' ' -f3)
> stash_branch="$current_branch-stash-$(date +%yy%mm%dd-%Hh%M)"
> git stash branch $stash_branch
> git checkout $current_branch
> git difftool $stash_branch

0

puoi facilmente

  1. Impegna le tue attuali modifiche
  2. Decomprimi la scorta e risolvi i conflitti
  3. Effettua modifiche dalla scorta
  4. Soft reset da cui provieni il commit (ultimo commit corretto)

-1

Un'altra opzione è quella di fare un'altra "git stash" delle modifiche locali senza commit, quindi combinare le due stash git. Sfortunatamente git sembra non avere un modo per combinare facilmente due blocchi. Quindi un'opzione è quella di creare due file .diff e applicarli entrambi - per non dire che non è un commit extra e non comporta un processo in dieci passaggi: |

come: https://stackoverflow.com/a/9658688/32453


Trasforma il problema di applicare un diff in un problema di applicare due diff. Inoltre, la soluzione accettata non implica un commit, solo una fase ed è solo un singolo comando (git add). (Non sono il downvoter.)
Eike

Almeno per me sembra più semplice, meno magia voodoo ... evviva!
rogerdpack
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.