¿Cómo revertir un "git rm -r"?


378

Dije accidentalmente git rm -r .. ¿Cómo me recupero de esto?

No me comprometí.

Creo que todos los archivos se marcaron para su eliminación y también se eliminaron físicamente de mi pago local.

EDITAR: podría (si supiera el comando) volver al último commit. Pero sería mucho mejor si pudiera deshacer el git rm -r .. Porque no estoy realmente seguro de lo que hice después del último commit y antes del git rm -r ..


3
Para esta pregunta en particular, restablecer --hard es una buena solución ... ya está en la lista, así que solo mencionaré en este comentario que es posible que desee consultar la documentación de git-reflog.
William Pursell

8
Tenga en cuenta que debido a que no suministró -fa git rmgit, no habrá eliminado ningún archivo que tuviera cambios organizados o no organizados, por lo que git reset; git checkout .debería recuperar todo.
CB Bailey

Solo ten cuidado, git checkout. eliminará todos los cambios no organizados.
PeterB

1
Acabo de hacer algo como esto, y no entiendo por qué mis archivos locales se eliminaron (y, como el OP, todavía no me he comprometido).
Xonatron

Con Git 2.23+ (agosto de 2019), que le restaurar archivos con git restore: git restore -s@ -SW -- .. Vea mi respuesta a continuación .
VonC

Respuestas:


468
git reset HEAD

Deberías hacerlo. Si no tiene ningún cambio no comprometido que le interese, entonces

git reset --hard HEAD

debería restablecer por la fuerza todo a su último commit. Si tiene cambios no confirmados, pero el primer comando no funciona, guarde los cambios no confirmados con git stash:

git stash
git reset --hard HEAD
git stash pop

22
Tenga en cuenta que git reset --hard HEADdestruye cualquier cambio útil que haya realizado en los directorios principales del directorio de trabajo actual.
Alex Brown

10
@Mild: ¡Todavía estoy sudando frío!
hoipolloi

66
No rechacé la votación, pero solo intenté guardar, restablecer duro, explotar y perdí todos mis cambios recientes. Quizás leí mal la respuesta.
Greg M. Krsak

1
Esto rara vez funciona para mí, y estoy muy contento de trabajar en una carpeta de Dropbox. Mala forma, pero me salva cada vez ...
Nuby

3
Cuando hice git stash pop, simplemente eliminé los archivos nuevamente, por supuesto porque oculta el hecho de que (accidentalmente) eliminé algunos archivos. Esta respuesta no funciona si tiene cambios no confirmados que desea conservar.
sudo

252

Git-rmd algunos archivos y seguí haciendo cambios antes de mi próxima confirmación cuando me di cuenta de que necesitaba recuperar algunos de esos archivos. En lugar de esconder y restablecer, simplemente puede retirar los archivos individuales que perdió / eliminó si desea:

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

Esto deja sus otros cambios no confirmados intactos sin soluciones.


66
Esto ayudó porque tuve otros cambios no comprometidos.
Dan

44
Esta respuesta ayuda a aquellos de nosotros que tropezamos con esta pregunta buscando revertir una git rmrecursiva en lugar de una recursiva completa git rm -r. Para una eliminación recursiva completa, las otras soluciones pueden ser mejores, dependiendo de la cantidad de archivos eliminados.
Tresf

Tú, mi hombre, mereces un premio.
Salamit

¡Si pudiera, lo haría clic 100 veces!
Wagner Braga

57

Para recuperar algunos archivos o carpetas individuales, se puede usar lo siguiente

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

Esto recreará primero las entradas de índice path/to/filey recreará el archivo como estaba en el último commit, es decir HEAD.

Sugerencia: se puede pasar un hash de confirmación a ambos comandos para recrear archivos de una confirmación anterior. Ver git reset --helpy git checkout --helppara más detalles.


La mejor respuesta. Fácil 'deshacer' quirúrgico de una sola git rmoperación sin eliminar otros cambios no comprometidos.
wberry

Me ayudó a salir! la mejor respuesta.
Akram

28

Actualizar:

Dado que git rm .elimina todos los archivos en este y los directorios secundarios en la comprobación de trabajo y en el índice, debe deshacer cada uno de estos cambios:

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

Esto debería hacer lo que quieras. No afecta a las carpetas principales de su código o índice desprotegido.


Antigua respuesta que no era:

reset HEAD

hará el truco y no borrará los cambios no confirmados que haya realizado en sus archivos.

después de eso, debe repetir cualquier git addcomando que haya puesto en cola.


1
lo siento, siempre configuro git alias.co="checkout"para que se git cohaga el pago.
Alex Brown

25

Si no funciona ninguno de los anteriores, puede recuperar datos utilizando la sugerencia de aquí: http://www.spinics.net/lists/git/msg62499.html

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

¡4 años después, todavía es un salvavidas!
ThievingSix

Escribí un programa de c ++ para concatenar los resultados (tenía unos 100 objetos colgando en mi repositorio, lo que lo hizo necesario). Simplemente compile y ejecute, luego pase su directorio local git repo. raw.githubusercontent.com/bluuman/git-recover-files/master/…
James Meas

15

deshacer git rm

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

deshacer git rm -r

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

deshacer git rm -rf

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

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


Por supuesto, nada puede deshacerse git rm -rf, ya que eso también puede eliminar archivos no rastreados o montados (solo).
jpaugh

git rm -rf filey git rm -rf dirno eliminará ningún archivo sin seguimiento.
canción xu

10

Si ha confirmado y enviado los cambios, puede hacer esto para recuperar el archivo

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

Esto funcionó para 'Cambios que se deben confirmar': donde se eliminó un archivo de un viejo git cherry-pick que todavía necesitaba. Intenté git reset HEAD ~ <number> <file> que no funcionó.
Mushcraft

7

Ya hay algunas buenas respuestas, pero podría sugerir una sintaxis poco utilizada que no solo funciona muy bien, sino que es muy explícita en lo que desea (por lo tanto, no da miedo ni es misterioso)

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

3

Obtener lista de compromiso

git log  --oneline

Por ejemplo, commit estable tiene hash: 45ff319c360cd7bd5442c0fbbe14202d20ccdf81

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

1

Tuve una situación idéntica. En mi caso la solución fue:

git checkout -- .

0

Con Git 2.23+ (agosto de 2019), el comando adecuado para restaurar archivos (y el índice) debería ser usar ... git restore(no reset --hardo el comando confusogit checkout )

Es decir:

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

O su forma abreviada:

git restore -s@ -SW -- .

-1

Tuve exactamente el mismo problema: estaba limpiando mis carpetas, reorganizando y moviendo archivos. Entré: git rm . y pulsa enter; y luego sentí que mis intestinos se aflojaban un poco. Afortunadamente, no escribí git commit -m "" inmediatamente.

Sin embargo, el siguiente comando

git checkout .

restauró todo y me salvó la vida.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.