Как восстановить удаленные файлы в Git?
Александр Кокин Updated on 2023-10-27 19:35:35 to windows восстановление решения
Как бы долго вы ни отправляли свою работу в Git, на самом деле потеря документа должна быть очень редкой. Стесняясь стирать весь каталог хранилища (и не имея пульта дистанционного управления), практически никакие действия не приведут к состоянию, когда вы не сможете вернуть документ. Восстановить удаленный файл в Git не так уж сложно, но согласимся, что можно немножко запутаться. Мы должны рассмотреть несколько способов, что Git восстановить удаленные файлы, в зависимости от того, насколько вы были убеждены в то время, что вам действительно нужно удалить документ! Мы увидим, как Tenorshare 4DDiG поможет Git очень плавно добавлять удаленные файлы. Программное обеспечение является передовым и полностью совместимым с Git восстановить удаленный файл. Функции этого инструмента восстановления созданы с учетом чувствительности данных. Давайте сразу перейдем к теме и объясним, как легко Git восстанавливает удаленные файлы.
Часть 1: Что такое Git?
Git — это просто емкость для записей кода, присутствующая в фреймворке каждого веб-разработчика. Он заполняется в качестве средства отслеживания содержания кода с помощью «структуры управления отображением». Эта система управления версиями позволяет разработчикам вносить изменения в код и отмечать эти изменения в наборе опыта проектирования. В настоящее время критической частью Git является то, что есть близлежащее хранилище и удаленное хранилище. Близлежащее хранилище находится в фреймворке каждого дизайнера (как указано ранее). Удаленное хранилище облегчается на фокальном сервере, который разрешает дублирование документов каждого разработчика на ПК. Невероятно, правда? Git был создан в свете того факта, что, как правило, многочисленные разработчики веб-сайтов работают над отдельными действиями и заполняют в качестве емкости эти записи кода. Тем не менее, это позволяет многим людям, которым могло бы быть позволено избавиться от аналогичного кодового документа, не обращая особого внимания на то, где они находятся на планете. Различные ситуации можно рассматривать как файл восстановления Git. У нас есть пункт за пунктом 4 из этих случаев и 4 ответа для восстановления потерянных документов из вашего близлежащего хранилища на Git.
Часть 2: 4 случая восстановления удаленного файла в Git
Вы только что удалили свой код или файл по ошибке в Git? Не проблема, если вы уже читаете эту статью. Вы наверняка сможете восстановить свои файлы, используя это полезное руководство. Помимо изучения кода в течение длительного времени и пристального изучения рецензий в течение длительных периодов, одна вещь, которую инженеры презирают, — это потеря своих исходных кодов. Как разработчик, вы, скорее всего, не раз стирали свой код по ошибке. Есть возможность восстановить удаленные файлы Git. В исключительно простых и понятных для понимания шагах мы исследуем неудачи с записью, которые невозможно пропустить, и как их исправить в Git. Пока мы заняты, вы поймете, что такое Git, что делает его необычным и почему он нужен вам как разработчику. Итак, приступим?
Случай 1: я удалил файл, но не сделал коммит
Отсутствие ваших данных в Git после выполнения задачи в Git чрезвычайно редко. На самом деле, чтобы полностью переместить файл в Git, требуется, по крайней мере, удалить весь ваш локальный репозиторий без какой-либо резервной копии на удаленном сервере. В случае, если вы допустили ошибку и вскоре осознали это, вы удалили файл без коммита и немедленно. Просто вставьте приведенный ниже код, чтобы Git извлек удаленный файл.
Случай 2: я удалил файл и зафиксировал удаление
Вы удалили данные или файл, вы также зафиксировали удаление. Позже вы узнали, что вам нужен этот файл. Чтобы получить Git отменить удаление файла, вам нужно выполнить сброс. Действие сброса восстановит данные до состояния, в котором вы их зафиксировали. Это действие, однако, имеет недостаток. Он может удалить другие изменения, внесенные в файл после фиксации. Как только вы запустите команду, отменить эту операцию будет невозможно.
Случай 3: Я зафиксировал удаление, а затем сделал еще несколько коммитов
Справляясь с задачей, углубляясь и стирая, а затем продолжая работать, делая больше отправок во время нее? Ваша запись пока не подлежит восстановлению. Вам нужно выполнить поиск фиксации, в которой действительно есть удаленный документ, как показано ниже.
В тот момент, когда наступят результаты, у вас есть 2 варианта, чтобы восстановить свой рекорд. 1. Вы можете решить работать с отправкой, у которой действительно есть документ. Вам нужно посмотреть на документ из этого коммита, как показано ниже.
2. Вы также можете решить работать с отправкой, которая удалила документ. Вам нужно просмотреть документ из одного коммита до этого, как показано ниже.
Случай 4: я удалил файл, зафиксировал и нажал
На тот случай, если вы эффективно продвинули свою фиксацию или сосредоточились на удаленном устройстве. Сброс и повторное нажатие вызовут проблемы, так как исторический фон близлежащего хранилища в основном был пересмотрен. В этой ситуации, скорее всего, лучше записать новую отправку, которая исправляет ошибки, созданные тем, кто стирает документ. Чтобы сделать это, запустите:
Часть 3: Восстановление удаленных файлов в репозитории Git с помощью 4DDiG
-
Шаг 1: Выберите местоположение
Скачайте и установите Tenorshare 4DDiG на свой компьютер и запустите его. Выберите место, где вы потеряли файлы, а затем нажмите Сканировать, чтобы выполнить сканирование.
4DDiG просканирует и найдет все потерянные файлы на вашем компьютере. Результат сканирования показывает все эффективно найденные файлы. После сканирования вы можете выбрать файлы для предварительного просмотра перед восстановлением данных.
Наконец, после этого вы можете нажать на «Восстановить«, чтобы вернуть их с вашего жесткого диска. После нажатия на кнопку Восстановить, выберите местоположение, в котором вы хотите восстановить файлы.
Часто задаваемые вопросы по Git
1. Может ли Git восстановить удаленные файлы?
Да, действительно, вы можете восстановить удаленный файл из репозитория Git. Для этого вам нужно использовать команду Git checkout.
2. Как мне отменить удаление Git?
Вы можете перемещаться по репозиторию в той точке истории, в которой вы указали отменить удаление Git.
3. Как мне восстановить удаленный репозиторий Git?
Вы можете восстановить удаленные репозитории Git, принадлежащие вашей собственной учетной записи пользователя. Удаленный репозиторий может быть восстановлен в течение 90 дней, если только хранилище не было частью сети fork, которая в настоящее время не свободна.
4. Как мне восстановить удаленные файлы из корзины?
Откройте корзину, дважды нажав на ее значок. Найдите то, что вам нужно для восстановления. Посмотрите хорошо на контейнер рядом с записями, которые вам нужно восстановить. Щелкните правой кнопкой мыши и выберите Восстановить, чтобы восстановить файлы в их уникальных областях.
Для восстановления удаленных файлов Git может быть не очень распространен. Тем не менее, это крайне важно, если вы потеряете один или несколько файлов из репозитория Git. Tenorshare 4DDiG — это универсальное программное обеспечение для восстановления вашей системы. Он прост в использовании и разработан таким образом, чтобы удовлетворять потребности различных типов пользователей. Независимо от того, идет ли речь об одном файле или о ёмких файлах, существует высокая вероятность того, что 4DDiG поможет восстановить потерянные данные. Поэтому лучше сохранить его в вашей системе, чтобы каждый раз, когда вы совершаете ошибку, у вас была возможность восстановить данные всего за три шага.
10.7 Git изнутри — Обслуживание репозитория и восстановление данных
Изредка вам потребуется делать «уборку» — сделать репозиторий более компактным, очистить импортированный репозиторий от лишних файлов или восстановить потерянные данные. Данный раздел охватывает некоторые из этих сценариев.
Обслуживание репозитория
Время от времени Git выполняет автоматическую сборку мусора. Чаще всего эта команда ничего не делает. Однако, если у вас накопилось слишком много «рыхлых» объектов (не в pack-файлах), или, наоборот, отдельных pack-файлов, Git запускает полноценный сборщик — git gc (здесь «gc» это сокращение от «garbage collect», что означает «сборка мусора»). Эта команда выполняет несколько действий: собирает все «рыхлые» объекты и упаковывает их в pack-файлы; объединяет несколько упакованных файлов в один большой; удаляет недостижимые объекты, хранящиеся дольше нескольких месяцев.
Сборку мусора можно запустить вручную следующим образом:
$ git gc --auto
Опять же, как правило, эта команда ничего не делает. Нужно иметь примерно 7000 несжатых объектов или более 50 pack-файлов, чтобы запустился настоящий gc . Эти значения можно изменить с помощью параметров gc.auto и gc.autopacklimit соответственно.
Ещё одно действие, выполняемое gc — упаковка ссылок в единый файл. Предположим, репозиторий содержит следующие ветки и теги:
$ find .git/refs -type f .git/refs/heads/experiment .git/refs/heads/master .git/refs/tags/v1.0 .git/refs/tags/v1.1
Если выполнить git gc , эти файлы будут удалены из каталога refs . Git перенесёт их в файл .git/packed-refs в угоду эффективности:
$ cat .git/packed-refs # pack-refs with: peeled fully-peeled cac0cab538b970a37ea1e769cbbde608743bc96d refs/heads/experiment ab1afef80fac8e34258ff41fc1b867c702daa24b refs/heads/master cac0cab538b970a37ea1e769cbbde608743bc96d refs/tags/v1.0 9585191f37f7b0fb9444f35a9bf50de191beadc2 refs/tags/v1.1 ^1a410efbd13591db07496601ebc7a059dd55cfe9
При обновлении ссылки Git не будет редактировать этот файл, а добавит новый файл в refs/heads . Для получения хеша, соответствующего нужной ссылке, Git сначала проверит наличие файла ссылки в каталоге refs , а к файлу packed-refs обратится только в случае отсутствия оного. Так что, если вы не можете найти ссылку в каталоге refs , скорее всего она упакована в файле packed-refs .
Обратите внимание, последняя строка файла начинается с ^ . Это означает, что предыдущая строка является аннотированным тегом, а текущая строка — это коммит, на который указывает аннотированный тег.
Восстановление данных
В какой-то момент при работе с Git вы можете нечаянно потерять коммит. Как правило, такое случается, когда вы удаляете ветку, в которой находились некоторые наработки, а потом оказывается, что они всё-таки были нужными; либо вы выполнили git reset —hard , тем самым отказавшись от коммитов, которые затем понадобились. Как же в таком случае вернуть свои коммиты обратно?
Ниже приведён пример, в котором мы сбрасываем ветку master с потерей данных до более раннего состояния, а затем восстанавливаем потерянные коммиты. Для начала, давайте посмотрим, как сейчас выглядит история изменений:
$ git log --pretty=oneline ab1afef80fac8e34258ff41fc1b867c702daa24b Modify repo.rb a bit 484a59275031909e19aadb7c92262719cfcdf19a Create repo.rb 1a410efbd13591db07496601ebc7a059dd55cfe9 Third commit cac0cab538b970a37ea1e769cbbde608743bc96d Second commit fdf4fc3344e67ab068f836878b6c4951e3b15f3d First commit
Теперь сбросим ветку master на третий коммит:
$ git reset --hard 1a410efbd13591db07496601ebc7a059dd55cfe9 HEAD is now at 1a410ef Third commit $ git log --pretty=oneline 1a410efbd13591db07496601ebc7a059dd55cfe9 Third commit cac0cab538b970a37ea1e769cbbde608743bc96d Second commit fdf4fc3344e67ab068f836878b6c4951e3b15f3d First commit
Итак, теперь два последних коммита по-настоящему потеряны — они не достижимы ни из одной ветки. Необходимо найти SHA-1 хеш последнего коммита и создать ветку, указывающую на него. Сложность в том, чтобы узнать этот самый SHA-1, ведь вряд ли вы его запомнили, да?
Зачастую самый быстрый способ — использование команды git reflog . Дело в том, что во время вашей работы Git записывает все изменения HEAD. Каждый раз при переключении веток и коммитов изменений, добавляется запись в reflog. reflog также обновляется командой git update-ref — это, кстати, хорошая причина использовать именно эту команду, а не вручную записывать SHA-1 в ref-файлы, как было показано в Ссылки в Git. Вы можете посмотреть где находился указатель HEAD в любой момент времени, запустив git reflog :
$ git reflog 1a410ef HEAD@: reset: moving to 1a410ef ab1afef HEAD@: commit: Modify repo.rb a bit 484a592 HEAD@: commit: Create repo.rb
Здесь мы видим два коммита, на которые когда-то указывал HEAD, однако информации не так уж и много. Для получения информации в более удобном виде, можно воспользоваться командой git log -g , которая выведет лог записей из reflog в привычном формате:
$ git log -g commit 1a410efbd13591db07496601ebc7a059dd55cfe9 Reflog: HEAD@ (Scott Chacon ) Reflog message: updating HEAD Author: Scott Chacon Date: Fri May 22 18:22:37 2009 -0700 Third commit commit ab1afef80fac8e34258ff41fc1b867c702daa24b Reflog: HEAD@ (Scott Chacon ) Reflog message: updating HEAD Author: Scott Chacon Date: Fri May 22 18:15:24 2009 -0700 Modify repo.rb a bit
Похоже, что последний коммит — это и есть тот, который мы потеряли; его можно восстановить, создав новую ветку, указывающую на него. Например, создадим новую ветку с именем recover-branch , указывающую на этот коммит ( ab1afef ):
$ git branch recover-branch ab1afef $ git log --pretty=oneline recover-branch ab1afef80fac8e34258ff41fc1b867c702daa24b Modify repo.rb a bit 484a59275031909e19aadb7c92262719cfcdf19a Create repo.rb 1a410efbd13591db07496601ebc7a059dd55cfe9 Third commit cac0cab538b970a37ea1e769cbbde608743bc96d Second commit fdf4fc3344e67ab068f836878b6c4951e3b15f3d First commit
Отлично — теперь у нас есть ветка recover-branch , указывающая туда, куда ранее указывала ветка master , тем самым делая потерянные коммиты вновь доступными. Теперь предположим, что потерянные изменения отсутствуют в reflog — для симуляции такого состояния удалим восстановленную ветку и очистим reflog.
$ git branch -D recover-branch $ rm -Rf .git/logs/
В этом случае два первых коммита недоступны ниоткуда. Так как данные reflog хранятся в каталоге .git/logs/ , которую мы только что удалили, то теперь у нас нет reflog. Как теперь восстановить коммиты? Один из вариантов — использование утилиты git fsck , проверяющую внутреннюю базу данных на целостность. Если выполнить её с ключом —full , будут показаны все объекты, недостижимые из других объектов:
$ git fsck --full Checking object directories: 100% (256/256), done. Checking objects: 100% (18/18), done. dangling blob d670460b4b4aece5915caf5c68d12f560a9fe3e4 dangling commit ab1afef80fac8e34258ff41fc1b867c702daa24b dangling tree aea790b9a58f6cf6f2804eeac9f0abbe9631e4c9 dangling blob 7108f7ecb345ee9d0084193f147cdad4d2998293
В нашем случае потерянный коммит указан после слов «dangling commit» («висячий коммит»). Его можно восстановить аналогичным образом, создав новую ветку, указывающую на этот SHA-1.
Удаление объектов
Git — замечательный инструмент с кучей классных возможностей, но некоторые из них способны стать источником проблем; например, команда git clone загружает проект вместе со всей историей, включая все версии всех файлов. Это нормально, если в репозитории хранится только исходный код, так как Git хорошо оптимизирован под такой тип данных и может эффективно сжимать их. Однако, если когда-либо в проект был добавлен большой файл, каждый, кто потом захочет клонировать проект, будет вынужден скачивать этот файл, даже если он был удалён в следующем коммите. Он будет в базе всегда, просто потому, что он доступен в истории.
Это может стать большой проблемой при конвертации Subversion или Perforce репозиториев в Git. В этих системах вам не нужно загружать всю историю, поэтому добавление больших файлов не имеет там особых последствий. Если при импорте из другой системы или при каких-либо других обстоятельствах стало ясно, что ваш репозиторий намного больше, чем он должен быть, то как раз сейчас мы расскажем, как можно найти и удалить большие объекты.
Предупреждаем: дальнейшие действия переписывают историю изменений. Каждый коммит, начиная с самого раннего, из которого нужно удалить большой файл, будет переписан. Если сделать это непосредственно после импорта, пока никто ещё не работал с репозиторием, то всё окей, иначе придётся сообщить всем участникам о необходимости перебазирования их правок относительно ваших новых коммитов.
Для примера добавим большой файл в тестовый репозиторий, удалим его в следующем коммите, а потом найдём и удалим его полностью из базы. Сначала добавим большой файл в нашу историю:
$ curl https://www.kernel.org/pub/software/scm/git/git-2.1.0.tar.gz > git.tgz $ git add git.tgz $ git commit -m 'Add git tarball' [master 7b30847] Add git tarball 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 git.tgz
Упс, мы нечаянно. Нам лучше избавиться от этого файла:
$ git rm git.tgz rm 'git.tgz' $ git commit -m 'Oops - remove large tarball' [master dadf725] Oops - remove large tarball 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 git.tgz
Теперь запустим сборщик мусора и посмотрим, сколько места сейчас используется:
$ git gc Counting objects: 17, done. Delta compression using up to 8 threads. Compressing objects: 100% (13/13), done. Writing objects: 100% (17/17), done. Total 17 (delta 1), reused 10 (delta 0)
Чтобы быстро узнать, сколько места занято, можно воспользоваться командой count-objects :
$ git count-objects -v count: 7 size: 32 in-pack: 17 packs: 1 size-pack: 4868 prune-packable: 0 garbage: 0 size-garbage: 0
Строка size-pack — это размер pack-файлов в килобайтах, то есть всего занято почти 5 MБ. Перед последним коммитом использовалось около 2 КБ — очевидно, удаление файла не удалило его из истории. Всякий раз, когда кто-либо захочет клонировать этот репозиторий, ему придётся скачивать все 5 МБ для того, чтобы заполучить этот крошечный проект, просто потому, что однажды вы имели неосторожность добавить большой файл. Давайте же исправим это!
Для начала найдём проблемный файл. В данном случае, мы уже знаем, что это за файл. Но если бы не знали, как можно было бы определить, какие файлы занимают много места? При вызове git gc все объекты упаковываются в один pack-файл, но, несмотря на это, определить самые крупные файлы можно, запустив служебную команду git verify-pack и отсортировав её вывод по третьей колонке, в которой записан размер файла. Так как нас интересуют самые крупный файлы, оставим три последние строки с помощью tail :
$ git verify-pack -v .git/objects/pack/pack-29…69.idx \ | sort -k 3 -n \ | tail -3 dadf7258d699da2c8d89b09ef6670edb7d5f91b4 commit 229 159 12 033b4468fa6b2a9547a70d88d1bbe8bf3f9ed0d5 blob 22044 5792 4977696 82c99a3e86bb1267b236a4b6eff7868d97489af1 blob 4975916 4976258 1438
Большой объект внизу списка, его размер — 5 МБ. Для того чтобы узнать, что это за файл, воспользуемся командой rev-list , которая уже упоминалась в разделе Проверка формата сообщения коммита главы 8. Если передать ей ключ —objects , она выдаст хеши всех коммитов, а также хеши объектов и соответствующие им имена файлов. Воспользуемся этим для определения имени выбранного объекта:
$ git rev-list --objects --all | grep 82c99a3 82c99a3e86bb1267b236a4b6eff7868d97489af1 git.tgz
Теперь необходимо удалить данный файл из всех деревьев в прошлом. Легко получить все коммиты, которые изменяли данный файл:
$ git log --oneline --branches -- git.tgz dadf725 Oops - remove large tarball 7b30847 Add git tarball
Для полного удаления этого файла из истории необходимо переписать все коммиты, начиная с 7b30847 . Воспользуемся командой filter-branch , о которой мы писали в разделе Перезапись истории главы 7:
$ git filter-branch --index-filter \ 'git rm --ignore-unmatch --cached git.tgz' -- 7b30847^.. Rewrite 7b30847d080183a1ab7d18fb202473b3096e9f34 (1/2)rm 'git.tgz' Rewrite dadf7258d699da2c8d89b09ef6670edb7d5f91b4 (2/2) Ref 'refs/heads/master' was rewritten
Опция —index-filter похожа на —tree-filter , использовавшуюся в разделе Перезапись истории главы 7, за исключением того, что вместо передачи команды, модифицирующей файлы на диске, мы используем команду, изменяющую файлы в индексе.
Вместо удаления файла чем-то вроде rm file , мы используем git rm —cached , так как нам надо удалить файл из индекса, а не с диска. Причина, по которой мы делаем именно так — скорость: нет необходимости извлекать каждую ревизию на диск, чтобы применить фильтр, а это может очень сильно ускорить процесс. Если хотите, можете использовать и tree-filter для получения аналогичного результата. Опция —ignore-unmatch команды git rm отключает вывод сообщения об ошибке в случае отсутствия файлов, соответствующих шаблону. Ещё один момент: мы указали команде filter-branch переписывать историю, начиная с коммита 7b30847 , потому что мы знаем, что именно в нём впервые появилась проблема. По умолчанию перезапись начинается с самого первого коммита, что потребовало бы гораздо больше времени.
Теперь история не содержит ссылок на данный файл. Однако, в reflog и в новом наборе ссылок, добавленном Git в .git/refs/original после выполнения filter-branch , ссылки на него всё ещё присутствуют, поэтому необходимо их удалить, а затем переупаковать базу. Необходимо избавиться от всех возможных ссылок на старые коммиты перед переупаковкой:
$ rm -Rf .git/refs/original $ rm -Rf .git/logs/ $ git gc Counting objects: 15, done. Delta compression using up to 8 threads. Compressing objects: 100% (11/11), done. Writing objects: 100% (15/15), done. Total 15 (delta 1), reused 12 (delta 0)
Проверим, сколько места удалось освободить:
$ git count-objects -v count: 11 size: 4904 in-pack: 15 packs: 1 size-pack: 8 prune-packable: 0 garbage: 0 size-garbage: 0
Размер упакованного репозитория сократился до 8 КБ, что намного лучше, чем 5 МБ. Из значения поля size видно, что большой объект всё ещё хранится в одном из ваших «рыхлых» объектов, но, что самое главное, при любой последующей отправке данных наружу (а значит и при последующих клонированиях репозитория) он передаваться не будет. Если очень хочется, можно удалить его навсегда локально, выполнив git prune —expire :
$ git prune --expire now $ git count-objects -v count: 0 size: 0 in-pack: 15 packs: 1 size-pack: 8 prune-packable: 0 garbage: 0 size-garbage: 0
Восстановление удаленного репозитория
Вы можете восстановить удаленные репозитории, чтобы восстановить их содержимое.
Кто может использовать эту функцию.
Enterprise owners can restore a deleted repository.
About repository restoration
Usually, if someone deletes a repository, it will be available on disk for 90 days and can be restored via the site admin dashboard. For more information, see «Site admin dashboard.»
Unless a legal hold is in effect on a user or organization, after 90 days the repository is purged and deleted forever.
If a repository was part of a fork network when it was deleted, the restored repository will be detached from the original fork network.
It can take up to an hour after a repository is deleted before that repository is available for restoration.
Restoring a repository will not restore release attachments or team permissions. Issues that are restored will not be labeled.
Restoring a deleted repository
- From an administrative account on GitHub AE, in the upper-right corner of any page, click
.
In the search results, click the name of the user or organization.
Repositories section, click the
Further reading
Восстановление удаленного репозитория
У вас есть возможность восстановить некоторые удаленные репозитории для восстановления содержимого.
Кто может использовать эту функцию.
Anyone can restore deleted repositories that were owned by their own personal account. Organization owners can restore deleted repositories that were owned by the organization.
About repository restoration
A deleted repository can be restored within 90 days, unless the repository was part of a fork network that is not currently empty. A fork network consists of a parent repository, the repository’s forks, and forks of the repository’s forks. If your repository was part of a fork network, it cannot be restored unless every other repository in the network is deleted or has been detached from the network. For more information about forks, see «About forks.»
If you want to restore a repository that was part of a fork network that is not currently empty, you can contact us through the GitHub Support portal.
It can take up to an hour after a repository is deleted before that repository is available for restoration.
Restoring a repository will not restore release attachments or team permissions. Issues that are restored will not be labeled.
Restoring a deleted repository that was owned by a personal account
- In the upper-right corner of any page, click your profile photo, then click Settings.
Repositories.
Under «Repositories», click Deleted repositories.
Next to the repository you want to restore, click Restore.
Restoring a deleted repository that was owned by an organization
- In the upper-right corner of GitHub.com, select your profile photo, then click
Your organizations.