Как оправиться от "git rm -rf." и до сих пор сохраняются несвязанные изменения? - PullRequest
2 голосов
/ 14 июня 2019

У меня есть куча изменений, добавленных к промежуточному индексу на git add *, , но еще не зафиксированных , я хотел их удалить, отменить добавление , поэтому я сделал git rm -rf . к моему удивлению, он удалил их с моего жесткого диска, я хочу, чтобы получить их обратно;однако я внес огромные изменения и хотел бы вернуть эти изменения.

TLDR: Я удалил весь свой проект на git rm -rf ., мне нужен какой-то способ сбросить удаление,так что я сохраняю свои незафиксированные изменения и возвращаю свои файлы.пожалуйста, я слишком напуган, что могу потерять весь свой проект.

ОТВЕТ: Мой репозиторий - это в основном веб-сайт с большим количеством контента. Исходя из ответов ниже, я сделал 2 копиимой репозиторий, давайте назовем их копией A и B, потому что AI сделал git reset --hard, чтобы вернуться к последнему коммиту, я вернул свои файлы, но потерял сделанные мной изменения.поэтому для копии BI сделал git fsck --lost-found и вошел в каталог .git / lost-found / other /, содержащий несколько версий моих файлов с хеш-именами, я продолжал открывать каждую из них, между ними было более 60 файлов, каждый файл, который я узнаю, переименовывает его в его фактическое имя, а затем помещает его вместо старых версий в копию А, в конце я удалил свое исходное хранилище и теперь использую копию А в качестве своего веб-сайта.как будто ничего не произошло сейчас.Одна маленькая глупая ошибка => 5 часов боли.Не повторяй то, что я сделал, никогда.

прямо сейчас git status показывает все мои файлы как "удалено:" и выделено зеленым.

Ответы [ 5 ]

4 голосов
/ 14 июня 2019

Использование

find .git/objects/ -type f -printf "%T+\t%p\n" \
  | sort \
  | sed 's:.*git/objects/\(.*\)/\(.*\):\1\2:' \
  | while read object; do
       echo -n "$object "; 
       git cat-file -t "$object";
    done

Вы должны получить список объектов и типов, упорядоченных по времени.

Например, на тестовом репо:

908553f63e9126f933b690970d41adc3377e3360 blob
31e0d0e213c9976308fbb91c542ced9218fa8f6a tree
5b181f91c49d287b4670fcf3545656dc0c0ef5f4 commit
de683137e0b2d0a40f766307e81999986e4b31c2 blob
086cb344a4fd8a9d671006b8e5844f2437faa3ab tree
930ba9809b5d50410b72c3fbff111d948f1027fa commit
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 blob
40cda8e010466dc7a4a0eb107e7e45804290685e blob

Последние два больших двоичных объекта были созданы после последнего коммита, и если вы печатаете их с помощью, например. git cat-file -p 40cda8e010466dc7a4a0eb107e7e45804290685e, вы сможете восстановить содержимое файла.

Вы также можете получить некоторые деревья таким образом (используйте git ls-tree <tree-id> для их печати), но не верхнего уровня, поскольку они были сохранены непосредственно в индексе.

3 голосов
/ 14 июня 2019

Может быть надежда: объекты, которые вы ранее добавили в индекс, могут все еще существовать, хотя на них больше нет ссылок.Для проверки я сделал следующее:

$ git init test
$ cd test
$ echo hello > README.md
$ git add README.md
$ git commit -m"Add README.md"
$ echo world >> README.md
$ cat README.md
hello
world
$ git add README.md
$ git rm -f README.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    README.md

$ git fsck
Checking object directories: 100% (256/256), done.
unreachable blob 94954abda49de8615a048f8d2e64b5de848e27a1
$ git show 94954abda49de8615a048f8d2e64b5de848e27a1
hello
world

Так что даже после git rm -f содержимое файла, добавленное в индекс, все еще существует.Вы можете сбросить их все в .git/lost-found/other, запустив git fsck --lost-found.

Сам индекс не сохраняется как объект Git, но находится непосредственно в .git/index, поэтому я думаю, что он был необратимо перезаписан.Это означает, что пути к файлам, а также любые метаданные, такие как разрешения, были потеряны.

3 голосов
/ 14 июня 2019

Для файлов, которые были зафиксированы, git reset --hard восстановит их все.

Для тех, кто добавлен, но не зафиксирован, попробуйте git fsck --lost-found. Он будет печатать свисающие капли и делать их копии в .git/lost-found/other. Вы можете запустить git cat-file -p $blob или cat .git/lost-found/other/$blob, чтобы просмотреть содержимое. BLOB-объекты не записывают пути к файлам, поэтому необходимо сопоставить содержимое и путь к файлу по памяти или по ключевому слову, которое не было изменено с помощью git grep $keyword. После того, как вы найдете путь для BLOB-объекта, запустите cp .git/lost-found/other/$blob $path, чтобы восстановить его.

0 голосов
/ 14 июня 2019

git status дает вам несколько советов о том, какие команды вы можете использовать для восстановления файлов:

$ git rm  -rf .
$ git status

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  deleted: file1
  deleted: file2

Чтобы удалить из архива удаленные файлы:

$ git reset HEAD file1 file2
$ git status

On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    deleted:    file1
    deleted:    file2

no changes added to commit (use "git add" and/or "git commit -a")

Извлечение удаленных файлов:

$ git checkout -- file1 file2
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean
0 голосов
/ 14 июня 2019

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

Вы можете вернуть ваши зафиксированные файлы с помощью git reset --hard HEAD.Поскольку вы очистили свое промежуточное дерево, ваши незафиксированные изменения больше не находятся в git (как указывают некоторые другие ответы, это может быть не так), поэтому ваш единственный шанс восстановить их - это любые резервные копии, которые вы или ваша ОС могли сделать.

Извините, это не помогает в текущей ситуации, но для дальнейшего использования вы можете отменить изменения с помощью git reset HEAD.

...