Как отменить локальный коммит

745

Моя проблема в том, что я изменил файл, например: 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. Этого не должно быть. Мне нужен контент, чтобы быть там. Есть ли способ сохранить контент и отменить мой локальный коммит?

Амаль Кумар С
источник
3
Похоже, что вы определенно не просите git revert, что создает новый коммит с обратным дифференциалом от обратного коммита. Сброс просто указывает текущую ветвь на другой коммит, в данном случае тот, что перед коммитом, который вы хотите «забыть».
Каскабель
1
NB: Стоит упомянуть, что git-commitможет прерваться, если вы оставите сообщение пустым, поэтому, если вы еще не закончили коммит, это может быть полезно.
GKFX

Ответы:

1425

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

git reset HEAD~1

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

Koraktor
источник
13
Кстати, это называется --mixed в руководстве .
Джош Ли
10
Более новые версии Git даже позволяют @^в качестве сокращения HEAD^.
Koraktor
Я не знаю, что это сделало, но в моем списке изменений появилось много файлов, файлов, которых я не трогал
FRR
@feresr Если вы действительно не трогали эти файлы во время последнего коммита или в рабочем дереве, это вызвано другими несоответствиями в вашем рабочем дереве, например, в Windows, и окончания файлов не совпадают.
Koraktor
1
Можно ли сбросить все коммиты с одной стороны?
веб-женщина
185

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

git reset --soft HEAD^
директива TPED
источник
18
Можете ли вы объяснить разницу между 2 флагами?
Джон Джотта
1
Если вы откроете консоль диспетчера пакетов и запустите этот «git reset --soft HEAD ^», он сделает то, что вы хотите (и то, что мне было нужно).
Дэвид Корнельсон
54
@JohnGiotta - git reset --soft HEAD^удалит последний локальный (unpushed) совершить , но будет держать изменения , которые вы сделали
Fider
@fider Спаситель! Не уверен, что принятый ответ все еще работает, но это должен быть точный ответ, необходимый ОП.
Бабу
git reset --soft HEAD~на окнах
Jack0fshad0ws
34

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

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

Это должно выглядеть так.

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

РЕДАКТИРОВАТЬ :

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

Чтобы удалить все строки в vim (если это ваш редактор по умолчанию), как только вы окажетесь в редакторе, напечатайте, ggчтобы перейти к первой строке, а затем dGудалить все строки. Наконец, напишите и выйдите из файла, wqи ваш коммит будет прерван.

inostia
источник
3
Это именно то , что я искал! Этот ответ нуждается в большем количестве голосов :)
jdunk
К вашему сведению, это также работает, если вы пытаетесь прерватьrebase -i mybranchname
Иностия
18

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

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

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

git reset --soft commit_id

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

git reset --hard commit_id

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

mistdon
источник
1
Я думаю, что это наоборот.
Ruff9
9

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

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

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

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

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

Неша Зорич
источник
1

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

$ git reset HEAD~1

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

Unstaged changes after reset:
M   application/config/config.php
M   application/config/database.php
Omkar
источник