Восстановить из git reset --hard?

457

Есть ли способ восстановить незафиксированные изменения в рабочем каталоге из git reset --hard HEAD?

Джейкоб Лайлс
источник
49
Я бы порекомендовал отучиться git reset. Вам не нужна эта команда, и она опасна, поэтому не используйте ее. Чтобы вернуть ответвление к предыдущему коммиту, либо git rebase -iотбросить ненужные коммиты, либо git checkout(отсоединить голову), а затем git branch -Mпереместить подсказку ветвления. Первый откажется работать с локальными изменениями, а последний будет работать только в том случае, если локально измененные файлы не отличаются между ревизиями.
Ян Худек
11
@ Ян, я не верю этому. Есть совершенно законные причины для использования перезагрузки.
spaaarky21
4
@ spaaarky21: Да, есть. Но git reset --hard somewhereэто одна из немногих действительно опасных команд git.
Ян Худек
5
@ Ян, я согласен, но это опасно, но это не значит, что ты не должен его использовать. Просто знайте, что вы делаете, и будьте осторожны. :)
spaaarky21
3
Не относится к отмене git reset --hard HEAD ~ 1 , потому что здесь оригинальный постер пытается восстановить незафиксированные изменения.

Ответы:

477

Вы не можете вернуть незафиксированные изменения в целом.

Предварительно подготовленные изменения ( git add) должны быть восстановлены из индексных объектов, поэтому, если вы это сделали, используйте git fsck --lost-foundдля поиска объектов, связанных с ним. (Это записывает объекты в .git/lost-found/каталог; оттуда вы можете использовать git show <filename>для просмотра содержимого каждого файла.)

Если нет, ответ здесь будет: посмотрите на свою резервную копию. Возможно, ваш редактор / IDE хранит временные копии в / tmp или C: \ TEMP и тому подобное. [1]

git reset HEAD@{1}

Это восстановит предыдущую ГОЛОВУ

[1] vim, например, дополнительно сохраняет постоянную отмену, затмение IDE хранит локальную историю ; такие функции могут сохранить ваш **

sehe
источник
18
Локальная история Eclipse - и, кроме того, поскольку некоторые изменения были старше 6 дней, моя резервная копия Time Machine для локальной истории Eclipse! По какой-то причине резервная копия Time Machine для папки, управляемой git, не содержала мои предыдущие изменения.
Кристианбродбек
2
Вы серьезно спасатель намека! У TextWrangler была резервная копия файлов. Спасибо
Вивек Сампара
6
Среда разработки (IntelliJ) хранила изменения локально, которые сохранили день. Спасибо за совет!
progonkpa
1
Вау, это удивительно. Это работает, даже если вы никогда не делали коммитов.
Будевейн Асман
2
Действительно, локальная история в «Затмении» (в моем случае - «Интеллидж») спасает мой день в восстановлении неосторожных изменений, документ здесь для Интеллидж: blog.jetbrains.com/idea/2008/01/…
Ричард
449

ответ от этого ТАК

$ git reflog show
93567ad HEAD@{0}: reset: moving to HEAD@{6}    
203e84e HEAD@{1}: reset: moving to HEAD@{1}    
9937a76 HEAD@{2}: reset: moving to HEAD@{2}
203e84e HEAD@{3}: checkout: moving from master to master
203e84e HEAD@{4}: reset: moving to HEAD~1
9937a76 HEAD@{5}: reset: moving to HEAD~1
d5bb59f HEAD@{6}: reset: moving to HEAD~1
9300f9d HEAD@{7}: commit: fix-bug

# said the commit to be recovered back is on 9300f9d (with commit message fix-bug)
$ git reset HEAD@{7}

Вы вернули свой день! :)

кругозор
источник
24
Просто чтобы добавить к этому ответу, это помогло бы людям, которые фактически совершили изменения, которые были выброшены через полную перезагрузку.
Murki
9
Отлично - но в моем случае файлы исчезли полностью. Использование git checkout HEAD@{19}позволило мне проверить потерянные файлы в отключенном состоянии. Затем используется git checkout -b new-branch-nameдля добавления их обратно в репо в «прикрепленном» состоянии.
NightOwl888
@ NightOwl888: Git newbie здесь, и у меня была та же проблема, что мои файлы все еще пропали. Не могли бы вы объяснить более подробно, как вы восстановили свои файлы в «прикрепленном» состоянии (или вы могли бы объяснить, что это на самом деле означает)? Спасибо огромное!
OhDaeSu
3
@ user3385759 - В Git, когда вы используете команду checkout для чего-либо, что не является ветвью, оно перейдет в специальный режим «отдельная голова». Это означает, что вы на самом деле не указываете на ветку, но вы можете просмотреть то, что было проверено в состоянии сущности (в данном случае запись reflog). Из этого состояния вы можете превратить его в «настоящую» ветвь, к которой вы можете вернуться снова, используя git checkout -b new-branch-name. Книга Pragmatic Version Control Using Git хорошо объясняет Git в простых терминах.
NightOwl888
2
Да, что сказали NomNomCameron и Джесси Адельман. Я ошибочно думал, что сброс будет сброшен до моего последнего коммита. Нет. Это уничтожило все. Этот ответ спас меня от дня или двух воссоздания моей работы.
VeteranCoder
308

git reset --hardСегодня я случайно запустил репо, в то время как сегодня у меня были незафиксированные изменения. Чтобы получить его обратно, я побежал git fsck --lost-found, который написал все ссылки без ссылки <path to repo>/.git/lost-found/. Поскольку файлы не были переданы, я нашел их в otherкаталоге внутри <path to repo>/.git/lost-found/. Оттуда я могу видеть использование незафиксированных файлов git show <filename>, копировать их и переименовывать.

Примечание. Это работает, только если вы добавили файлы, которые хотите сохранить в индекс (используя git add .). Если файлы не были в индексе, они будут потеряны.

Джастин
источник
4
Я получил только файлы с ссылками на коммиты lost-found. Но я мог тогда сделать, git showчтобы получить содержание.
Митар
6
Просто , чтобы спасти кому - время#!/bin/bash cd PATH_TO_PROJECT/.git/lost-found/other FILES=* COUNTER = 0 for f in $FILES do echo "Processing $f file..." git show $f > "PATH_TO_RECOVERY_DIRECTORY/$COUNTER.m" let COUNTER=COUNTER+1 done
rwolst
209

Да, ВЫ МОЖЕТЕ ВОССТАНОВИТЬ с жесткого сброса в git.

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

git reflog

чтобы получить идентификатор вашего коммита. Тогда используйте:

git reset --hard <commit-id-retrieved-using-reflog>

Этот трюк пару раз спас мне жизнь.

Вы можете найти документацию reflog ЗДЕСЬ .

Гейб
источник
9
Пока что я думаю, что это лучший и самый краткий ответ. Может показаться нелогичным восстановление после git reset --hardиспользования другого, git reset --hardно если вы не используете --hardпереключатель, у вас останутся записи в вашем рабочем пространстве, которые эффективно вернут работу, которую вы только что восстановили.
Райан Х.
2
Работает как шарм! Предыдущий ответ ( stackoverflow.com/questions/5788037/recover-from-git-reset-hard/… ) не работал для меня.
codemax
3
Этот ответ не правильный. Этот подход восстанавливает только ранее совершенные изменения. Он не сможет восстановить незафиксированные изменения (о чем этот вопрос).
Альдерат
2
Это решение работает для меня. Я сделал полный сброс, а затем, когда я использовал, git logя не увидел идентификатор коммита. С помощью git reflogя мог видеть идентификатор коммита
dboscanv
2
это работает для меня. Спасибо!!!!!!
RedEyed
60

Пока я работал над локальным проектом, я хотел переместить его на GitHub, а затем создал новый репозиторий. Пока я пытался добавить все эти файлы в новый репозиторий с помощью .gitignore, я случайно добавил неправильный файл, а затем попытался очистить его.

Я побежал git reset --hard origin/master: P

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

Это спасло мне жизнь

git reflog show
git reset HEAD@{1} 
git push 

Надеюсь, это спасет другую жизнь.

Орчун
источник
Для меня это было git reset HEAD@\{27\} , спасибо!
4
1
У меня есть 7 коммитов для сброса, я использую git reflog showдля проверки и с того первого коммита, который я используюgit reset HEAD@{number}
Vishwas Nahar
38

Если вы используете что-то вроде IntelliJ:

В контекстном меню выберите «Локальная история» и нажмите «Показать историю» в подменю:

Представление локальной истории проекта или папки показывает все, что вы сделали за последние несколько дней. В столбце «Действие» в нижней части диалогового окна выберите действие, которое необходимо откатить. [...] Таким образом, в верхней части диалогового окна отображается древовидная структура измененных файлов. Если вы хотите восстановить только удаленный файл, независимо от других изменений, которые были сделаны с тех пор, вы можете выбрать файл Lost.txt в виде дерева и нажать кнопку «Восстановить».

http://blog.jetbrains.com/idea/2008/01/using-local-history-to-restore-deleted-files/

Это только что вытащило мою задницу из огня!

JonathanTien
источник
Это, безусловно, лучший ответ для пользователей IntelliJ! Большое спасибо, это сработало отлично. Я попробовал все остальные решения, и ни одно из них не сработало. git reflogне работал, потому что я не совершал изменения. git fsck --lost-foundработал для постановочных файлов, но не все из них были поставлены. Локальная история IntelliJ отлично восстановила мои несохраненные файлы, я так благодарен за эту возможность
Денес Папп
30

Я только что сделал git reset --hardи потерял все свои незафиксированные изменения. К счастью, я использую редактор (IntelliJ), и мне удалось восстановить изменения из локальной истории. Затмение должно позволить вам сделать то же самое.

user1147827
источник
20

По определению, git reset --hardGit выбрасывает незафиксированные изменения без какого-либо способа их восстановления (может помочь ваша система резервного копирования, но не Git).

На самом деле, очень мало случаев, когда git reset --hardэто хорошая идея. В большинстве случаев есть более безопасная команда, чтобы сделать то же самое:

  • Если вы хотите выбросить свои незафиксированные изменения, используйте git stash. Он сохранит резервную копию этих изменений, срок действия которых истечет через некоторое время, если вы запустите git gc. Если вы на 99,9% уверены, что эти изменения вам никогда не понадобятся, тогда git stashвы все равно ваш друг в случае с 0,1%. Если вы уверены на 100%, то git stashвсе равно ваш друг, потому что эти 100% имеют ошибку измерения ;-).

  • Если вы хотите подвинуть свою HEADи верхушку текущей ветки в истории, то git reset --keepэто ваш друг. Это сделает то же самое git reset --hard, но не отменит ваши локальные изменения.

  • Если вы хотите сделать и то и другое, то git stash && git reset --keepэто ваш друг.

Научите ваши пальцы не использовать git reset --hard, он окупит один день.

Матье Мой
источник
так что, если кто- git stash && git reset --hardто это сделает , это сотрет любой скрытый контент, верно?
jxramos
1
Нет, git reset --hardне сбрасывает тайник. git stashявляется заменой git reset --hardв том смысле, что он удаляет незафиксированные изменения из вашего рабочего дерева, за исключением того, что он сохраняет их в безопасности, а не отбрасывает их навсегда.
Мэтью Мой
или просто зафиксируйте свои изменения, прежде чем выполнить жесткий сброс, и они все еще будут в вашем локальном репо
ThaJay
11

если вы случайно сбросили коммит, сделайте это,

git reflog show
git reset HEAD@{2} // i.e where HEAD used to be two moves ago - may be different for your case

при условии HEAD@{2}, что вы хотите вернуться

Эдвин Икечукву Оконкво
источник
для меня это отлично работало, если вы делаете это на PowerShell, обязательно напишите его следующим образом: git reset 'HEAD @ {2}', иначе не будет работать в powershell
VectorX
10

Это то, что я обычно делаю, если я теряю некоторые изменения.

git reflog
git checkout <commit id> // now you are in where you want but you cannot push from detached branch to master
manually copy and paste changes from detached branch to master or working branch
git reset --hard HEAD // if needed
git add ... > git commit ... > git push ...

чтобы переместить указатель назад к вашим предыдущим коммитам, но сохранить изменения, которые вы сделали до сих пор в вашей последней проверке коммитов git reset --soft dadada

Дракон рыцарь
источник
8

Информация потеряна.

Поскольку вы не фиксировали, ваш .git никогда не сохранял эту информацию. Таким образом, в принципе gitне могу восстановить его для вас.

Но, если вы только что это сделали git diff, есть способ восстановления с помощью вывода терминала, выполнив следующие 3 простых шага.

  1. прокрутите свой терминал и найдите o / p of git diff. Сохраните o / p в файле с именем diff.patch
  2. Найдите и замените все 7 пробелов и 8 пробелов символом табуляции (\ t) и сохраните изменения.
  3. Зайдите в свой репозиторий git. Примените diff.patch ( patch -p1 < diff.patch)

Вы спасены! :)

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

тк ..
источник
7

Я столкнулся с той же проблемой, и я почти сходил с ума .... сначала я зафиксировал проект и слился .. позже, когда я попытался запустить, git push --set-upstream origin master я получил эту ошибку

  fatal: refusing to merge unrelated histories

поэтому я запустил git reset --hard HEADи удалил 3-недельный проект, но эти несколько команд ниже спасают день:

git reset HEAD@{1}         //this command unstage changes after reset
git fsck --lost-found      //I got the dangling commit fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b
git show <dangling commit something like-> fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b>
git rebase fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b

надеюсь это поможет

Slycreator
источник
6

Вы можете вернуть коммит после выполнения reset --hard HEAD.

Используйте " git reflog", чтобы проверить историю HEADв ветке.

Вы увидите свой коммит и его идентификатор здесь.

Сделать

git reset {commit Id of the commit you want to bring back}
рачана ачарья
источник
5

Если вы, к счастью, открыли те же файлы в другом редакторе (например, Sublime Text), попробуйте ctrl-z на них. Это просто спасло меня ..

Гейб
источник
3

Я обнаружил, что любые неподтвержденные файлы перед тем, как они были git reset --hard <commit>удалены из истории git. Однако мне посчастливилось держать сеанс редактора кода открытым в течение всего времени, когда я вырывал свои волосы, и обнаружил, что простой control + zв каждом из затронутых файлов возвращал состояние файла обратно в версию до того, как Git так обязательно сбросить все, что я не просил это специально.Hooray!!

Дружественный-робот
источник
3

Если вы пытаетесь использовать код ниже:

git reflog show
# head to recover to
git reset HEAD@{1} 

и по какой-то причине получают:

ошибка: неизвестный переключатель `e '

тогда попробуйте заключить HEAD@{1}в кавычки

git reset 'HEAD@{1}'
Ржавчина
источник
3
 git reset HEAD@{4}

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

$ git reflog show

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

$ git reset --hard 8c4d112

8c4d112 - это код, который вы хотите сбросить там. давайте посмотрим на https://www.theserverside.com/video/How-to-use-the-git-reset-hard-command-to-change-a-commit-history, чтобы получить больше информации.

мохаммад
источник
Большое спасибо @mohammad, это спасло меня. Ранее я не мог видеть свои исходные файлы, но, выполнив вышеуказанные шаги, смог восстановить все исходные файлы.
Гаурав Бансал
2

Правильные ответы. Хорошо, теперь я люблю мерзавца :-) Вот простой рецепт.

git log HEAD@{2}
git reset --hard  HEAD@{2}

Где «2» - это номер возврата туда, где вы зафиксировали свои изменения. В моем случае, прервано коллегой и начальником, чтобы помочь отладить некоторые проблемы со сборкой; Итак, дважды сделал сброс - жесткий; Итак, HEAD и HEAD @ {1} были перезаписаны. Фух, потерял бы наш тяжелый труд.

TimJowers2
источник
2

Я сделал git reset --hardпо неправильному проекту по ошибке (я знаю ...). Я только что работал над одним файлом, и он все еще был открыт во время и после выполнения команды.

Несмотря на то, что я не зафиксировал, я смог получить старый файл с простым COMMAND + Z.

Даниэль Сегура
источник
0

Ссылочный ответ от этого,

После запуска git reflog show говорят, что вы хотите перейти на коммит 9300f9d

после запуска git reset 9300f9d

вы можете сделать git status, а затем вам, возможно, понадобится проверить ваши файлы, чтобы восстановить ваши изменения

git checkout - filepath / name

Даниил
источник
0

Если вы разрабатываете на Netbeans, посмотрите между вкладками файлов и областью редактирования файлов. Есть «Источник» и «История». В «Истории» вы увидите изменения, сделанные с помощью контроля версий (git / other), а также изменения, сделанные локально. В этом случае локальные изменения могут вас спасти.

Педро Альварес
источник
0

( ответ подходит для подмножества пользователей )

Если вы используете (все последние) macOS, и даже если вы находитесь за пределами диска Time Machine, ОС будет сохранять ежечасные резервные копии, называемые локальными снимками .

Введите Time Machine и перейдите к файлу, который вы потеряли. ОС спросит вас:

The location to which you're restoring "file.ext" already contains an
item with the same name. Do you want to replace it with the one you're
restoring?

Вы должны быть в состоянии восстановить потерянные файлы.

Калаф
источник
0

Если у вас была открытая IDE с тем же кодом, попробуйте выполнить ctrl + z для каждого отдельного файла, в который вы внесли изменения. Это помогло мне восстановить мои незафиксированные изменения после выполнения git reset --hard.

Дваракеш Т.П.
источник
-3

Когда мы делаем git reset --hard и все локальные незафиксированные изменения удаляются. Чтобы восстановить изменения - в IDE щелкните файл, сравните файл с локальной историей, в которой будут перечислены изменения по дате, и мы сможем восстановить данные. Ваш день сохранен!

Roopa
источник
1
Этот ответ повторяет два предыдущих.
Ишервуд