Истории успеха наших клиентов — лучшие проекты
Вход/ Регистрация

Команда git reset

1761
9 минут чтения
Средний рейтинг статьи: 3

Сегодня трудно представить работу программиста или другого IT-специалиста без контроля версий. Среди инструментов SCM особое внимание заслуживает Git, который быстро завоевал всеобщую популярность и негласно считается стандартом в мире систем контроля версий. Git позволяет легко отслеживать изменения в файлах проекта, работать с функционалом веток, организовывать совместную разработку, хранить код и другие файлы централизованно. Также одной из сильных сторон Git является возможность гибкой отмены и удаления внесенных изменений. Одним из вариантов отмены изменений является команда git reset, поддерживающая три режима работы. В рамках данной статьи мы рассмотрим, как можно отменить внесенные изменения при помощи команды git reset, а также ее режимы работы на практических примерах.

Предварительные требования

Мы будем рассматривать практическую часть работы с git reset, поэтому нам необходимо заранее установить Git. 

В качестве теста будем использовать операционную систему на ядре Linux, а именно выберем дистрибутив Ubuntu версии 22.04. Но можно использовать абсолютно любой дистрибутив Linux на ваш вкус, так как git присутствует практически во всех современных пакетных менеджерах.

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

    

Для всех остальных Debian-based-дистрибутивов (Debian, Linux Mint, Kali Linux и т.д.) установку можно выполнить из стандартных репозиториев ОС при помощи команды:

    

Если же вы решите выбрать дистрибутивы, основанные на RHEL (RedHat, CentOS, Fedora, Oracle Linux), то команда установки будет варьироваться в зависимости от используемого пакетного менеджера:

    

После того как установка будет завершена, проверим корректность установки пакета при помощи вывода версии git:

    

Описание git reset

Предназначение git reset — отмена внесенных локальных изменений. Если говорить техническим языком, то команда git reset сбрасывает указатель (ссылку) HEAD на предыдущий коммит в репозитории. Под HEAD понимается указатель на текущую ветку, который одновременно указывает еще и на последний коммит, сделанный в текущей ветке.

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

Отдельно стоит отметить, что в различных веб-сервисах, использующих git, включая GitHub, GitLab и Bitbucket, присутствует возможность отмены действий при помощи веб-интерфейса. Однако, как правило, вместо git reset используется ее другой безопасный аналог — git revert, которая отличает от reset тем, что не удаляет коммиты из истории проекта, тем самым сохраняя всю историю вносимых изменений.

Рабочий каталог

Под рабочим каталогом понимается та директория, где была выполнена команда git reset и хранятся файлы проекта, которые будут отправлены в репозиторий git. Для того чтобы система git понимала, какой каталог является рабочим, а какой нет, при выполнении команды git init в корне директории создается скрытая директория с именем .git, в которой хранятся конфигурационные файлы git.

Использование рабочего каталога выглядит следующим образом:

1) Создаем новый каталог и переходим в него:

    

2) Создаем новый репозиторий git:

    

Image14

3) После того как был инициирован новый репозиторий, в корне директории будет создана скрытая папка с именем git с  конфигурационными файлами git:

Image9

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

Указатель HEAD

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

На практике это выглядит следующим образом:

1) Создаем новый файл:

    

И добавляем его в репозиторий:

    

2) Делаем коммит:

    

Image8

3) Самый простой способ увидеть указатель HEAD — выполнить команду git cat-file:

    

Image15

Так как у нас один коммит, то указатель HEAD указывает на него. 

4) Теперь внесем изменения в ранее созданный файл new1.txt:

    

Добавляем файл в git:

    

5) Делаем коммит:

    

Image19

6) Повторно выполняем команду:

    

Image16

Как можно увидеть на скриншоте выше, указатель HEAD указывает уже на другой последний коммит в ветке.

Индекс

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

1) Создаем файл:

    

И добавляем его в индекс:

    

2) Проверяем статус:

    

Image4

Файл находится в staging-этапе, он же индекс. Файл уже отслеживается git, но еще не добавлен в коммит.

VDS и VPS

Гибкие виртуальные серверы с почасовым
биллингом по всему миру: Россия, Азия и Европа.

Режимы git reset

В своей работе git reset может использовать три различных режима — Soft, Mixed, Hard.

Режим Soft

Режим Soft используется для отмены последних внесенных изменений. С технической стороны при использовании режима soft происходит возврат указателя HEAD к указанному коммиту. При этом режим soft сохраняет все изменения, внесенные в индекс. 

На практике режим soft работает следующим образом:

1) Создадим новый файл с именем new3.txt в репозитории:

    

2) Добавляем его в индекс (staging):

    

3) Создаем коммит:

    

Смотрим историю коммитов:

    

Image18

4) Теперь представим ситуацию, когда мы сделали коммит по ошибке и нам предстоит сделать откат:

    

5) Проверяем историю коммитов:

    

Image13

Как можно заметить на скриншоте выше, ранее присутствующий последний коммит, в котором был добавлен файл new3.txt, был удален, и указатель HEAD сместился на предыдущий коммит в репозитории.

Также режим soft возвращает добавленные файлы обратно в индекс:

    

Image7

Режим Mixed

Режим Mixed используется в команде git reset по умолчанию. Режим mixed производит отмену последнего внесенного изменения в коммите, а также сброс индекса. Сами файлы при этом не затрагиваются. На практике это выглядит следующим образом:

1) Создаем три файла и добавляем их по одному:

    
    

2) Далее создаем коммит:

    

Текущая история коммитов выглядит следующим образом:

Image21

3) В итоге мы получили ситуацию, когда все три файла были добавлены в рамках одного коммита. Теперь нам необходимо отменить последнее внесенное изменение, в данном случае — отменить добавление файла с именем new3.txt:

    

4) Проверяем историю коммитов после git reset --mixed:

Image3

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

    

Image5

Файлы были возвращены в первоначальное состояние. Само содержимое файлов не затрагивается.

Режим Hard

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

1) Выведем список файлов в папке:

    

Image11

Создаем новый файл:

    

2) Добавляем файл readme.md в индекс:

    

Смотрим статус:

    

Image1

3) Делаем новый коммит:

    

Image6

4) Теперь предположим, что добавленный файл не должен присутствовать в репозитории и его необходимо удалить. Также необходимо удалить коммит и состояние индекса. Воспользуемся режимом hard команды git reset:

    

Image10

Режим hard выводит в терминале часть кэша того коммита, к которому был совершен откат.

5) Смотрим историю изменений:

    

Image22

6) Проверяем статус индекса:

    

Image12

Статус индекса тоже был удален.

7) Наконец проверяем файлы, которые остались в директории:

    

Image20

Ранее созданный файл с именем readme.md был успешно удален.

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

Откат на несколько коммитов назад 

В начале статьи было упомянуто, что команда git reset позволяет сделать откат не только на коммит назад (конструкция HEAD~1), но и на любой другой, который присутствует в репозитории. Рассмотрим на конкретном практическом примере. 

Предположим, что у нас присутствует репозиторий, в котором расположены четыре коммита:

    

Image2

Последний коммит в репозитории — это коммит с хэш-суммой bae2f49660c0807e46579fa2708040f329bc4717 и сообщением Added extra files. Например, следующая команда вернет состояние репозитория на коммит с хэш-суммой be401c3f5c55869ae04c333c9c19ef959634951a и сообщением Added new2.txt file:

    

Чтобы вернуться на два коммита назад, достаточно выполнить:

    

Проверяем текущий последний коммит:

    

Image17

Также произвести откат можно при помощи хэш-суммы коммита. Достаточно выбрать один из трех режимов (например, hard): 

    

Выгодные тарифы на VDS/VPS в Timeweb Cloud

Cloud MSK 15

477 ₽/мес

Процессор
1 x 3.3 ГГц
Память
1 ГБ
NVMe
15 ГБ
Канал
1 Гбит/с
Публичный IP
Cloud MSK 30

657 ₽/мес

Процессор
1 x 3.3 ГГц
Память
2 ГБ
NVMe
30 ГБ
Канал
1 Гбит/с
Публичный IP

Заключение

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

1761
9 минут чтения
Средний рейтинг статьи: 3
Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server