Как я могу отменить git reset --hard HEAD ~ 1?

Можно ли отменить изменения, вызванные следующей командой? Если так, то как?

git reset --hard HEAD~1
7.08.2008 23:22:51
Я написал полное руководство по восстановлению любого потерянного коммита с помощью git. У него даже есть иллюстрации :-) [Проверьте это] [fixLink] [fixLink]: programblings.com/2008/06/07/…
webmat 16.09.2008 17:13:48
--hardотбрасывает незафиксированные изменения. Поскольку они не отслеживаются git, нет способа восстановить их через git.
Zaz 8.08.2013 22:22:47
CodeWizard 7.05.2016 22:25:57
Это отличная статья, которая поможет вам восстановить ваши файлы.
Jan Swart 22.10.2016 11:10:50
Это отличный ресурс прямо из Github: как отменить (почти) что-нибудь с помощью Git
jasonleonhard 3.02.2017 21:15:12
17 ОТВЕТОВ
РЕШЕНИЕ

Пэт Нотц прав. Вы можете вернуть коммит, если он был в течение нескольких дней. git собирает только мусор примерно через месяц или около того, если вы явно не скажете ему удалить более новые BLOB-объекты.

$ git init
Initialized empty Git repository in .git/

$ echo "testing reset" > file1
$ git add file1
$ git commit -m 'added file1'
Created initial commit 1a75c1d: added file1
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file1

$ echo "added new file" > file2
$ git add file2
$ git commit -m 'added file2'
Created commit f6e5064: added file2
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file2

$ git reset --hard HEAD^
HEAD is now at 1a75c1d... added file1

$ cat file2
cat: file2: No such file or directory

$ git reflog
1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD
f6e5064... HEAD@{1}: commit: added file2

$ git reset --hard f6e5064
HEAD is now at f6e5064... added file2

$ cat file2
added new file

Вы можете видеть в примере, что file2 был удален в результате аппаратного сброса, но был восстановлен после сброса через reflog.

1739
29.01.2009 05:35:42
Вы можете использовать «git reset --hard HEAD @ {1}», нет необходимости использовать SHA1. В большинстве случаев должно быть достаточно использовать «git reset --hard ORIG_HEAD».
Jakub Narębski 21.05.2009 06:17:08
git log -gможет быть немного лучше способ просмотра reflog, чем git reflog.
Dan Moulding 28.10.2010 13:09:06
Есть одна очень важная оговорка с этим .. и это - "тяжелая" часть. --hard сносит ваши местные незафиксированные изменения. И вы не можете получить их обратно, как это (так как они нигде не были совершены). Я полагаю, что вы ничего не можете с этим поделать :(
Michael Anderson 4.08.2011 05:05:31
^ Просто чтобы вы знали, что можете сохранить свои локальные изменения перед выполнением сброса --hard, а затем просто вытолкнуть их, и вы ничего не потеряете! Должен любить мерзавца.
Lethjakman 1.09.2014 02:49:30
Я предпочитаю git reflogболее git log -gпросто потому , что вы получите всю информацию на одной линии с sha1, HEAD , информация и сообщения фиксации все выстроены. Гораздо проще читать.
Snowcrash 11.11.2014 18:41:19

То, что вы хотите сделать, это указать sha1 коммита, в который вы хотите восстановить. Вы можете получить sha1, изучив reflog ( git reflog), а затем выполнив

git reset --hard <sha1 of desired commit>

Но не ждите слишком долго ... через несколько недель git увидит этот коммит как не имеющий ссылки и удалит все BLOB-объекты.

364
9.08.2008 05:30:13
предупреждение для себя несколько минут назад: это сбросит все модификации. это не коснется неотслеживаемых файлов, хотя.
aexl 9.01.2018 10:20:49

Его можно восстановить, если Git еще не собрал мусор.

Получите обзор висячих коммитов с fsck:

$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

Восстановите оборванный коммит с помощью rebase:

$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf
113
13.07.2014 19:51:59
Это потрясающая вещь. Жизнь спасена.
Mohhamad Hasham 30.08.2017 18:30:32
Подробное объяснение можно найти здесь: medium.com/@CarrieGuss/… . Спасательные вещи.
tuan.dinh 20.03.2020 02:55:05

Если вы еще не собрали сборщик мусора в своем хранилище (например, с помощью git repack -dили git gc, но учтите, что сборка мусора также может происходить автоматически), то ваш коммит все еще там - он просто больше не доступен через HEAD

Вы можете попытаться найти свой коммит, просмотрев выходные данные git fsck --lost-found.

В более новых версиях Git есть нечто, называемое «reflog», которое представляет собой журнал всех изменений, которые были внесены в ссылки (в отличие от изменений, которые вносятся в содержимое репозитория). Так, например, каждый раз, когда вы переключаете свой HEAD (то есть каждый раз, когда вы git checkoutпереключаете ветви), который будет регистрироваться. И, конечно же, вы git resetтакже манипулировали ГОЛОВОЙ, так что это также было зарегистрировано. Вы можете получить доступ к более старым состояниям ваших ссылок таким же образом, как вы можете получить доступ к более старым состояниям вашего репозитория, используя @знак вместо « ~, как» git reset HEAD@{1}.

Мне потребовалось некоторое время, чтобы понять, в чем разница между HEAD @ {1} и HEAD ~ 1, поэтому вот небольшое объяснение:

git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show HEAD@{1} # => Three
git reflog

Таким образом, HEAD~1означает «перейти к коммиту до коммита, на который в данный момент указывает HEAD», а HEAD@{1}означает «перейти к коммиту, на который указал HEAD, до того, как он указал на тот, на который в данный момент указывает».

Это легко позволит вам найти потерянный коммит и восстановить его.

21
29.08.2008 01:49:54
Другое объяснение, которое, я думаю, будет более понятным: HEAD ~ 1 означает перейти к «родителю HEAD», а HEAD @ {1} - «вернуться на один шаг назад в истории HEAD»
kizzx2 22.07.2009 17:30:25
Проблема в том, что термин «история» действительно перегружен в VCS. Еще одним способом выражения является то, что ~ идет назад в истории коммитов , тогда как @ идет назад в хронологической или временной истории . Но ни одна из трех версий не особенно хороша.
Jörg W Mittag 22.07.2009 22:02:23
@ kizzx2 (и Йорг) на самом деле эти 3 объяснения, вместе взятые, очень помогают - спасибо
Richard Le Mesurier 12.05.2014 10:32:10

Ответ скрыт в подробном ответе выше, вы можете просто сделать:

$> git reset --hard HEAD@{1}

(Смотрите вывод git reflog show )

171
26.02.2011 15:13:20
Обратите внимание, что это не решение, если вы сделали какие-либо другие изменения репо после сброса. Обязательно взгляните на reflog, прежде чем запускать что-либо.
forresthopkinsa 12.06.2017 19:06:45
Случайно сбросил мой репозиторий, думал, что моя работа потерялась навсегда. Этот ответ спас мой день.
Zaiyang Li 25.07.2018 15:12:49
воу! ты действительно спасешь меня день =)
jfcogato 14.03.2019 09:22:06
Отлично. Это действительно помогло.
Prashant Biradar 9.12.2019 16:08:32

Если вам действительно повезло, как и мне, вы можете вернуться в свой текстовый редактор и нажать «Отменить».

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

45
13.01.2012 00:48:48
На самом деле это очень хороший совет, спасший меня много раз;) И это намного проще, чем делать что-либо в git ...
severin 21.05.2012 15:30:24
и спасибо тебе за все доброе, милостивое во всем этом мире. Спасибо. Спасибо. Спасибо.
Trip 14.08.2012 18:12:07
Это единственный способ восстановить неустановленные изменения в файлах после полной перезагрузки. Спас меня тоже;)
Czarek Tomczak 30.05.2013 20:33:17
В качестве дополнительной подсказки некоторые IDE, такие как eclipse, также сохраняют недавнюю историю файлов. Таким образом, вы даже сможете восстановить старые изменения после закрытия редактора. Это творило чудеса для меня.
martin 15.08.2014 09:48:21
Да благословит вас Бог Крис
Adam Waite 10.04.2017 21:56:09

Пример случая IRL:

$ git fsck --lost-found

Checking object directories: 100% (256/256), done.
Checking objects: 100% (3/3), done.
dangling blob 025cab9725ccc00fbd7202da543f556c146cb119
dangling blob 84e9af799c2f5f08fb50874e5be7fb5cb7aa7c1b
dangling blob 85f4d1a289e094012819d9732f017c7805ee85b4
dangling blob 8f654d1cd425da7389d12c17dd2d88d318496d98
dangling blob 9183b84bbd292dcc238ca546dab896e073432933
dangling blob 1448ee51d0ea16f259371b32a557b60f908d15ee
dangling blob 95372cef6148d980ab1d7539ee6fbb44f5e87e22
dangling blob 9b3bf9fb1ee82c6d6d5ec9149e38fe53d4151fbd
dangling blob 2b21002ca449a9e30dbb87e535fbd4e65bac18f7
dangling blob 2fff2f8e4ea6408ac84a8560477aa00583002e66
dangling blob 333e76340b59a944456b4befd0e007c2e23ab37b
dangling blob b87163c8def315d40721e592f15c2192a33816bb
dangling blob c22aafb90358f6bf22577d1ae077ad89d9eea0a7
dangling blob c6ef78dd64c886e9c9895e2fc4556e69e4fbb133
dangling blob 4a71f9ff8262701171d42559a283c751fea6a201
dangling blob 6b762d368f44ddd441e5b8eae6a7b611335b49a2
dangling blob 724d23914b48443b19eada79c3eb1813c3c67fed
dangling blob 749ffc9a412e7584245af5106e78167b9480a27b
dangling commit f6ce1a403399772d4146d306d5763f3f5715cb5a    <- it's this one

$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a

commit f6ce1a403399772d4146d306d5763f3f5715cb5a
Author: Stian Gudmundsen Høiland <stian@Stians-Mac-mini.local>
Date:   Wed Aug 15 08:41:30 2012 +0200

    *MY COMMIT MESSAGE IS DISPLAYED HERE*

diff --git a/Some.file b/Some.file
new file mode 100644
index 0000000..15baeba
--- /dev/null
+++ b/Some.file
*THE WHOLE COMMIT IS DISPLAYED HERE*

$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a

First, rewinding head to replay your work on top of it...
Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a.
34
20.08.2012 01:39:49
Свисающий шарик звучит как монстр AD & D!
sbichenko 15.12.2014 17:44:03
Спасибо @Stian Хорошо объяснил! Я хотел бы добавить для других, которые находят этот ответ, что если у вас есть более одного «висячего» коммита, он не уверен, что вы хотите сделать ребаз в последнем ряду :)
JimiSweden 10.11.2016 13:45:53
Git Show сохранил некоторые из моих файлов, спасибо большое, чувак!
William 25.07.2019 14:02:49

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

Когда вы делаете «git add» или перемещаете что-либо из верхнего левого угла в нижний левый в git gui, содержимое файла сохраняется в большом двоичном объекте, и содержимое файла можно восстановить из этого большого двоичного объекта.

Таким образом, можно восстановить файл, даже если он не был зафиксирован, но его необходимо добавить.

git init  
echo hello >> test.txt  
git add test.txt  

Теперь BLOB-объект создан, но на него ссылается индекс, поэтому он не будет указан с помощью git fsck, пока мы не сбросим его. Итак, мы сбрасываем ...

git reset --hard  
git fsck  

вы получите болтающийся шарик ce013625030ba8dba906f756967f9e9ca394464a

git show ce01362  

вернет вам содержимое файла "привет"

Чтобы найти несвязанные коммиты, я нашел подсказку, где это предлагается.

gitk --all $(git log -g --pretty=format:%h)  

У меня есть это как инструмент в git gui, и это очень удобно.

11
20.01.2014 06:27:22
+1. Как уже упоминалось в stackoverflow.com/a/21350689/6309 , git fsck --lost-foundможет помочь.
VonC 27.01.2014 09:05:45

Сделал крошечный скрипт, чтобы немного легче было найти коммит, который искали:

git fsck --lost-found | grep commit | cut -d ' ' -f 3 | xargs -i git show \{\} | egrep '^commit |Date:'

Да, это можно сделать намного красивее с помощью awk или чего-то в этом роде, но это просто, и мне это просто нужно. Может спасти кого-то еще 30 секунд.

3
11.03.2014 08:09:52

В большинстве случаев да.

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

Ниже я перечислил ряд возможных сценариев и способы их устранения.

Все мои изменения были зафиксированы, но коммиты исчезли!

Такая ситуация обычно возникает, когда вы запускаете git resetс аргументом, как в git reset --hard HEAD~. Не волнуйтесь, это легко восстановить!

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

git reset --hard @{1}

Это сбрасывает вашу текущую ветку независимо от того, в каком она была состоянии до того, как в последний раз она была изменена (в вашем случае самой последней модификацией ветки будет полная перезагрузка, которую вы пытаетесь отменить).

Однако, если вы уже сделали другие изменения в вашей отрасли с сброса, один вкладыш выше не будет работать. Вместо этого вы должны запустить, чтобы увидеть список всех последних изменений, внесенных в вашу ветку (включая перезагрузки). Этот список будет выглядеть примерно так:git reflog <branchname>

7c169bd master@{0}: reset: moving to HEAD~
3ae5027 master@{1}: commit: Changed file2
7c169bd master@{2}: commit: Some change
5eb37ca master@{3}: commit (initial): Initial commit

Найдите в этом списке операцию, которую вы хотите отменить. В приведенном выше примере это будет первая строка с надписью «сброс: переход к HEAD ~». Затем скопируйте представление коммита до (ниже) этой операции. В нашем случае это будет master@{1}(или 3ae5027они оба представляют один и тот же коммит) и будет запущен git reset --hard <commit>для сброса текущей ветки обратно в этот коммит.

Я поставил свои изменения с git add, но никогда не совершал. Теперь мои изменения исчезли!

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

Подробнее об этом смотрите Undo git reset --hard с незафиксированными файлами в области подготовки .

У меня были изменения в файлах в моем рабочем каталоге, с которыми я никогда не ставил git addи никогда не фиксировал. Теперь мои изменения исчезли!

Ооо Я не хочу тебе этого говорить, но тебе, вероятно, не повезло. git не хранит изменения, которые вы не добавляете или не фиксируете, и в соответствии с документацией дляgit reset :

--жесткий

Сбрасывает индекс и рабочее дерево. Любые изменения отслеживаемых файлов в рабочем дереве, так <commit>как отбрасываются.

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

31
23.05.2017 11:47:36
Однострочник работал на меня, спасибо, но мне просто интересно, что именно делает "@ {1}" ..
Stan Bashtavenko 30.11.2015 19:45:48
@StanB Документация находится здесь: git-scm.com/docs/git-rev-parse в основном это относится к первой записи reflog в текущей ветви.
Ajedi32 30.11.2015 20:44:44
Спасибо за освещение всех дел. Я не совершал и не добавил свой.
xdhmoore 28.02.2018 20:23:28

насколько я знаю, --hardоткажется от незавершенных изменений. Так как они не отслеживаются Git. но вы можете отменить discarded commit.

$ git reflog

будут списки:

b0d059c HEAD@{0}: reset: moving to HEAD~1
4bac331 HEAD@{1}: commit: added level introduction....
....

где 4bac331это discarded commit.

Теперь просто переместите голову на этот коммит ::

$ git reset --hard 4bac331
43
2.04.2015 08:57:22

Я только что сделал полный сброс на неправильный проект. То, что спасло мою жизнь, было местной историей Затмения. Говорят, что у IntelliJ Idea тоже есть такой же, как и у вашего редактора, стоит проверить:

  1. Раздел справки Eclipse по местной истории
  2. http://wiki.eclipse.org/FAQ_Where_is_the_workspace_local_history_stored%3F
4
7.04.2017 08:59:29
Местная история Jetbrains CLion великолепна и сэкономила мне 2 часа работы :)
Fabian Knapp 18.12.2017 20:35:59

Прежде чем ответить, давайте добавим некоторый фон, объясняя, что это такое HEAD.

First of all what is HEAD?

HEADэто просто ссылка на текущий коммит (последний) в текущей ветке.
Там может быть только один HEADв любой момент времени. (исключая git worktree)

Содержимое HEADхранится внутри .git/HEADи содержит 40 байтов SHA-1 текущего коммита.


detached HEAD

Если вы не используете последний коммит, то HEADесть он указывает на предыдущий коммит в истории detached HEAD.

введите описание изображения здесь

В командной строке это будет выглядеть так - SHA-1 вместо имени ветви, так как HEADне указывает на вершину текущей ветви

введите описание изображения здесь


Несколько вариантов того, как восстановить систему с отключенной HEAD:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Это извлечет новую ветку, указывающую на желаемый коммит.
Эта команда вернется к данному коммиту.
На этом этапе вы можете создать ветку и начать работать с этого момента.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

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

Каждый раз, когда заголовок изменяется, в reflog

git reflog
git checkout HEAD@{...}

Это вернет вас к желаемой фиксации

введите описание изображения здесь


git reset HEAD --hard <commit_id>

«Переместите» свою голову назад к желаемому коммиту.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • Примечание: ( начиная с Git 2.7 )
    вы также можете использовать git rebase --no-autostash.


git revert <sha-1>

"Отменить" данный диапазон фиксации или фиксации.
Команда сброса «отменит» любые изменения, сделанные в данном коммите.
Новый коммит с патчем отмены будет зафиксирован, в то время как оригинальный коммит останется в истории.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Эта схема иллюстрирует, какая команда что делает.
Как вы можете видеть там reset && checkoutизменить HEAD.

введите описание изображения здесь

14
21.04.2018 16:30:45
Похоже, ваш git reset HEAD --hard <commit_id>пример взят из stackoverflow.com/questions/4114095/… - Если это так, не могли бы вы отредактировать в атрибуции?
Rob♦ 27.04.2018 03:44:00

git reflog

  • Найдите свой коммит в списке, затем скопируйте и вставьте его в эту команду:

git cherry-pick <the sha>

11
27.02.2020 16:20:06
git-cherry-pick - применить изменения, внесенные некоторыми существующими коммитами. Я думаю, что это просто и очень полезно в этом контексте
Amitesh 12.02.2020 09:54:48
все на самом деле ищут это, когда ищут, как отменить изменения с полным сбросом. этот ответ должен получить больше голосов
ErenL 27.02.2020 15:17:29
@ErenL Полагаю, я просто понял, что людям нравится делать дополнительную работу. хаха
ScottyBlades 27.02.2020 16:13:29

Если вы используете IDE JetBrains (на базе IntelliJ), вы можете восстановить даже свои незафиксированные изменения с помощью функции «Локальная история».

Щелкните правой кнопкой мыши каталог верхнего уровня в дереве файлов, найдите «Локальная история» в контекстном меню и выберите «Показать историю». Это откроет представление, в котором можно найти ваши последние изменения, и как только вы найдете ревизию, к которой хотите вернуться, щелкните ее правой кнопкой мыши и нажмите «Вернуть».

7
16.08.2019 22:17:00

Моя проблема почти похожа. У меня есть незафиксированные файлы перед входом git reset --hard.

К счастью. Мне удалось пропустить все эти ресурсы. После того как я заметил, что я могу просто отменить ( ctrl-z). Just Я просто хочу добавить это ко всем ответам выше.

Заметка. Невозможно ctrl-zоткрыть неоткрытые файлы.

0
13.03.2020 10:53:44

Это спасло мне жизнь: https://medium.com/@CarrieGuss/how-to-recover-from-a-git-hard-reset-b830b5e3f60c

В основном вам нужно запустить:

for blob in $(git fsck --lost-found | awk ‘$2 == “blob” { print $3 }’); do git cat-file -p $blob > $blob.txt; done

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

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

0
20.03.2020 02:54:23