Команды git reset, git checkout и git revert – одни из самых полезных в Git. Все они позволяют отменять изменения в вашем репозитории, а первые две могут применяться как к коммитам, так и к отдельными файлам.
Поскольку они очень похожи, легко запутаться в выборе подходящей команды для различных сценариев разработки. В данной статье мы рассмотрим самые распространенные варианты использования команд git reset
, git checkout
, и git revert
. Надеемся, после прочтения вы сможете уверенно управлять своим репозиторием с помощью любой из них.
Содержание
- Обзор команд
- Сравнение git reset, git revert и git checkout
- Команды на уровне коммита
- Команды на уровне файлов
- Заключение
Обзор команд

Лучше всего рассматривать каждую команду с точки зрения их влияния на три механизма управления состоянием репозитория Git: рабочая директория, снимок состояния/индекс и историю коммитов. Эти компоненты также иногда называют “тремя деревьями” Git.
Друзья, поддержите нас вступлением в наш телеграм канал QaRocks. Там много туториалов, задач по автоматизации и книг по QA.
Переключение версий (команда checkout
) перемещает указатель HEAD
на указанный коммит. Покажем это на следующем примере.

В примере показана последовательность коммитов в ветке main
. Сейчас и ссылка HEAD
, и ссылка ветки main
указывают на коммит d
. Теперь давайте выполним команду git checkout b
.

Это обновление дерева «истории коммитов». Команду git checkout
можно использовать на уровне коммита или файла. Если применить её к файлу, его содержимое будет отражать состояние при указанном коммите.
Операция отмены (команда revert
) принимает в качестве аргумента коммит и создает новый, который обращает изменения, внесенные в указанный коммит. git revert
действует только на уровне коммита и не работает для файлов.
Операция сброса (команда reset
) принимает в качестве аргумента коммит и сбрасывает «три дерева» до состояния репозитория при указанном коммите. Ее можно использовать в трех разных режимах, соответствующих трем деревьям.
Команды checkout
и reset
обычно применяются для локальной или приватной отмены изменений. Следует помнить, что эти команды изменяют историю репозитория, из-за чего могут возникнуть конфликты при отправке изменений в общий репозиторий. Для безопасной отмены изменений в таком случае подойдет revert
, поскольку она добавляет в историю новые данные, а не перезаписывает старые, от которых могут зависеть участники команды.
Сравнение git reset, git revert и git checkout
В таблице ниже приведены наиболее распространенные сценарии использования данных команд. Сохраните ее, поскольку вам, несомненно, придется использовать хотя бы некоторые из этих сценариев при работе с Git.
Команда | Область применения | Общие случаи использования |
---|---|---|
git reset | На уровне коммита | Откат коммитов в приватной ветке или удаление незакоммиченных изменений |
git reset | На уровне файла | Удаление файла из индекса |
git checkout | На уровне коммита | Переключение между ветками или проверка старых снимков состояния |
git checkout | На уровне файла | Отмена коммитов в публичной ветке |
git revert | На уровне коммита | Отмена фиксаций в публичной ветке |
git revert | На уровне файла | Не применимо |
Команды на уровне коммита
Параметры, которые вы передаете в командах git reset
и git checkout
, определяют область их действия. Если в качестве параметра не указан путь к файлу, они действуют на весь коммит. Данный раздел посвящен работе на этом уровне. Обратите внимание, что git revert
не применяется для файлов.
Сброс (reset) коммита
На уровне коммита команда reset
позволяет перенести конец ветки (последний коммит) на другой коммит. Таким образом можно удалять коммиты из текущей ветки. Например, следующая команда перемещает ветку hotfix
на два коммита назад.
git checkout hotfix git reset HEAD~2
У двух коммитов, которые располагались в конце ветки hotfix
, теперь нет родителя и ссылки. Поэтому при следующей сборке мусора Git удалит их. Иными словами, вы выбрасываете эти коммиты. Выглядит это следующим образом:


Команда git reset
— это простой способ отменить изменения, которые еще никто не получал. Она прекрасно подойдет, когда вы начали работать с кодом и вдруг поняли, что лучше начать все сначала.
Помимо изменения текущей ветки, с помощью команды git reset
можно также изменить снимок состояния индекса и (или) рабочий каталог, указав один из следующих флагов:
--soft
– снимок состояния индекса и рабочий каталог никак не изменяются.--mixed
– снимок состояния индекса обновляется в соответствии с указанным коммитом, а рабочий каталог остается неизменным. Это вариант по умолчанию.--hard
– снимок состояния индекса и рабочий каталог обновляются в соответствии с указанным коммитом.
Эти режимы помогают понять, на что влияет команда git reset
. Для более подробной информации смотрите страницу git reset.
Переключение (checkout) на старые коммиты
Команду git checkout
используют для обновления состояния репозитория до определенной точки в истории проектов. Если в команде передать имя ветки, она позволяет переключиться на нее.
git checkout hotfix
Технически, эта команда просто перемещает указатель HEAD
на другую ветку и обновляет рабочий каталог в соответствии с ней. Поскольку при этом можно перезаписать локальные изменения, Git требует закоммитить изменения в рабочем каталоге, которые будут потеряны при операции checkout
, или отправить их в стэш. В отличие от git reset
, команда git checkout
не переносит ветки.


Кроме того, можно переключаться на любые коммиты, указывая ссылку на коммит вместо ветки. Работает это аналогично переключению ветки: команда перемещает указатель HEAD
на переданный коммит. Например, следующая команда переключит версию на два шага до текущего коммита:
git checkout HEAD~2

Это бывает полезно, когда нужно быстро изучить старую версию проекта. Однако, поскольку ссылка на текущий указатель HEAD
отсутствует, это переводит систему в состояние с открепленным HEAD
. Это может быть опасно, если вы будете добавлять новые коммиты, потому что после перехода на другую ветку у вас не будет возможности вернуться к ним. Поэтому перед добавлением коммитов с открепленным указателем HEAD
всегда следует создавать новую ветку.
Отмена коммитов, внесенных в общий доступ, с помощью revert
При использовании команды revert
коммит отменяется путем создания нового коммита. Это безопасный способ отменить изменения, поскольку при нем невозможно перезаписать историю. Например, следующая команда определит изменения, содержащиеся во втором коммите с конца, создаст новый, в котором этих изменений не будет, и добавит его к проекту.
git checkout hotfix git revert HEAD~2
Выглядит это следующим образом:


Сравните это с командой git reset
, которая меняет существующую историю коммитов. Поэтому команду git revert
лучше использовать для отмены изменений в общей ветке, а git reset
лучше оставить для сброса изменений в приватной.
Либо же можно рассматривать git revert
как инструмент для отмены изменений, попавших в коммиты, в то время как команда git reset HEAD
предназначена для отмены изменений, не попавших в коммиты.
Как и git checkout
, команда git revert
может перезаписать файлы в рабочем каталоге и поэтому предложит отправить изменения, которые будут потеряны при отмене, в стэш.
Команды на уровне файлов
Команды git reset
и git checkout
также принимают в качестве параметра необязательный путь к файлу. Это кардинально меняет их поведение. Вместо того чтобы работать с целыми снимками, они вынуждены ограничиваться одним файлом.
Отмена изменений в файле с помощью git reset
При вызове с указанием пути к файлу команда git reset
обновляет индекс, чтобы он соответствовал версии из указанного коммита. Команда ниже получит версию файла foo.py во втором коммите и занесет ее в индекс для следующего коммита:
git reset HEAD~2 foo.py
Как и в случае с версией git reset
на уровне коммита, этот вариант чаще используется с указателем HEAD
, а не с конкретным коммитом. Команда git reset HEAD foo.py
удалит файл foo.py из индекса. Содержащиеся в нем изменения по-прежнему будут присутствовать в рабочем каталоге.

Флаги --soft
, --mixed
и --hard
не влияют на работу команды git reset
на уровне файла, поскольку снимок состояния индекса обновляется всегда, а рабочий каталог — никогда.
Восстановление файла с помощью git checkout
Команда checkout
для файла аналогична использованию git reset
с указанием пути к файлу, за исключением того, что она обновляет рабочую директорию, а не индекс. В отличие от версии на уровне коммитов, эта команда не перемещает указатель HEAD
, а значит, вы не переключитесь на другие ветки.

Для примера, после выполнения следующей команды, файл foo.py в рабочей директории будет совпадать с его версией из второго коммита:
git checkout HEAD~2 foo.py
Как и вызов git checkout
на уровне коммита, эту команду можно использовать для просмотра старых версий проекта, только область действия будет ограничена указанным файлом.
Если вы выполните индексирование и коммит для файла, на который переключились, это приведет к восстановлению старой версии файла. Обратите внимание, что при этом удаляются все последующие изменения в файле, тогда как команда git revert
отменяет только те изменения, которые были в указанном коммите.
Как и git reset
, эту команду обычно используют с указателем HEAD
в качестве ссылки на коммит. Например, команда git checkout HEAD foo.py
отменит неиндексированные изменения в файле foo.py. Это поведение аналогично команде git reset HEAD --hard
, но действует только на указанный файл.
Смотрите также: “Настройка Git репозитория”.
Заключение
Теперь у вас есть все необходимые инструменты для отмены изменений в Git. В командах git reset, git checkout и git revert легко запутаться, но учитывая их воздействие на рабочую директорию, снимок состояния/индекс и историю коммитов, вы сможете легче определять, какая команда подойдет для вашей задачи.
Перевод статьи «Resetting, checking out & reverting».