Как отменить последний коммит в git

Если у вас возникла ситуация, когда вы уже сделали коммит, но хотите добавить в него новые данные, можно воспользоваться командой:
git commit -a --amend
ключ —amend будет означать что нужно добавить новые изменения в последний коммит.
Если вы сделали коммит, но решили его удалить (отменить), то есть 2 варианта решения этого вопроса.
Чтобы отменить коммит, но ОСТАВИТЬ все изменения (файлы и правки в файлах НЕ будут удалены), нужно ввести команду:
git reset --soft HEAD^
ключ —soft указывает на то что изменения не будут удалены
Чтобы удалить коммит и все файлы (изменения), нужно ввести команду:
git reset --hard HEAD^
ключ —hard говорит о том, что нужно удалить и коммит и файлы
Также вместо значения HEAD^ вы можете указать hash любого другого коммита (не последнего).
Все эти способы работают если вы еще не опубликовали изменения на сервере. Если же нужно отменить коммит на сервере, нужно воспользоваться командой:
git revert *COMMIT-sha1* git push
где *COMMIT-sha1* — id вашего коммита
14. Отмена коммитов
Иногда вы понимаете, что новые коммиты являются неверными, и хотите их отменить. Есть несколько способов решения этого вопроса, здесь мы будем использовать самый безопасный.
Мы отменим коммит путем создания нового коммита, отменяющего нежелательные изменения.
02 Измените файл и сделайте коммит
Измените файл hello.html на следующий.
Файл: hello.html
html> head> head> body> h1>Hello, World!h1> body> html>
Выполните
git add hello.html git commit -m "Oops, we didn't want this commit"
03 Сделайте коммит с новыми изменениями, отменяющими предыдущие
Чтобы отменить коммит, нам необходимо сделать коммит, который удаляет изменения, сохраненные нежелательным коммитом.
Выполните
git revert HEAD
Перейдите в редактор, где вы можете отредактировать коммит-сообщение по умолчанию или оставить все как есть. Сохраните и закройте файл. Вы увидите:
Результат
$ git revert HEAD [main 86364a1] Revert "Oops, we didn't want this commit" Date: Tue Nov 28 05:51:38 2023 -0600 1 file changed, 1 deletion(-)
Так как мы отменили самый последний произведенный коммит, мы смогли использовать метку HEAD в качестве аргумента для отмены коммита. Мы можем отменить любой произвольной коммит в истории, указав его хеш.
04 Проверьте лог
Проверка лога показывает нежелательные и отмененные коммиты в наш репозиторий.
Выполните
git log
Результат
$ git log 86364a1 2023-11-28 | Revert "Oops, we didn't want this commit" (HEAD -> main) [Alexander Shvets] 6a44bec 2023-11-28 | Oops, we didn't want this commit [Alexander Shvets] b7614c1 2023-11-28 | Added HTML header (tag: v1) [Alexander Shvets] 46afaff 2023-11-28 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets] 78433de 2023-11-28 | Added h1 tag [Alexander Shvets] 5836970 2023-11-28 | Initial commit [Alexander Shvets]
Эта техника будет работать с любым коммитом (хотя, возможно, возникнут конфликты). Она безопасна в использовании даже в публичных ветках удаленных репозиториев.
05 Далее
Далее давайте посмотрим на технику, которая может быть использована для удаления последних коммитов из истории репозитория.
Git для начинающих. Часть 9. Как удалить коммит в git?
![]()
Рассмотрим довольно важный вопрос: как удалить коммит в git? Начнем с вопроса отмены изменений в рабочей директории, после этого перейдем к репозиторию. В рамках этой темы изучим вопросы удаления и замены последнего коммита, работу с отдельными файлами и использование команд git revert и git reset.
- Отмена изменений в файлах в рабочей директории
- Удаление коммитов в git
- Работа с последним коммитом
- Отмена изменений в файле в выбранном коммите
- Использование git revert для быстрой отмены изменений
- Удаление группы коммитов
- Удаление коммитов из репозитория (без изменения рабочей директории) (ключ –soft)
- Удаление коммитов из репозитория и очистка stage (без изменения рабочей директории) (ключ –mixed)
- Удаление коммитов из репозитория, очистка stage и внесение изменений в рабочую директорию (ключ –hard)
Отмена изменений в файлах в рабочей директории
Если вы сделали какие-то изменения в файле и хотите вернуть предыдущий вариант, то для этого следует обратиться к репозиторию и взять из него файл, с которым вы работаете. Таким образом, в вашу рабочую директорию будет скопирован файл из репозитория с заменой. Например, вы работаете с файлом main.c и внесли в него какие-то изменения. Для того чтобы вернуться к предыдущей версии (последней отправленной в репозиторий) воспользуйтесь командой git checkout.
> git checkout -- main.cКлюч “- -” означает, что нас интересует файл в текущем бранче (ветке).
Отмена коммитов в git
Работа с последним коммитом
Для демонстранции возможностей git создадим новый каталог и инициализируем в нем репозиторий.
> git initДобавим в каталог файл main.c.
> touch main.cОтправим изменения в репозиторий.
> git add main.c > git commit -m "first commit" [master (root-commit) 86f1495] first commit 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 main.c
Внесем изменения в файл.
> echo "// main.c file" > main.cИ сделаем еще один коммит.
> git add main.c > git commit -m "second commit" [master d142679] second commit 1 file changed, 1 insertion(+)
В репозиторий, на данный момент, было сделано два коммита.
> git log --oneline d142679 second commit 86f1495 first commitТеперь удалим последний коммит и вместо него отправим другой. Предварительно изменим содержимое файла main.c.
> echo "// author: Writer" > main.cОтправим изменения в репозиторий с заметой последнего коммита.
> git add main.c > git commit --amend -m "third commit" > git log --oneline 18411fd third commit 86f1495 first commit
Как вы можете видеть: из репозитория пропал коммит с id=d142679, вместо него теперь коммит с id=18411fd.
Отмена изменений в файле в выбранном коммите
Сделаем ещё несколько изменений в нашем файле main.c, каждое из которых будет фиксироваться коммитом в репозиторий.
> echo "// Some text 1" > main.c > git add main.c > git commit -m "fourth commit" [master dcf7253 ] fourth commit 1 file changed, 1 insertion(+), 1 deletion(-) > echo "// Some text 2" > main.c > git add main.c > git commit -m "fifth commit" [master 7f2eb3a ] fifth commit 1 file changed, 1 insertion(+), 1 deletion(-) > git log --oneline 7f2eb3a fifth commit dcf7253 fourth commit 18411fd third commit 86f1495 first commit
Помните, что в предыдущем разделе мы поменяли коммит с сообщением “second commit” на “third commit”, поэтому он идет сразу после “first commit”.
Представим ситуацию, что два последних коммита были неправильными, и нам нужно вернуться к версии 18411fd и внести изменения именно в нее. В нашем примере, мы работаем только с одним файлом, но в реальном проекте файлов будет много, и после коммитов, в рамках которых вы внесли изменения в интересующий вас файл, может быть ещё довольно много коммитов, фиксирующих изменения в других файлах. Просто так взять и удалить коммиты из середины ветки не получится – это нарушит связность, что идет в разрез с идеологией git. Одни из возможных вариантов – это получить версию файла из нужного нам коммита, внести в него изменения и сделать новый коммит. Для начала посмотрим на содержимое файла main.c из последнего, на текущий момент, коммита.
> git checkout main.c > cat main.c // Some text 2
Для просмотра содержимого файла в коммите с id=18411fd воспользуемся правилами работы с tree-ish (об этом подробно написано здесь)
> git show 18411fd:main.c // author: WriterПереместим в рабочую директорию файл main.c из репозитория с коммитом id=18411fd.
> git checkout 18411fd -- main.c > cat main.c // author: Writer
Мы видим, что теперь содержимое файла main.c соответствует тому, что было на момент создания коммита с id=18411fd. Сделаем коммит в репозиторий и в сообщении укажем, что он отменяет два предыдущих.
> git add main.c > git commit -m "return main.c from third commit" [master cffc5ad] return main.c from third commit 1 file changed, 1 insertion(+), 1 deletion(-) > git log --oneline cffc5ad return main.c from third commit 7f2eb3a fifth commit dcf7253 fourth commit 18411fd third commit 86f1495 first commit
Таким образом мы вернулись к предыдущей версии файла main.c и при этом сохранили всю историю изменений.
Использование git revert для быстрой отмены изменений
Рассмотрим ещё одни способ отмены коммитов, на этот раз воспользуемся командой git revert.
В нашем примере, отменим коммит с id=cffc5ad. После того как вы введете команду git revert (см. ниже), система git выдаст сообщение в текстовом редакторе, если вы согласны с тем, что будет написано в открытом файле, то просто сохраните его и закройте. В результате изменения будут применены, и автоматически сформируется и отправится в репозиторий коммит.
> git revert cffc5ad [master 81499da] Revert "return main.c from third commit" 1 file changed, 1 insertion(+), 1 deletion(-)Если вы хотите поменять редактор, то воспользуйтесь командой.
> git config core.editor "notepad.exe"Обратите внимание, что в этом случае будут изменены настройки для текущего репозитория. Более подробно об изменении настроек смотрите в “Git для начинающих. Часть 3. Настройка Git”
Проверим, применялась ли настройка.
> git config core.editor notepad.exeПосмотрим на список коммитов в репозитории.
> git log --oneline 81499da Revert "return main.c from third commit" cffc5ad return main.c from third commit 7f2eb3a fifth commit dcf7253 fourth commit 18411fd third commit 86f1495 first commitСодержимое файла вернулось к тому, что было сделано в рамках коммита с >
> cat main.c // Some text 2 > git show 7f2eb3a:main.c // Some text 2
Отмена группы коммитов
ВНИМАНИЕ! Используйте эту команду очень аккуратно!
Если вы не знакомы с концепцией указателя HEAD, то обязательно прочитайте статью “ Git для начинающих. Часть 7. Поговорим о HEAD и tree-ish“. HEAD указывает на коммит в репозитории, с которого будет вестись дальнейшая запись, т.е. на родителя следующего коммита. Существует три опции, которые можно использовать с командой git reset для изменения положения HEAD и управления состоянием stage и рабочей директории, сейчас мы все это подробно разберем.
Удаление коммитов из репозитория (без изменения рабочей директории) (ключ –soft)
Для изменения положения указателя HEAD в репозитории, без оказания влияния рабочую директорию (в stage, при этом, будет зафиксированно отличие рабочей директории от репозитория), используйте ключ –soft. Посмотрим ещё раз на наш репозиторий.
> git log --oneline 81499da Revert "return main.c from third commit" cffc5ad return main.c from third commit 7f2eb3a fifth commit dcf7253 fourth commit 18411fd third commit 86f1495 first commitСодержимое файла main.с в рабочей директории.
> cat main.c // Some text 2Содержимое файла main.с в репозитории.
> git show HEAD:main.c // Some text 2Теперь переместим HEAD в репозитории на коммит с id=dcf7253.
> git reset --soft dcf7253Получим следующий список коммитов.
> git log --oneline dcf7253 fourth commit 18411fd third commit 86f1495 first commitСодержимое файла main.c в репозитории выглядит так.
> git show HEAD:main.c // Some text 1В рабочей директории файл main.c остался прежним (эти изменения отправлены в stage).
> cat main.c // Some text 2Для того, чтобы зафиксировать в репозитории последнее состояние файла main.c сделаем коммит.
> git commit -m "soft reset example" [master db1a8b0] soft reset example 1 file changed, 1 insertion(+), 1 deletion(-)Посмотрим на список коммитов.
> git log --oneline db1a8b0 soft reset example dcf7253 fourth commit 18411fd third commit 86f1495 first commitКак видите из репозитория пропали следующие коммиты:
81499da Revert "return main.c from third commit" cffc5ad return main.c from third commit 7f2eb3a fifth commit
Удаление коммитов из репозитория и очистка stage (без изменения рабочей директории) (ключ –mixed)
Если использовать команду git reset с аргументом –mixed, то в репозитории указатель HEAD переместится на нужный коммит, а также будет сброшено содержимое stage. Отменим последний коммит.
> git reset --mixed dcf7253 Unstaged changes after reset: M main.cВ результате изменилось содержимое репозитория.
> git log --oneline dcf7253 fourth commit 18411fd third commit 86f1495 first commitСодержимое файла main.c в последнем коммите выглядит так.
> git show HEAD:main.c // Some text 1Файл main.c в рабочей директории не изменился.
> cat main.c // Some text 2Отправим изменения вначале в stage, а потом в репозиторий.
> git add main.c > git commit -m "mixed reset example" [master ab4ef00] mixed reset example 1 file changed, 1 insertion(+), 1 deletion(-)
Удаление коммитов из репозитория, очистка stage и внесение изменений в рабочую директорию (ключ –hard)
Если вы воспользуетесь ключем –hard, то обратного пути уже не будет. Вы не сможете восстановить данные из рабочей директории. Все компоненты git (репозиторий, stage и рабочая директория) будут приведены к одному виду в соответствии с коммитом, на который будет перенесен указатель HEAD.
Текущее содержимое репозитория выглядит так.
> git log --oneline ab4ef00 mixed reset example dcf7253 fourth commit 18411fd third commit 86f1495 first commitПосмотрим на содержимое файла main.c в каталоге и репозитории.
> cat main.c // Some text 2 > git show HEAD:main.c // Some text 2
Содержимое файлов идентично.
Удалим все коммиты до самого первого с id=86f1495.
> git reset --hard 86f1495 HEAD is now at 86f1495 first commit> git log --oneline 86f1495 first commitСостояние рабочей директории и stage.
> git status On branch master nothing to commit, working tree cleanСодержимое файла main.c в репозитории и в рабочей директории.
> cat main.c > git show HEAD:main.c
Т.к. мы воспользовались командой git reset с ключем –hard, то восстановить прежнее состояние нам не получится.
БУДЬТЕ ОЧЕНЬ АККУРАТНЫ С ЭТОЙ КОМАНДОЙ!
Отличный курс по git делают ребята из GeekBrains , найдите в разделе “Курсы” курс “Git. Быстрый старт” , он бесплатный!
Раздел: Git Git для начинающих Метки: Git, Git для начинающих, Уроки по Git
Git для начинающих. Часть 9. Как удалить коммит в git? : 2 комментария
- Paul 12.04.2018 Работа с последним коммитом:
git commit –amend -m “third commit” Это отменяет последний коммит, но не возвращает файл в исходное состояние.
А в какой задаче это может быть полезно?
- adminka 14.04.2018 Эта команда перезаписывает последний коммит (т.е. последний удаляется и на его место встает новый), файл в исходное состояние не возвращается.
А в какой задаче это может быть полезно?
хм… хороший вопрос! Даже затрудняюсь на него ответить. Ну например, вы закоммитили какой-то “ужас” и не хотите, чтобы он стал достоянием общественности))
Как удалить commit на Github?
1. Как удалить самый первый тестовый комит на гитхаб
пробывал git reset —hard HEAD, но он один, и поэтому не могу нигде найти как его удалить
И как это сделать так что бы на гитхабе его тоже не было.
p.s только начал пользоваться гитом поэтому сори за возможно глупые вопросы- Вопрос задан более двух лет назад
- 6930 просмотров
Комментировать
Решения вопроса 2
Сергей Кузнецов @sergey-kuznetsov Куратор тега Git
АвтоматизаторРаз первый коммит единственный и он тебе не нужен, то можно просто удалить репозиторий на GitHub и создать заново. Но можно и не пересоздавать:
# удалить все файлы в рабочей копии git rm -r * # создать на месте первого коммита пустой коммит git commit --allow-empty --amend --message "Initial commit" # отправить текущую ветку на GitHub git push --forceПолучишь чистый репозиторий с начальным пустым коммитом.
Сам пустой коммит можно использовать как основу для построения своего дерева коммитов.
Либо через ключ —amend замени его на что-то более осмысленное.А ещё лучше не заниматься ерундой, исправить код и исправить коммит ключиком —amend
Ответ написан более двух лет назад
Нравится 1 14 комментариев
ebaysher @ebaysher Автор вопроса$ git rm *
fatal: not removing ‘Chess’ recursively without -r
Сделал:
git rm -r Chess
git commit —allow-empty —amend —all —message «Initial commit»
git push —force,
Содержимое коммита не изменилось (кроме названия),
а весь код в файле Chess удалился
Как откатить теперь назад и вернуть код?
Сергей Кузнецов @sergey-kuznetsov Куратор тега Git
Тогда так
git rm -r .
Удалить желательно всёПотом закоммитить факт удаления и посмотреть содержимое коммита перед тем как пушить.
Что значит код в файле удалился? Должен был удалиться не код, а сам файл. Точнее все файлы по маске .
ebaysher @ebaysher Автор вопроса
Сергей Кузнецов, У меня почему то после команды git rm -r, студия загрузилась и удалились неколько файлов с классами. Теперь пытаюсь разобраться как назад откатить.

Сергей Кузнецов @sergey-kuznetsov Куратор тега Git
Если речь про https://github.com/ebaysher/chess
то там вообще нет такого файла или папки. Удали всё руками просто в проводнике.
И потом коммит.Ты точно уверен что надо удалить коммит? Вариант с исправлением кода на нужный не подходит?