Come posso ripristinare tutte le modifiche locali nel progetto gestito da Git allo stato precedente?


1914

Ho un progetto in cui ho corso git init. Dopo diversi impegni, ho fatto ciò git statusche mi diceva che tutto era aggiornato e non c'erano cambiamenti locali.

Quindi ho apportato diverse modifiche consecutive e ho capito che volevo buttare via tutto e tornare al mio stato originale. Questo comando lo farà per me?

git reset --hard HEAD

Risposte:


3390

Se si desidera ripristinare le modifiche apportate alla copia di lavoro, procedere come segue:

git checkout .

Se si desidera ripristinare le modifiche apportate all'indice (ovvero, che sono state aggiunte), procedere come segue. Attenzione, questo resetterà tutti i tuoi commit non spremuti da padroneggiare! :

git reset

Se desideri annullare una modifica che hai eseguito, procedi come segue:

git revert <commit 1> <commit 2>

Se si desidera rimuovere file non tracciati (ad es. Nuovi file, file generati):

git clean -f

O directory non tracciate (ad es. Directory nuove o generate automaticamente):

git clean -fd

133
dopo così tanto tempo, git checkout path/to/filele modifiche locali verranno ripristinate inpath/to/file
Matijs il

29
+1 sulle risposte di seguito menzionano anche git clean -f (per rimuovere le modifiche non tracciate) e -fd (per rimuovere anche le directory non
tracciate

3
e se si vuole anche di pulire i file non monitorate, leggere questo stackoverflow.com/questions/61212/...
Surasin Tancharoen

9
git checkout .e git reset [--hard HEAD]non ha funzionato, ho dovuto fare un git clean -fdper ripristinare le mie modifiche.
BrainSlugs83

7
git resetnon reimposta le modifiche, lo git reset --hardfa.
Cerin,

388

Nota: potresti anche voler eseguire

git clean -fd

come

git reset --hard

sarà non rimuovere i file non monitorate, dove, come git-pulito consente di eliminare ogni file dalla directory principale cingolato che non sono sotto il monitoraggio git. ATTENZIONE: ATTENZIONE A QUESTO! È utile eseguire prima un ciclo a secco con git-clean, per vedere cosa verrà eliminato.

Ciò è particolarmente utile quando viene visualizzato il messaggio di errore

~"performing this command will cause an un-tracked file to be overwritten"

Il che può accadere quando si fanno diverse cose, una è l'aggiornamento di una copia funzionante quando tu e il tuo amico avete entrambi aggiunto un nuovo file con lo stesso nome, ma lo ha prima impegnato nel controllo del codice sorgente e non ti interessa cancellare la tua copia non tracciata .

In questa situazione, anche una corsa a secco ti aiuterà a mostrare un elenco di file che verrebbero sovrascritti.


13
Il comando file clean è "git clean -f". Le directory non tracciate vengono rimosse con "git clean -d"
Jonathan Mitchell,

35
git clean -fd (è richiesta la forza per -d)
electblake

14
-n o --dry-run sono i flag per dry-run.
stephenbez,

2
git clean -ffd se hai un altro repository git nel tuo repository git. Senza la doppia f non verrebbe rimosso.
Trismegistos,

149

Re-clone

GIT=$(git rev-parse --show-toplevel)
cd $GIT/..
rm -rf $GIT
git clone ...
  • ✅ Elimina i commit locali senza push
  • ✅ Ripristina le modifiche apportate ai file monitorati
  • ✅ Ripristina i file tracciati che hai eliminato
  • ✅ Elimina i file / le directory elencati in .gitignore(come i file di build)
  • ✅ Elimina i file / le directory che non sono tracciati e non presenti .gitignore
  • 😀 Non dimenticherai questo approccio
  • 😔 Riduzione della larghezza di banda

Di seguito sono riportati altri comandi che dimentico ogni giorno.

Pulisci e ripristina

git clean --force -d -x
git reset --hard
  • ❌ Elimina i commit locali senza push
  • ✅ Ripristina le modifiche apportate ai file monitorati
  • ✅ Ripristina i file tracciati che hai eliminato
  • ✅ Elimina i file / le directory elencati in .gitignore(come i file di build)
  • ✅ Elimina i file / le directory che non sono tracciati e non presenti .gitignore

Pulito

git clean --force -d -x
  • ❌ Elimina i commit locali senza push
  • ❌ Ripristina le modifiche apportate ai file monitorati
  • ❌ Ripristina i file tracciati che hai eliminato
  • ✅ Elimina i file / le directory elencati in .gitignore(come i file di build)
  • ✅ Elimina i file / le directory che non sono tracciati e non presenti .gitignore

Ripristina

git reset --hard
  • ❌ Elimina i commit locali senza push
  • ✅ Ripristina le modifiche apportate ai file monitorati
  • ✅ Ripristina i file tracciati che hai eliminato
  • ❌ Elimina i file / le directory elencati in .gitignore(come i file di build)
  • ❌ Elimina i file / le directory che non sono tracciati e non presenti .gitignore

Appunti

Caso di prova per confermare tutto quanto sopra (usare bash o sh):

mkdir project
cd project
git init
echo '*.built' > .gitignore
echo 'CODE' > a.sourceCode
mkdir b
echo 'CODE' > b/b.sourceCode
cp -r b c
git add .
git commit -m 'Initial checkin'
echo 'NEW FEATURE' >> a.sourceCode
cp a.sourceCode a.built
rm -rf c
echo 'CODE' > 'd.sourceCode'

Guarda anche

  • git revert per effettuare nuovi commit che annullano i commit precedenti
  • git checkout per tornare indietro nel tempo a precedenti commit (potrebbe essere necessario eseguire prima i comandi sopra)
  • git stashcome git resetsopra, ma puoi annullarlo

Ci scusiamo per il furto dalle risposte sopra. Uso costantemente questo riferimento, pubblicando principalmente per me.
William Entriken,

1
Sono abbastanza sicuro che la prima opzione ( Re-clone ) effettivamente "elimina i commit locali e non spinti" :)
Marandil

1
@styfle ✅ è qualcosa che fa, ❌ è qualcosa che non fa
William Entriken,

3
@FullDecent È un po 'confuso leggere. "❌ NON elimina i commit locali, senza push". Ciò significa che NON viene eliminato. Il doppio negativo significa che cancella?
styfle

1
Informazioni sul flag -x in git clean -f -d -x: se si specifica l'opzione -x, vengono rimossi anche i file ignorati. Questo, ad esempio, può essere utile per rimuovere tutti i prodotti di build.- dai documenti GIT
Alex

82

Se desideri annullare tutte le modifiche ed essere aggiornato con l'attuale master remoto (ad esempio, scopri che il HEAD principale si è spostato in avanti da quando ti sei ramificato e la tua spinta è stata "rifiutata") puoi usare

git fetch  # will fetch the latest changes on the remote
git reset --hard origin/master # will set your local branch to match the representation of the remote just pulled down.

Sembra importante specificare originin git reset --hard origin/master(che funziona) - senza di esso (ovvero git reset --hard) nulla sembra essere cambiato.
Jake,

Ho avuto alcune modifiche locali e non sono riuscito a liberarmene con qualsiasi comando che ho fatto resettare --hard origin / master ed è stato in grado di estrarre anche le modifiche del master
abhishek ringsia

50

Guarda in git-reflog. Elencherà tutti gli stati che ricorda (il valore predefinito è 30 giorni) e puoi semplicemente verificare quello che desideri. Per esempio:

$ git init > /dev/null
$ touch a
$ git add .
$ git commit -m"Add file a" > /dev/null
$ echo 'foo' >> a
$ git commit -a -m"Append foo to a" > /dev/null
$ for i in b c d e; do echo $i >>a; git commit -a -m"Append $i to a" ;done > /dev/null
$ git reset --hard HEAD^^ > /dev/null
$ cat a
foo
b
c
$ git reflog
145c322 HEAD@{0}: HEAD^^: updating HEAD
ae7c2b3 HEAD@{1}: commit: Append e to a
fdf2c5e HEAD@{2}: commit: Append d to a
145c322 HEAD@{3}: commit: Append c to a
363e22a HEAD@{4}: commit: Append b to a
fa26c43 HEAD@{5}: commit: Append foo to a
0a392a5 HEAD@{6}: commit (initial): Add file a
$ git reset --hard HEAD@{2}
HEAD is now at fdf2c5e Append d to a
$ cat a
foo
b
c
d

grazie mille William, per reflog git. Ho ripristinato il mio albero alla versione precedente e non sono sicuro di come tornare al recente. il tuo reflog git mi ha salvato. Grazie ancora.
palaniraja,

1
mi ha salvato anche! Nel mio caso la mia avventura con git rebase -iera andata storta (alla fine ha cancellato alcuni commit a causa di un errore di modifica). Grazie a questo consiglio sono tornato in buono stato!
paneer_tikka,

Cosa intendi con 30 giorni di default !?
Mohe TheDreamy,

@MoheTheDreamy Voglio dire che c'è un limite di tempo. Alla fine il Garbage Collector eliminerà i riferimenti non raggiungibili quando la loro età supera tale limite. L'impostazione predefinita era (e forse lo è ancora) 30 giorni. Quindi i riferimenti più vecchi potrebbero non essere disponibili.
William Pursell,

36

PERICOLO AVANTI: (leggere i commenti. L'esecuzione del comando proposto nella mia risposta potrebbe eliminare più di quanto si desideri)

per rimuovere completamente tutti i file incluse le directory che dovevo eseguire

git clean -f -d

13
Per salvare a chiunque il dolore che ho appena vissuto: questo eliminerà anche i file .gitignore-d!
landons,

scusa se ti ho causato problemi. Allora ho appena provato a ripristinare ed eliminare tutto in quella cartella. Non ricordo le circostanze esatte, ma la "-d" era l'unica cosa che funzionava per me. Spero di non averti causato troppo dolore :-)
Tobias Gassmann,

1
nessun danno fatto. Avevo dei backup, ma questo probabilmente
merita

35

Dopo aver letto un sacco di risposte e averle provate, ho trovato vari casi limite che a volte non puliscono completamente la copia di lavoro.

Ecco il mio attuale script bash per farlo, che funziona sempre.

#!/bin/sh
git reset --hard
git clean -f -d
git checkout -- HEAD

Esegui dalla directory principale della copia di lavoro.


10
L'ultimo comando mi dàerror: pathspec 'HEAD' did not match any file(s) known to git.
0xC0000022L

1
Ha funzionato per me quando ho tolto il "-". git checkout HEAD
Giullare

4
git reset --hardripristina i file monitorati (messi in scena o meno), git clean -f -drimuove i file git checkout -- HEADnon tracciati , perché allora ne abbiamo bisogno?
v.shashenko,

Non abbiamo bisogno del doppio trattino. Deve essere un errore di battitura.
Farax,

35

esegui semplicemente -

git stash

rimuoverà tutte le modifiche locali. e puoi anche usarlo in seguito eseguendo -

git stash apply 

3
l'uso git stash poprimuoverà automaticamente la modifica più nascosta per te
Arrow Cen,

8
git stash dropper rimuovere l'ultimo stato nascosto senza applicare alla copia di lavoro.
Deerchao,

git stash apply non aggiungerà i file appena creati
Ravistm

27

Ho riscontrato un problema simile. La soluzione è utilizzare git logper cercare quale versione del commit locale è diversa da quella remota. (Ad esempio la versione è3c74a11530697214cbcc4b7b98bf7a65952a34ec ).

Quindi utilizzare git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ecper ripristinare la modifica.


16

Ho cercato un problema simile,

Volevo buttare via gli impegni locali:

  1. clonato il repository (clone git)
  2. passato al ramo di sviluppo (git checkout dev)
  3. ha fatto pochi commit (git commit -m "commit 1")
  4. ma ho deciso di buttare via questi commit locali per tornare in remoto (origine / sviluppo)

Quindi ha fatto quanto segue:

git reset --hard origin/dev

Dai un'occhiata:

git status  

        On branch dev  
        Your branch is up-to-date with 'origin/dev'.  
        nothing to commit, working tree clean  

ora i commit locali vengono persi, tornando allo stato iniziale clonato, punto 1 sopra.


1
grazie, questa è l'unica cosa che ha funzionato per me - "git reset --hard origin"
Nisim Naim

felice di sapere che mi ha aiutato.
Manohar Reddy Poreddy,

7

Potresti non voler necessariamente / dover riporre i tuoi lavori / file nella tua directory di lavoro, ma semplicemente eliminarli completamente. Il comandogit clean lo farà per te.

Alcuni casi d'uso comuni per fare questo sarebbe rimuovere l'innesto che è stata generata da fusioni o strumenti esterni o rimuovere altri file in modo da poter eseguire una build pulita.

Tieni presente che dovrai prestare molta attenzione a questo comando, poiché è progettato per rimuovere i file dalla directory di lavoro locale NON TRACCIABILI. se cambi idea in seguito dopo aver eseguito questo comando, non potrai tornare indietro per vedere il contenuto dei file che sono stati rimossi. Un'alternativa più sicura è eseguire

git stash --all

che rimuoverà tutto ma lo salverà in una scorta. Questa scorta può essere successivamente utilizzata.

Tuttavia, se si desidera veramente rimuovere tutti i file e pulire la directory di lavoro, è necessario eseguire

git clean -f -d

Ciò rimuoverà tutti i file e anche eventuali sottodirectory che non hanno alcun elemento come risultato del comando. Una cosa intelligente da fare prima di eseguire il git clean -f -dcomando è eseguire

git clean -f -d -n

che ti mostrerà un'anteprima di ciò che verrà rimosso dopo l'esecuzione git clean -f -d

Quindi, ecco un riepilogo delle tue opzioni dalla più aggressiva alla meno aggressiva


Opzione 1 : Rimuovi tutti i file localmente (più aggressivo)

git clean -f -d

Opzione 2 : Anteprima dell'impatto sopra (Anteprima più aggressiva)

git clean -f -d -n

Opzione 3 : stash tutti i file (almeno aggressivo)

`git stash --all` 

6

Prova questo per ripristinare tutte le modifiche non impegnate nella filiale locale

$ git reset --hard HEAD

Ma se vedi un errore come questo:

fatal: Unable to create '/directory/for/your/project/.git/index.lock': File exists.

Puoi passare alla cartella '.git' quindi eliminare il file index.lock:

$ cd /directory/for/your/project/.git/
$ rm index.lock

Infine, esegui di nuovo il comando:

$ git reset --hard HEAD

0

Questa domanda riguarda di più il reset / ripristino del repository più ampio, ma nel caso in cui sei interessato a ripristinare le singole modifiche, ho aggiunto una risposta simile qui:

https://stackoverflow.com/a/60890371/2338477

Risposte alle domande:

  • Come ripristinare i singoli cambiamenti con o senza modifiche preservando nella cronologia git

  • Come tornare alla versione precedente per riavviare dallo stesso stato

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.