Как вернуть "git rm -r."? - PullRequest
       100

Как вернуть "git rm -r."?

343 голосов
/ 24 января 2010

Я случайно сказал git rm -r .. Как мне восстановиться после этого?

Я не совершал.

Я думаю, что все файлы были помечены для удаления, а также были физически удалены из моей локальной проверки.

РЕДАКТИРОВАТЬ: Я мог бы (если бы я знал команду) вернуться к последнему коммиту. Но было бы намного лучше, если бы я мог просто отменить git rm -r .. Потому что я не совсем уверен, что я сделал после последнего коммита и до git rm -r ..

Ответы [ 11 ]

432 голосов
/ 24 января 2010
git reset HEAD

Должен сделать это. Если у вас нет незафиксированных изменений, которые вас волнуют, то

git reset --hard HEAD

должен принудительно сбросить все до вашего последнего коммита. Если у вас есть незафиксированные изменения, но первая команда не работает, сохраните незафиксированные изменения с помощью git stash:

git stash
git reset --hard HEAD
git stash pop
232 голосов
/ 05 января 2012

Я собрал несколько файлов и продолжал вносить изменения до моего следующего коммита, когда понял, что мне нужны эти файлы обратно. Вместо того, чтобы прятать и сбрасывать, вы можете просто извлекать отдельные файлы, которые вы пропустили / удалили, если хотите:

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

Это оставляет ваши другие незафиксированные изменения без изменений.

46 голосов
/ 19 января 2013

Для восстановления отдельных файлов или папок можно использовать следующие

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

Сначала будут воссозданы записи индекса для path/to/file, и файл будет воссоздан, как это было в последнем коммите, т.е. HEAD.

Подсказка: можно передать хеш коммита обеим командам, чтобы воссоздать файлы из более старого коммита. Подробнее см. git reset --help и git checkout --help.

27 голосов
/ 24 января 2010

Обновление:

Поскольку git rm . удаляет все файлы в этом и дочерних каталогах в рабочей кассе, а также в индексе, вам необходимо отменить каждое из этих изменений:

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

Это должно делать то, что вы хотите. Это не влияет на родительские папки вашего извлеченного кода или индекса.


Старый ответ, которого не было:

reset HEAD

сделает свое дело, а не сотрет любые незафиксированные изменения , которые вы внесли в свои файлы.

после этого вам нужно повторить любые git add команды, которые вы поставили в очередь.

24 голосов
/ 28 ноября 2012

Если у вас не получится ничего из вышеперечисленного, вы можете получить данные, используя следующее предложение: http://www.spinics.net/lists/git/msg62499.html

git prune -n
git cat-file -p <blob #>
9 голосов
/ 30 января 2015

Если вы зафиксировали и отправили изменения, вы можете сделать это, чтобы вернуть файл

// Replace 2 with the # of commits back before the file was deleted.
git checkout HEAD~2 path/to/file
7 голосов
/ 05 февраля 2018

отмена мерзавца rm

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

отмена мерзавца -r

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

отмена мерзавца-rf

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

Uncommitted changes включает not staged changes, staged changes but not committed.

7 голосов
/ 28 сентября 2013

Уже есть несколько хороших ответов, но я мог бы предложить малоиспользуемый синтаксис, который не только прекрасно работает, но и очень явно выражает то, что вы хотите (поэтому не страшно и не таинственно)

git checkout <branch>@{"20 minutes ago"} <filename>
3 голосов
/ 30 сентября 2016

Получить список коммитов

git log  --oneline

Например, хэш стабильного коммита: 45ff319c360cd7bd5442c0fbbe14202d20ccdf81

git reset --hard 45ff319c360cd7bd5442c0fbbe14202d20ccdf81
git push -ff origin master
1 голос
/ 14 августа 2014

У меня была идентичная ситуация. В моем случае решение было:

git checkout -- .
...