Можно сказать, что команда git revert представляет собой типичную команду отмены. Однако принцип ее действия отличается от привычного отката изменений. Вместо удаления коммита из истории проекта эта команда обращает внесенные изменения и добавляетновый коммит с полученным содержимым. Такая операция обеспечивает целостность истории версий Git и надежность совместной работы.

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

git revert — обучающие руководства Atlassian по Git

Порядок действий

Команда git revert используется для отката изменений в истории коммитов репозитория. Другие команды отмены, такие как git checkout и git reset, перемещают указатель HEAD и указатели ветки на определенный коммит. Команда git revert также работает с определенным коммитом, но при этом использование git revert не перемещает указатели. При операции отката (revert) совершается переход к указанному коммиту, обращаются его изменения и создается новый, «обращенный» коммит. Затем позиция указателей обновляется — они перемещаются к этому коммиту в конце ветки.

Для наглядности создадим тестовый репозиторий и напишем в командной строке следующее:

$ mkdir git_revert_test
$ cd git_revert_test/
$ git init .
Initialized empty Git repository in /git_revert_test/.git/
$ touch demo_file
$ git add demo_file
$ git commit -am"initial commit"
[master (root-commit) 299b15f] initial commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 demo_file
$ echo "initial content" >> demo_file
$ git commit -am"add new content to demo file"
[master 3602d88] add new content to demo file
n 1 file changed, 1 insertion(+)
$ echo "prepended line content" >> demo_file
$ git commit -am"prepend content to demo file"
[master 86bb32e] prepend content to demo file
1 file changed, 1 insertion(+)
$ git log --oneline
86bb32e prepend content to demo file
3602d88 add new content to demo file
299b15f initial commit

Мы выполнили инициализацию репозитория в новом каталоге git_revert_test. В репозитории мы сделали три коммита: добавили файл demo_file и дважды изменили его содержимое. В конце настройки репозитория мы запустили команду git log, чтобы просмотреть историю коммитов (в ней содержится 3 коммита). Теперь можно запустить команду git revert.

$ git revert HEAD
[master b9cd081] Revert "prepend content to demo file"
1 file changed, 1 deletion(-)

Команда git revert не будет работать без назначения ссылки на коммит. В примере мы указали ссылку HEAD, чтобы обратить изменения последнего коммита. То же самое произошло бы при откате до коммита 3602d8815dbfa78cd37cd4d189552764b5e96c58. Как и слияние, операция отката создаст новый коммит. Затем в открывшемся настроенном системном редакторе будет предложено набрать его сообщение. После ввода и сохранения сообщения Git продолжит операцию. Теперь мы можем узнать состояние репозитория с помощью команды git log. Мы видим, что к журналу добавлен новый коммит:

$ git log --oneline
1061e79 Revert "prepend content to demo file"
86bb32e prepend content to demo file
3602d88 add new content to demo file
299b15f initial commit

Обратите внимание, что третий коммит по-прежнему содержится в истории проекта после отката. Вместо его удаления команда git revert добавила новый коммит для отката изменений. В результате второй и четвертый коммиты представляют собой одну и ту же базу кода, а третий коммит хранится в истории на случай, если в дальнейшем нам понадобится к нему вернуться.

Распространенные опции

-e
--edit

Это опция по умолчанию, и указывать ее необязательно. Она открывает настроенный системный редактор, в котором вам будет предложено изменить сообщение коммита перед откатом.

--no-edit

Действие этой опции обратно опции -e. Редактор не откроется во время отката.

-n
--no-commit

Назначьте эту опцию, чтобы команда git revert не создавала новый коммит, обратный целевому по своему содержанию. Вместо этого обращенные изменения будут добавлены в промежуточный индекс и рабочий каталог. Это деревья, с помощью которых Git управляет состоянием репозитория. Подробную информацию см. на странице команды git reset.

Разница между командами git reset и git revert

Важно понимать, что команда git revert отменяет один коммит. Она не возвращает проект в предыдущее состояние с удалением всех последующих коммитов — такой результат в Git дает команда reset.

Сравнение git revert и git reset — обучающие руководства Atlassian по Git

У команды revert есть два значительных преимущества перед командой reset. Во-первых, она не изменяет историю проекта и поэтому безопасна для коммитов, которые уже опубликованы в общем репозитории. Подробнее о том, почему изменять общую историю опасно, см. на странице команды git reset.

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

Заключение

Команда git revert — это операция для безопасной отмены изменений, действие которой направлено на следующие коммиты. Для отката изменений команда не удаляет коммиты или родительские элементы, a создает новый коммит. С командой git revert потерять код сложнее, чем при использовании команды git reset. Чтобы показать применение команды git revert, в примерах использовались другие команды. Подробные сведения по ним см. на страницах команд git log, git commit и git reset.

Готовы изучить команду git revert?

Ознакомьтесь с этим интерактивным обучающим руководством.

Начните прямо сейчас