Как отменить локальную фиксацию git

Моя проблема в том, что я изменил файл, например: README, добавил новую строку «это для моей тестовой строки» и сохранил файл, затем я выполнил следующие команды

git status

# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   README
#
no changes added to commit (use "git add" and/or "git commit -a")


git add README

git commit -a -m 'To add new line to readme'

Я не отправлял код на github, теперь хочу отменить эту фиксацию.

Для этого я использовал

git reset --hard HEAD~1

Но я потерял недавно добавленную строку «это для моей тестовой строки» из файла README. Этого не должно происходить. Мне нужно, чтобы контент был там. Есть ли способ сохранить содержимое и отменить локальную фиксацию?


person Amal Kumar S    schedule 31.01.2011    source источник
comment
Похоже, вы определенно не просите git revert, который создает новую фиксацию с обратной разницей отмененной фиксации. Сброс просто указывает вашу текущую ветвь на другую фиксацию, в данном случае на ту, которая была перед фиксацией, которую вы хотите забыть.   -  person Cascabel    schedule 31.01.2011
comment
NB: Возможно, стоит упомянуть, что git-commit может прерваться, если вы оставите сообщение пустым, поэтому, если вы на самом деле не завершили фиксацию, это может быть полезно.   -  person GKFX    schedule 24.02.2014


Ответы (6)


Просто используйте git reset без флага --hard:

git reset HEAD~1

PS: В системах на базе Unix вы можете использовать HEAD^, что равно HEAD~1. В Windows HEAD^ не будет работать, потому что ^ сигнализирует о продолжении строки. Итак, ваша командная строка просто спросит вас More?.

person Koraktor    schedule 31.01.2011
comment
Кстати, это называется --mixed в руководство. - person Josh Lee; 31.01.2011
comment
В более новых версиях Git даже допускается @^ в качестве сокращения для HEAD^. - person Koraktor; 16.09.2014
comment
Я не знаю, что это произошло, но в моем списке изменений появилось много файлов, которые я не трогал - person frankelot; 05.02.2015
comment
@feresr Если вы действительно не трогали эти файлы в последнем коммите или в рабочем дереве, это вызвано другими несоответствиями в вашем рабочем дереве, например у вас Windows и окончания файлов не совпадают. - person Koraktor; 06.02.2015
comment
У меня есть 10 отложенных коммитов из-за проблемы с размером ... и ваше решение - изолированный шторм во время засушливого лета ... ^ _ ^ - person RYO ENG Lian Hu; 28.04.2016
comment
да! эта линия избежала катастрофы мэра ... добрый, хранитель! - person Pedro Emilio Borrego Rached; 05.09.2019
comment
можно ли сбросить все коммиты с одной стороны? - person Webwoman; 08.09.2019

Используйте --soft вместо флага --hard:

git reset --soft HEAD^
person TpED    schedule 10.08.2012
comment
Вы можете объяснить разницу между двумя флагами? - person John Giotta; 05.05.2015
comment
Если вы откроете консоль диспетчера пакетов и запустите этот git reset --soft HEAD ^, он сделает то, что вы хотите (и то, что мне нужно). - person David Cornelson; 03.12.2015
comment
@JohnGiotta - git reset --soft HEAD^ удалит последнюю локальную (не отправленную) фиксацию, но сохранит сделанные вами изменения - person fider; 25.04.2016
comment
@fider Спаситель! Не уверен, что принятый ответ по-прежнему работает, но это должен быть точный ответ, необходимый OP. - person Babu; 27.12.2017
comment
git reset --soft HEAD~ в windows - person Jack0fshad0ws; 14.05.2020

Если вы находитесь в середине фиксации (т.е. уже находитесь в редакторе), вы можете отменить ее, удалив все строки выше первого #. Это прервет фиксацию.

Таким образом, вы можете удалить все строки, чтобы сообщение фиксации было пустым, а затем сохраните файл:

«Это

Затем вы получите сообщение Aborting commit due to empty commit message..

person inostia    schedule 09.03.2017
comment
Это именно то, что я искал! Этот ответ требует больше голосов :) - person jdunk; 11.06.2017
comment
К вашему сведению, это также работает, если вы пытаетесь прервать rebase -i mybranchname - person inostia; 30.04.2018
comment
это действительно должен быть ответ. - person Xaxxus; 07.01.2021

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

Используйте git log, чтобы отобразить текущие сообщения о фиксации, затем найдите commit_id перед фиксацию, которую вы хотите удалить, а не фиксацию, которую вы хотите удалить.

Если вы хотите сохранить локально измененные файлы и просто удалить сообщение фиксации:

git reset --soft commit_id

Если вы хотите удалить все локально измененные файлы и сообщение о фиксации:

git reset --hard commit_id

В этом разница между мягким и жестким

person mistdon    schedule 02.09.2018
comment
Думаю, все наоборот. - person Ruff9; 10.09.2018

Вы можете указать Git, что делать с вашим индексом (набором файлов, которые станут следующей фиксацией) и рабочим каталогом при выполнении git reset, используя один из параметров:

--soft: сбрасываются только коммиты, в то время как индекс и рабочий каталог не изменяются.

--mixed: Это приведет к сбросу индекса в соответствии с HEAD, в то время как рабочий каталог не будет затронут. Все изменения останутся в рабочем каталоге и будут отображаться как измененные.

--hard: сбрасывает все (фиксации, индекс, рабочий каталог) в соответствии с HEAD.

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

person Nesha Zoric    schedule 29.05.2018

Используйте команду ниже:

$ git reset HEAD~1

После этого вы также сможете просматривать файлы, которые возвращаются, как показано ниже.

Unstaged changes after reset:
M   application/config/config.php
M   application/config/database.php
person Omkar    schedule 14.05.2018