Как отменить коммит Git без потери изменений

GitBeginner
Практиковаться сейчас

Введение

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

Просмотр истории коммитов

Прежде чем вносить какие-либо изменения, важно понять текущее состояние нашего проекта. Лабораторная среда была предварительно настроена с репозиторием Git, содержащим файл с именем story.txt и несколько коммитов. Давайте просмотрим историю коммитов.

Сначала используйте команду git log с опцией --oneline для получения компактного представления истории коммитов. Эта команда выводит каждый коммит в одной строке, показывая хэш коммита и сообщение коммита.

git log --oneline

Вы должны увидеть вывод, похожий на этот. Обратите внимание, что ваши хэши коммитов будут отличаться:

c7a3e69 (HEAD -> master) Add a second, unwanted line
a9b2d5f Add the first line to the story
f3e1c8a Initial commit: Add story.txt

Этот лог показывает три коммита. Самый последний коммит, находящийся вверху, имеет сообщение "Add a second, unwanted line". Давайте представим, что этот коммит внес ошибку, которую нам нужно исправить.

Давайте также посмотрим текущее содержимое файла story.txt:

cat story.txt

Вывод будет следующим:

Once upon a time, in a land of code.
The hero of our story was a brave developer.
Suddenly, a wild bug appeared!

Наша цель — удалить последнюю строку, "Suddenly, a wild bug appeared!", которая была добавлена в нашем самом последнем коммите.

Использование git revert для безопасной отмены изменений

Команда git revert используется для создания нового коммита, который отменяет изменения из предыдущего коммита. Это безопасный метод отмены изменений, поскольку он не изменяет историю проекта.

Сначала скопируйте хэш коммита, который вы хотите отменить. Из вывода предыдущего шага, это коммит с сообщением "Add a second, unwanted line".

Теперь выполните команду git revert с этим хэшем.

Пожалуйста, замените <your-commit-hash> на фактический хэш из вашего терминала.

git revert <your-commit-hash>

После выполнения этой команды Git откроет ваш редактор текста по умолчанию (nano), чтобы позволить вам отредактировать сообщение коммита для этого нового коммита отмены. Сообщение по умолчанию обычно достаточно.

Чтобы сохранить и выйти из nano:

  1. Нажмите Ctrl+O (Write Out) и затем Enter для подтверждения имени файла.
  2. Нажмите Ctrl+X для выхода.

Теперь давайте снова проверим историю коммитов:

git log --oneline

Вы увидите новый коммит вверху:

e0d5f1b (HEAD -> master) Revert "Add a second, unwanted line"
c7a3e69 Add a second, unwanted line
a9b2d5f Add the first line to the story
f3e1c8a Initial commit: Add story.txt

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

Наконец, проверьте содержимое story.txt, чтобы убедиться, что изменение было отменено:

cat story.txt

Теперь вывод должен быть следующим:

Once upon a time, in a land of code.
The hero of our story was a brave developer.

Нежелательная строка была успешно удалена.

Отмена изменений с сохранением с помощью --no-commit

Иногда вы хотите отменить изменения из коммита, но сохранить их в вашей рабочей директории для дальнейшего изменения. Например, вы можете захотеть исправить ошибку в коммите, а не полностью отбрасывать его. Опция --no-commit (или -n) идеально подходит для этого.

Сначала давайте сбросим наш репозиторий к состоянию перед последней отменой, чтобы попробовать другой подход. Для этого мы используем git reset. Эта команда перемещает указатель HEAD, а --hard обновляет файлы в вашей рабочей директории в соответствии с этим.

git reset --hard HEAD~1

Эта команда удаляет коммит "Revert", который мы только что сделали. Вы можете подтвердить это, выполнив git log --oneline.

Теперь давайте снова отменим "нежелательный" коммит, но на этот раз используя опцию --no-commit. Не забудьте использовать хэш коммита "Add a second, unwanted line".

Пожалуйста, замените <your-commit-hash> на фактический хэш из вашего терминала.

git revert --no-commit <your-commit-hash>

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

git status

Вывод покажет, что story.txt подготовлен к коммиту (staged for commit):

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   story.txt

Изменения из отмененного коммита теперь находятся в вашей области подготовки (staging area). Теперь вы можете их изменить. Давайте заменим нежелательную строку на лучшую. Откройте story.txt с помощью nano:

nano story.txt

Файл будет выглядеть так же, как после отмены в Шаге 2. Добавьте новую, лучшую строку в конец файла:

And they lived happily ever after.

Сохраните и выйдите из nano (Ctrl+O, Enter, Ctrl+X).

Теперь добавьте ваши изменения в область подготовки и закоммитьте их с новым, описательным сообщением:

git add story.txt
git commit -m "Replace unwanted line with a proper conclusion"

Наконец, проверьте лог и содержимое файла, чтобы увидеть результат:

git log --oneline
cat story.txt

Лог показывает ваш новый коммит, а story.txt содержит исправленное содержимое. Вы успешно отменили коммит, сохранив и изменив его изменения.

Резюме

В этой лабораторной работе вы научились безопасно отменять коммит Git без потери работы. Вы практиковались в просмотре истории коммитов с помощью git log, выполнении стандартного git revert для создания нового коммита, который отменяет предыдущие изменения, и использовании опции git revert --no-commit для отмены изменений в вашей области подготовки (staging area), что позволяет вам модифицировать их перед созданием нового коммита. Эти методы необходимы для чистого и безопасного управления историей вашего проекта, особенно в командной среде.