Come ripristinare un "git rm -r."?


378

Ho detto per caso git rm -r .. Come posso recuperare da questo?

Non mi sono impegnato.

Penso che tutti i file siano stati contrassegnati per l'eliminazione e anche fisicamente rimossi dal mio checkout locale.

EDIT: potrei (se avessi saputo il comando) tornare all'ultimo commit. Ma sarebbe molto meglio se potessi semplicemente annullare il git rm -r .. Perché non sono davvero sicuro di quello che ho fatto dopo l'ultimo commit e prima del git rm -r ..


3
Per questa domanda particolare, ripristina --hard è una buona soluzione ... è già elencato, quindi citerò in questo commento che potresti voler controllare la documentazione per git-reflog.
William Pursell,

8
Nota che, poiché non hai fornito -fa git rmgit, non avrai rimosso alcun file con modifiche in scena o non in scena, quindi git reset; git checkout .dovresti recuperare tutto.
CB Bailey

Fai solo attenzione: git checkout. cancellerà tutte le modifiche non messe in scena.
PeterB,

1
Ho appena fatto una cosa del genere e non capisco perché i miei file locali siano stati eliminati (e, come l'OP, non ho ancora eseguito il commit).
Xonatron,

Con Git 2.23+ (agosto 2019), si dovrebbe ripristinare i file con git restore: git restore -s@ -SW -- .. Vedi la mia risposta qui sotto .
VonC

Risposte:


468
git reset HEAD

Dovrebbe farlo. Se non hai cambiamenti senza impegno che ti interessano, allora

git reset --hard HEAD

dovrebbe reimpostare forzatamente tutto sull'ultimo commit. Se hai modifiche senza commit, ma il primo comando non funziona, quindi salva le modifiche senza commit con git stash:

git stash
git reset --hard HEAD
git stash pop

22
Nota che git reset --hard HEADdistrugge tutte le modifiche utili che hai apportato nelle directory principali della directory di lavoro corrente.
Alex Brown,

10
@Mild: indosso ancora un sudore freddo!
hoipolloi,

6
Non ho votato al ribasso, ma ho appena provato a conservare, azzerare, a fare pop e ho perso tutte le mie ultime modifiche. Forse ho letto male la risposta.
Greg M. Krsak,

1
Questo raramente funziona per me, e sono così felice di lavorare in una cartella Dropbox. Forma scadente, ma mi salva ogni volta ...
Nuby,

3
Quando ho eseguito gash stash pop, ho semplicemente rimosso di nuovo i file, ovviamente perché ostacola il fatto che ho (accidentalmente) rimosso alcuni file. Questa risposta non funziona se hai delle modifiche non impegnate che desideri conservare.
sudo,

252

Ho inviato alcuni file e ho continuato a apportare modifiche prima del mio prossimo commit quando mi sono reso conto che avevo bisogno di alcuni di quei file. Invece di stash e reset, puoi semplicemente controllare i singoli file che hai perso / rimosso se vuoi:

git checkout HEAD path/to/file path/to/another_file

Ciò lascia intatte le altre modifiche non confermate senza soluzioni alternative.


6
Questo mi ha aiutato perché avevo altre modifiche non confermate.
Dan,

4
Questa risposta aiuta per quelli di noi che si sono imbattuti in questa domanda cercando di ripristinare un singolo git rmpiuttosto che un intero ricorsivo git rm -r. Per un'eliminazione ricorsiva completa, le altre soluzioni potrebbero essere migliori, a seconda della quantità di file rimossi.
tresf

Tu, amico mio, meriti un premio.
Saluta il

Se potessi lo farei clic su 100.times !!!
Wagner Braga,

57

Per recuperare alcuni singoli file o cartelle è possibile utilizzare quanto segue

git reset -- path/to/file
git checkout -- path/to/file

Questo per prima cosa ricrea le voci dell'indice path/to/filee ricrea il file com'era nell'ultimo commit, ovvero HEAD.

Suggerimento: è possibile passare un hash di commit a entrambi i comandi per ricreare i file da un commit precedente. Vedi git reset --helpe git checkout --helpper i dettagli.


Migliore risposta. Facile annullamento chirurgico di una singola git rmoperazione senza cancellare altre modifiche non confermate.
wberry,

Mi ha aiutato! migliore risposta.
Akram,

28

Aggiornare:

Poiché git rm .elimina tutti i file in questa e nelle directory figlio nel checkout funzionante e nell'indice, è necessario annullare ciascuna di queste modifiche:

git reset HEAD . # This undoes the index changes
git checkout .   # This checks out files in this and child directories from the HEAD

Questo dovrebbe fare quello che vuoi. Non influisce sulle cartelle principali del codice o dell'indice estratto.


Vecchia risposta che non era:

reset HEAD

farà il trucco e non cancellerà alcuna modifica non impegnata che hai apportato ai tuoi file.

successivamente è necessario ripetere tutti i git addcomandi in coda.


1
mi dispiace, ho sempre impostato in git alias.co="checkout"modo da git cofare il checkout.
Alex Brown,

25

Se si finisce con nessuna delle precedenti funzioni, si potrebbe essere in grado di recuperare i dati utilizzando il suggerimento da qui: http://www.spinics.net/lists/git/msg62499.html

git prune -n
git cat-file -p <blob #>

4 anni dopo, ancora un salvavita!
Ladro:

Ho scritto un programma c ++ per concatenare i risultati (avevo circa 100 oggetti penzolanti nel mio repository, rendendolo necessario). Basta compilare ed eseguire, quindi passare nella directory locale git repo. raw.githubusercontent.com/bluuman/git-recover-files/master/…
James Meas

15

annulla git rm

git rm file             # delete file & update index
git checkout HEAD file  # restore file & index from HEAD

annulla git rm -r

git rm -r dir          # delete tracked files in dir & update index
git checkout HEAD dir  # restore file & index from HEAD

annulla git rm -rf

git rm -r dir          # delete tracked files & delete uncommitted changes
not possible           # `uncommitted changes` can not be restored.

Uncommitted changescomprende not staged changes, staged changes but not committed.


Naturalmente, nulla può essere annullato git rm -rf, in quanto ciò può anche eliminare file (solo) non tracciati o messi in scena.
jpaugh

git rm -rf filee git rm -rf dirnon eliminerà alcun file non tracciato.
canzone xu,

10

Se hai eseguito il commit e il push delle modifiche, puoi farlo per recuperare il file

// Replace 2 with the # of commits back before the file was deleted.
git checkout HEAD~2 path/to/file

Funzionava con "Modifiche da impegnare:" dove un file era stato cancellato da un vecchio git cherry-pick di cui avevo ancora bisogno. Avevo provato git reset HEAD ~ <number> <file> che non funzionava.
fungo

7

Ci sono già alcune buone risposte, ma potrei suggerire una sintassi poco usata che non solo funziona alla grande, ma è molto esplicita in ciò che vuoi (quindi non spaventoso o misterioso)

git checkout <branch>@{"20 minutes ago"} <filename>

3

Ottieni il commit della lista

git log  --oneline

Ad esempio, il commit stabile ha l'hash: 45ff319c360cd7bd5442c0fbbe14202d20ccdf81

git reset --hard 45ff319c360cd7bd5442c0fbbe14202d20ccdf81
git push -ff origin master

1

Ho avuto una situazione identica. Nel mio caso la soluzione era:

git checkout -- .

0

Con Git 2.23+ (agosto 2019), il comando corretto per ripristinare i file (e l'indice) dovrebbe essere quello di usare ... git restore(no reset --hardo il comando confusogit checkout )

Questo è:

git restore -s=HEAD --staged --worktree -- .

O la sua forma abbreviata:

git restore -s@ -SW -- .

-1

Ho avuto esattamente lo stesso problema: stava pulendo le mie cartelle, riorganizzando e spostando i file. Sono entrato: git rm .e premi invio; e poi ho sentito le mie viscere allentarsi un po '. Fortunatamente, non ho digitato subito git commit -m "".

Tuttavia, il seguente comando

git checkout .

restaurato tutto e mi ha salvato la vita.

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.