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

Как отменить изменения в Git

Александр Бархатов
Александр Бархатов
Технический писатель
27 марта 2024 г.
228
7 минут чтения
Средний рейтинг статьи: 5

При работе с системой контроля версий Git вы можете в любой момент отменить внесенные изменения. В Git существует несколько способов, которые позволяют отменить последние внесенные изменения в необходимом коммите или ветки.

Отмена изменений при помощи команды git reset

Одним из основных способов отмены (удаления) внесенных изменений в Git является команда git reset. Команда git reset предназначена для удаления коммита путем переноса указателя HEAD назад к более старому (предыдущему) коммиту. Тем самым git reset эмулирует ситуацию, как будто последнего коммита вообще не существовало.

Рассмотрим применение git reset на конкретном примере. Предположим, мы только что сделали коммит, но поняли что забыли внести изменения или добавить нужный файл. Один из способов отмены внесенных изменений — сделать откат к предыдущему коммиту. Для этого воспользуемся следующей командой:

git reset HEAD~1

Где:

  • HEAD — указатель на текущую ветку, а также указатель на последний коммит в этой ветке;
  • ~1 — количество коммитов, на которое необходимо произвести откат. В данном случае откат будет произведен на один коммит назад.

Команда выше произведет откат на один коммит назад, при этом текущая рабочая директория и индекс Git останутся неизменными. На реальном примере это выглядит так:

  1. В директории присутствует файл test1.txt со следующим содержимым:
Hello, world!

Image11

Данный файл присутствует в git:

Image6

  1. Внесем изменения в файл test1.txt, удалив из него world!, и применим данное изменение. В итоге у нас появится два коммита:

Image2

  1. Теперь откатим изменения на последний коммит, в котором была строка Hello, world!:
git reset HEAD~1

Image4

  1. Проверяем, что мы успешно откатились до предыдущего коммита:
git log

Image6

Обратите внимание, что второй коммит был удален. Также содержимое файла test1.txt осталось нетронутым.

Несмотря на то, что команда git reset кажется довольно простой в использовании, она поддерживает несколько различных режимов. Рассмотрим эти режимы более подробно.

Режим Soft

Режим soft предназначен для отмены последних коммитов. Изменения, которые были внесены в сами файлы, остаются в индексе. При использования режима soft указатель HEAD перемещается на выбранное количество коммитов назад. Изменения остаются в разделе проиндексированных файлов и в рабочем каталоге. Дерево объектов также не изменяется.

Рассмотрим работу режима soft на практике. Предположим, мы сделали ошибочный коммит, и нам надо откатиться назад.

  1. Создаем новый файл в директории с именем new-file.txt и добавляем его в индекс:
touch new-file.txt
git add new-file.txt
  1. Делаем ошибочный коммит:
git commit -m "Add new-file.txt"

Image3

  1. Далее производим откат до предыдущего состояния репозитория, используя параметр soft:
git reset --soft HEAD~1
  1. Проверяем статус изменений:
git status

Image7

Как можно заметить, добавленный ранее файл new-file.txt был возвращен в индекс, об этом в частности говорят строки:

Changes to be committed:
 (use "git restore --staged <file>..." to unstage)
new file:   new-file.txt
  1. Теперь можно создать новый правильный коммит:
git commit -m "new correct commit"

Image9

Режим Mixed 

Mixed — режим, используемый по умолчанию. Предназначен для отмены последних внесенных изменений в коммите, а также сбрасывания индекса. При этом рабочая директория остается без изменений. Фактически команда git reset --mixed аналогична команде git reset.

Рассмотрим принцип работы режима mixed на практике. Например, мы сделали коммит в который включили лишний файл. Нам необходимо сбросить индекс с дальнейшим добавлением только необходимых файлов. Воспроизведем данную ситуацию:

  1. Добавляем в индекс следующие файлы: test1.txt, test2.txt, test3.txt и после каждого добавленного файла делаем коммит:
git add test1.txt
git commit -m "Added test1.txt file"
git add test2.txt
git commit -m "Added test2.txt file"
git add test3.txt
git commit -m "Added test3.txt file"
  1. Последний файл test3.txt оказался лишним. Необходимо его убрать из индекса, но при этом не удалять. Для этого выполним команду:
git reset --mixed HEAD~1

Аналогом команды выше является команда:

git reset HEAD~1

Она выполнит откат изменения на один коммит назад (в данном случае до коммита Added test2.txt file).

  1. Далее добавляем необходимый файл и делаем коммит:
git add test4.txt
git commit -m "Added test4.txt file"

Режим Hard

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

Рассмотрим принцип работы режима hard на практике. 

  1. Предположим, мы добавили лишний файл и сделали коммит:
git add another_new_file.txt
git commit -m "Added another file"
  1. Так как добавленный файл another_new_file.txt нам больше не нужен, мы можем полностью его удалить. Для этого воспользуемся командой:
git reset --hard HEAD~1

Команда выше удалит ранее добавленный файл another_new_file.txt, его коммит, а также его индекс.

Отмена изменений при помощи команды git revert

Еще одним способом отмены внесенных изменений является команда git revert. git revert отличается от git reset, несмотря на то, что обе эти команды выполняют одну и ту же функцию — отменяют изменения. В то время как git reset изменяет историю репозитория при помощи перемещения указателя ветки (HEAD) на необходимый коммит, git revert создает новый коммит, а также не удаляет историю с ранее внесенными изменениями (коммитами). Тем самым вы полностью сохраняете структуру изменений вашего проекта. 

Рассмотрим применение git revert на практике. Предположим, у нас есть следующая история коммитов:

Image8

Нам необходимо сделать откат до третьего коммита с именем Edit test1.txt file и хэш-суммой 536ac2cb42030f4de9ebf6fca977b6588487c016. Для этого воспользуемся командой:

git revert HEAD~2

При выполнении команды выше откроется меню с вводом сообщения для нового коммита. Это эквивалентно вводу сообщения при помощи ключа -m при использовании команды git commit. Можно как ввести свое сообщение, так и оставить текст по умолчанию в формате "Revert <имя_коммита_к_которому_был_произведен_откат>".

После этого проверяем историю коммитов (git log) и обнаруживаем новый коммит с пометкой revert, в котором сказано, что данный коммит является revert-коммитом от коммита с именем Edit test1.txt:

Image5

Тем самым мы не только сделали откат необходимого изменения, но и сохранили саму историю изменений.

Отмена изменений при помощи команды git checkout

Несмотря на то, что команда git checkout предназначена для работы с ветками (в частности, для создания новых веток, а также для переключения между существующими ветками), ее можно использовать для отката изменений в одном определенном файле или в нескольких файлах сразу.

Предположим, мы внесли некоторые изменения в файл script.sh и сделали коммит, однако вскоре поняли, что внесенные изменения нас не устраивают и нам необходимо вернуться к последнему коммиту для файла script.sh. В таком случае необходимо выполнить команду:

git checkout HEAD -- script.sh

Команда выше вернет состояние файла script.sh к последнему коммиту, который был сделан для файла script.sh.

Если же необходимо вернуться не к последнему коммиту, а к другому, то необходимо знать хэш-сумму нужного коммита. Для этого сначала воспользуемся командой git log, которая отобразит историю коммитов:

git log

Image1

Хэш-сумма отображается после слова commit. В данном случае откатимся к коммиту с хэш-суммой e4dfe5bf3bab71add158ac1ca5dc3c59dc5ff38e. Для этого выполняем команду:

git checkout e4dfe5bf3bab71add158ac1ca5dc3c59dc5ff38e -- script.sh

Заключение

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

Зарегистрируйтесь и начните пользоваться
сервисами Timeweb Cloud прямо сейчас

15 лет опыта
Сосредоточьтесь на своей работе: об остальном позаботимся мы
165 000 клиентов
Нам доверяют частные лица и компании, от небольших фирм до корпораций
Поддержка 24/7
100+ специалистов поддержки, готовых помочь в чате, тикете и по телефону