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.