Как сделать откат в github desktop

Обновлено: 08.07.2024

Для отмены слияния веток в git (git merge) есть два решения:

- удаление коммита слияния (unmerge, merge undo, merge delete)

- отмена изменений слияния (revert)

Первый случай поможет, если вы еще не сделали новых коммитов, после слияния веток, и не отправили изменения в ваш центральный репозиторий (например в GitHub или Bitbucket). Для удаления коммита слияния нужно перейти на ветку, в которую вы влили другую ветку. Например так:

и выполнить операцию отката ветки:

Для отмены изменений слияния можно выполнить либо

где _some_hash_ - это хэш коммита, который вы хотите отменить (это отменяет изменения конкретного коммита). Либо

где _some_hash_ - это хэш коммита слияния (коммит созданный командой git merge), который вы хотите отменить. Этот вариант отменяет все изменения, сделанные командой git merge, и восстанавливает состояние ветки (в которую происходило вливание) до мерджа

Гит — система, в которой не нужно бояться совершать ошибки. Можно сказать, что это единственный способ научиться им пользоваться. В git практически всегда есть способ восстановить или изменить любые коммиты. На крайний случай спасет повторный git clone .

Что делать, если коммит уже сделан, но он нас по каким-то причинам не устраивает? Ситуаций может быть много, и все они возникают регулярно даже у профессиональных разработчиков:

Git revert

Самая простая ситуация — отмена изменений. Фактически она сводится к созданию ещё одного коммита, который выполняет изменения противоположные тому коммиту, который отменяется. Руками создавать подобный коммит довольно сложно, поэтому в git добавили команду, автоматизирующую откат. Эта команда называется git revert :

Команда revert может "отменять" не только последний коммит, но и любой другой коммит из истории проекта. Согласитесь, это очень круто. Без системы контроля версий о таком нельзя было и мечтать.

Git reset

Иногда удалить нужно только что сделанный по ошибке коммит. Конечно, и в этом случае подходит git revert , но так загрязняется история. Если этот коммит сделан был только сейчас и ещё не отправлялся на Github, то лучше сделать так, как будто бы этого коммита не существовало в принципе.

Git позволяет удалять коммиты. Это опасная операция, которую нужно делать только в том случае, если речь идет про новые коммиты, которых нет ни у кого, кроме вас.

Если коммит был отправлен во внешний репозиторий, например, на Github, то менять историю ни в коем случае нельзя, это сломает работу у тех, кто работает с вами над проектом.

Для удаления коммита используется команда git reset . Делается это так:

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

Флаг --hard означает полное удаление. Без него git reset отменит коммит, но не удалит его, а поместит все изменения этого коммита в рабочую директорию, так что с ними можно будет продолжить работать. HEAD~ означает "один коммит от последнего коммита". Если бы мы хотели удалить два последних коммита, то могли бы написать HEAD~2 .

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

Последнего коммита больше не существует, но изменения, сделанные в нём, не пропали. Они находятся в рабочей директории для дальнейшей доработки.

Система контроля версий git позволяет очень быстро вернуть состояние файла или состояние всего проекта к моменту в котором они были зафиксированы в последнем коммите. Операция эта очень проста, быстра и удобна.

Как сбросить файл к исходному состоянию в коммите?

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

[cce lang=’bash’]
$ git status
[/cce]


По каким-то причинам изменения в файле second.php нам не нужны, и требуется получить состояние файла, которое было зафиксировано на момент последнего коммита. Сделать это очень просто с помощью команды:

[cce lang=’bash’]
$ git checkout — second.php
[/cce]


Как сбросить файл к состоянию в коммите, если изменения уже подготовлены командой git add?

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

  • Убрать файл из подготовленного состояния к фиксации в коммите, т.е. перевести файл из состояния staged.
  • Сбросить файл к исходному состоянию.

Для примера рассмотрим ситуацию, когда в нашем локальном репозитории есть файл second.php , в который были внесены изменения и более того эти изменения были подготовлены к фиксации в коммит при помощи команды [cci]$ git add *.php[/cci] .


В репозитории есть модифицированный файл со статусом staged, подготовленный для фиксации изменений в следующий коммит.

Для того, чтобы такой модифицированный файл сбросить к первоначальному состоянию, вначале следует перевести его в состояние not staged. Делается это при помощи команды:

[cce lang=’bash’]
$ git reset HEAD second.php
[/cce]


На иллюстрации выше к файлу применена команда [cci]$ git reset HEAD [имя файла][/cci], а после этого команда [cci]$ git satus[/cci] в результате вывода информации которой видно, что файл second.php теперь просто является модифицированным. Кстати, обратите внимание, что система контроля версий git сама в выводе команды status подсказывает, что файл можно сбросить к исходному состоянию командой [cci]$ git checkout — [имя файла][/cci] или подготовить изменения к фиксации в коммит при помощи [cci]$ git add [имя файла][/cci] .

Для сброса файла в исходное состояние мы воспользуемся командой:

[cce lang=’bash’]
$ git checkout — second.php
[/cce]


Файл сброшен к исходному состоянию при помощи команды git checkout

Вывод: Для сброса команды к состоянию сохраненному в последнем коммите применяется команда [cci]$ git checkout — [имя файла][/cci]. Если изменения в файле уже подготовлены для фиксации в следующем коммите, то перед сбросом следует воспользоваться также командой [cci]git reset HEAD [имя файла][/cci].


Коллеги, приветствую. Сегодня мы немного поговорим о работе с коммитами в системе контроля версиями — Git.

Целью этой статьи является обзор популярных сценариев проблем и методов их решения. Мы узнаем о том, как можно решить проблемы связанные с человеческими ошибками при создании коммитов в Git, какой способ устранения ошибок лучше применять в конкретных ситуациях.

Возникающие проблемы

В ходе разработки каких-либо проектов в Git, мы можем столкнуться с различными ситуациями, такими как:

Безопасные изменения для локального репозитория

Изменить последний коммит

Давайте предположим, что мы работаем над каким-либо проектом локально.




Но что делать, если мы забыли добавить или изменить какие-то файлы в наш последний коммит?

Для этого импортируем нужные файлы в наш проект или изменяем уже существующие и добавляем их в индекс.

Для теста я добавлю файл forgotten file.txt в проект. После этого еще раз выполним команду:



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

Удалить коммит

Для того, чтобы удалить один или несколько коммитов, мы можем воспользоваться командой git reset. Существует два типа выполнения reset:

  • Soft — удаляет коммит из истории и переводит файлы из него в состояние рабочего каталога.
  • Hard — удаляет коммит из истории вместе с файлами.

Сначала разберем soft reset. Возвращаемся к нашему проекту.


В один момент мы осознали, что допустили ошибку и хотели бы переделать последний коммит.

Для этого выполним команду:

Проверим историю коммитов. Мы можем убедится, что последний коммит был удален.


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


Подобные действия мы можем выполнять для нескольких коммитов сразу. Для примера введем команду:

3 последних коммита пропали из истории.


Проверим состояние файлов, которых коснулась процедура удаления коммитов.


Мы можем полностью удалить коммиты без сохранения связанных с ними файлов. Для этого выполним процедуру hard reset:

И проверим состояние.


Массовое изменение коммитов


Для этой задачи хорошо подходит выполнение команды git rebase. Ее запуск в интерактивном режиме позволит нам последовательно сообщить Git’у как бы мы хотели выполнить оптимизацию.

Мы считаем, что 4 последних коммита можно смело объединить в один.

Для этого выполним команду:

Перед нами откроется текстовый редактор по умолчанию в котором мы будем выполнять изменения. Используем коммит с хэшем aab958a как начальный, путем указания команды pick напротив него и укажем напротив трех остальных команду squash. Как мы можем видеть ниже в описании, команда suqash объединит коммит с предыдущим в списке.


После выполнения — выходим из текстового редактора.


Снова выходим из текстового редактора.

Похоже, что наше объединение нескольких коммитов прошло успешно. Давайте проверим это командой:


Снова вводим команду:


В этот раз в качестве начального коммита будет использоваться с коммит хэшем 4c17043. Для его переименования укажем напротив команду reword. Затем объединяем с ним два последующих коммита командой squash. Последний коммит мы никак не изменяем.

После переименования выходим из текстового редактора и проверяем историю.


Похоже, что нам удалось провести историю коммитов в порядок и теперь нет причин откладывать загрузку нашего проекта на удаленный репозиторий. 🙂

Безопасные изменения для удаленных репозиториев

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

Однако, что делать, если мы совместно работаем над проектом и только спустя какое-то время понимаем, что один из коммитов — лишний? Если мы воспользуемся вышеописанными методами, это может спровоцировать ряд проблем в работе над проектом у наших коллег.

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

Снова вовзращаемся к исходному состоянию проекта.


Предположим, что изменения в коммите с хэшем и 5140d80 — лишние. Выполним команду:

Git сообщит нам об изменениях, после отката.



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

Итоги

В этой статье мы узнали о четырех способах изменять коммиты:

  • git commit —amend — позволяет изменять последний коммит.
  • git reset — позволяет удалять коммиты.
  • git rebase — позволяет производить массовое изменение коммитов, приводить в порядок историю.
  • git revert — позволяет откатывать изменения коммитов.

Первые три команды — подойдут для использования в условиях локальной разработки.

Последняя команда — лучший способ, не создавать лишних проблем коллегам при совместной разработке.

Читайте также: