Annullamento accidentale git stash pop


186

Ho nascosto alcune modifiche locali prima di fare una fusione complicata, ho fatto la fusione, poi ho stupidamente dimenticato di impegnarmi prima di correre git stash pop. Il pop ha creato alcuni problemi (chiamate di metodo errate in una grande base di codice) che si stanno rivelando difficili da rintracciare. Ho corso git stash show, quindi so almeno quali file sono stati modificati. Se non altro, suppongo che questa sia una lezione per impegnarsi di più.

La mia domanda: è possibile annullare lo stash pop senza annullare anche l'unione?


2
Non dovresti essere autorizzato a farlo git stash popsenza impegnarti prima. Cosa hai fatto per raggiungerlo?
Chris Jester-Young,

Non sono sicuro di essere onesto (questo era ieri). La fusione non si è impegnata da sola perché c'erano conflitti. Sono stato in qualche modo in grado di eseguire stash pop dopo quello.
nren

1
L'ho fatto solo per sapere usando la versione 1.7.9.msysgit.0 di git. Avevo file non messi in scena e il pop stash ha appena unito tutto.
PandaWood,

Sono stato in grado di eseguire git stash popdopo la messa in scena delle modifiche (non mi sono impegnato però) con la versione 2.25.0.windows.1 di git
Artem Hevorhian

Se hai indicizzato le modifiche e le hai perse mentre correvi stash pop/applyprima di effettuare un commit, puoi sparare git fsck --lost-found. Questo comando eseguirà l'iterazione attraverso i BLOB penzolanti (file effettivi per coloro che non hanno familiarità con la terminologia git) che sono stati messi in scena ma non impegnati da nessuna parte (quindi penzolanti) e li metterà nella directory .git / lost-found / , dove è possibile git showvisualizzarli e vedere se questi sono i file che stai cercando.
Artem Hevorhian,

Risposte:


69

Prova a utilizzare Come recuperare una scorta rilasciata in Git? per trovare la scorta che hai spuntato. Penso che ci siano sempre due commit per uno stash, dal momento che preserva l'indice e la copia di lavoro (così spesso il commit dell'indice sarà vuoto). Quindi git showli vedono il diff e li usano patch -Rper non applicarli.


6
Wow, ha funzionato. Sono stato in grado di trovare gli stash con commit git fsck --no-reflog | awk '/dangling commit/ {print $3}'(dal link) e ho appena trovato manualmente il problema da quel diff. Grazie!
nren

1
il fsck emette un elenco enorme. È noioso esibire tutti gli SHA1 là fuori. Come fai a fare questo ?
meson10

5
@ meson10: Sfortunatamente gli stash sono tenuti in un reflog, il che sarebbe il modo ovvio (se fossero un vero ramo) di guardare alla storia degli stash spuntati. Consentitemi anche di suggerire che una valutazione negativa + richiesta di aiuto non è la strategia migliore.
Ben Jackson,

2
Mi ci è voluto un po 'di manomissione per farlo bene. Ecco il risultato del mio lavoro git diff -p ${STACH_SHA1}~1 ${STASH_SHA1} | patch -R -p1:; Ho provato git showcome suggerito ma il suo output non era buono per la patch; inoltre ho dovuto fornire l' -p1opzione di patch per eliminare l' elemento a/..e b/..che git diffmette davanti ai file altrimenti non risolverebbe i percorsi dalla radice del repository. SUGGERIMENTO: sii cauto e commetti il ​​disordine in un ramo separato prima di giocare con la patch.
basilikode,

@BenJackson Nella tua risposta "sempre" significa entrambi stash pope stash pushattiverà un commit che salverebbe le modifiche all'indice e alla directory di lavoro, giusto?
Artem Hevorhian,

36

A partire dal git stash --help

Recovering stashes that were cleared/dropped erroneously
   If you mistakenly drop or clear stashes, they cannot be recovered through the normal safety mechanisms. However, you can try the
   following incantation to get a list of stashes that are still in your repository, but not reachable any more:

       git fsck --unreachable |
       grep commit | cut -d\  -f3 |
       xargs git log --merges --no-walk --grep=WIP

Questo mi ha aiutato meglio della risposta accettata con lo stesso scenario.


13
Si noti che molte soluzioni che prevedono la ricerca di "WIP" si basano sui messaggi predefiniti. Se dai messaggi espliciti agli stash, questi potrebbero non contenere WIP.
Ben Jackson,

Grazie. Ho aggiunto l'opzione --oneline al comando log per migliorare la leggibilità.
basslo

Questo ti aiuta solo a trovare lo SHA del commit stash. Ma se integrato con il commento @basilikode della risposta accettata (git diff SHA ~ 1 SHA | patch -R), funziona benissimo. Raccomando di usare path --dry-run prima per verificare.
Jarek C

3

Se la tua unione non fosse troppo complicata, un'altra opzione sarebbe:

  1. Sposta tutte le modifiche tra cui le modifiche di unione nuovamente allo stash usando "git stash"
  2. Eseguire nuovamente l'unione e confermare le modifiche (senza le modifiche dalla scorta rilasciata)
  3. Esegui un "git stash pop" che dovrebbe ignorare tutte le modifiche dalla tua unione precedente poiché i file ora sono identici.

Dopo di che ti rimangono solo le modifiche dalla scorta che hai lasciato cadere troppo presto.

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.