Найти в Дзене
"Мы"-Прогер

Как откатить что-либо в Git

Важно! Откатывать в Git можно только то, что ещё не было запушено на сервер. Потому что, если вы измените коммит, от которого ответвились ваши товарищи, то их работу нельзя будет пристроить к вашему новому коммиту: их работа основана на старом (неправильном) коммите, а не на вашем новом. Поэтому Git не изменяет запушенные коммиты (ну, почти). Если вы попытаетесь отредактировать запушенный коммит, то Git создаст исправленный коммит рядом с испорченным, а испорченный останется на своём месте. Поэтому, если вам надо изменить что-то запушенное, то единственный хороший вариант - это сделать ещё один коммит, оставив старые как есть. Показываю на примере IntelliJIDEA / Rider / PyCharm / ... Если мы сделали коммит, но ещё не успели его запушить, как вдруг поняли, что нужно что-то в нём изменить, то можно открыть вкладку коммита (слева вверху) и поставить галочку Amend. Мы сможем добавить новые изменения к коммиту или убрать оттуда что-то лишнее. Чтобы выбрать изменения конкретного файла, выдел
Оглавление

Важно! Откатывать в Git можно только то, что ещё не было запушено на сервер. Потому что, если вы измените коммит, от которого ответвились ваши товарищи, то их работу нельзя будет пристроить к вашему новому коммиту: их работа основана на старом (неправильном) коммите, а не на вашем новом. Поэтому Git не изменяет запушенные коммиты (ну, почти). Если вы попытаетесь отредактировать запушенный коммит, то Git создаст исправленный коммит рядом с испорченным, а испорченный останется на своём месте.

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

Показываю на примере IntelliJIDEA / Rider / PyCharm / ...

Amend commit (как отредактировать коммит)

Если мы сделали коммит, но ещё не успели его запушить, как вдруг поняли, что нужно что-то в нём изменить, то можно открыть вкладку коммита (слева вверху) и поставить галочку Amend. Мы сможем добавить новые изменения к коммиту или убрать оттуда что-то лишнее. Чтобы выбрать изменения конкретного файла, выделите файл и нажмите Ctrl + D (от слова Difference). Также можно изменить название коммита.

Amend commit
Amend commit

Undo commit (как отменить коммит)

Также можно расскоммитить изменения, как будто мы не делали последний коммит. Последний коммит исчезнет, а все его изменения окажутся незакоммиченными. Для этого выберем последний коммит нашей текущей ветки в Git Log и нажмём на него правой кнопкой. В меню найдём Undo commit...

Меню коммита в Git Log
Меню коммита в Git Log

Далее выберем ченджлист, в который попадут наши изменения. Ченджлист - это всего-навсего "папочка" в списке изменений, так что можно оставить всё по умолчанию:

Выбор changelist'а
Выбор changelist'а
Что такое changelist'ы в Git
Что такое changelist'ы в Git

Revert commit (как отменить изменения, сделанные давно)

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

Поэтому старайтесь делать коммиты атомарными, то есть 1 коммит = 1 мелкая задача/подзадача. Если вдруг вам нужно будет отменить изменения, то у вас будет коммит, который вы хотите отменить, и в нём не будет ничего лишнего, что вы отменять не хотите.

Найдите этот коммит в Git Log или выделите несколько коммитов с помощью Shift/Ctrl, нажмите на них правой и выберите Revert commit. В конце вашей текущей ветки создастся новый коммит, противоположный выбранному:

-5

Если с тех пор были сделаны какие-то изменения, затрагивающие этот код, то выскочит конфликт, где вы сможете вручную выбрать, что и как откатывать в новом коммите.

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

Edit commit message (как отредактировать сообщение коммита)

В том же меню коммита из Git Log есть и другие полезные пункты. Например, вы можете отредактировать сообщение коммита (если он не был запушен), выбрав Edit commit message.

Reset current branch to here... (как откатить ветку назад)

Если нам не нужны несколько последних коммитов, то мы можем найти последний нужный и на его меню нажать Reset current branch to here..., чтобы откатить конец ветки назад:

Git Reset current branch to here...
Git Reset current branch to here...

Откроется меню:

Меню Reset current branch to here
Меню Reset current branch to here

Интерес представляют пункты Soft и Hard. Soft делает все изменения, которые были в откатываемых коммитах, снова незакоммиченными. А Hard убирает изменения из файлов, приводя их в состояние последнего "хорошего" коммита.

Reflog (как восстановить удалённый коммит)

Если вы откатили конец ветки назад или вообще удалили ветку на сервере, то некоторые коммиты окажутся не входящими ни в одну ветку. Такие коммиты удаляются. Но это Git, а значит, их ещё может быть можно восстановить!

Сначала создадим временную ветку, чтобы не испортить рабочую. Сделать это можно в меню веток вверху, нажав на New branch.

А теперь нам понадобится терминал. Открыть его можно прямо в IntelliJIDEA / Rider / PyCharm /..., вкладка внизу слева.

Git Reflog
Git Reflog

Наберём команду "git reflog". Она покажет нам историю, на каких коммитах мы побывали. История идёт снизу вверх, сверху самые последние. Находим удалённый коммит и копируем его хеш (жёлтые цифры в начале строки).

Далее вбиваем в терминале команду "git reset --hard хеш", и наша временная ветка откатывается на этот коммит. Файлы приходят в состояние этого коммита.

Всё, коммит виден в Git Log. Далее мы можем перейти на рабочую ветку и, например, замержить временную ветку в рабочую (в меню веток вверху находим рабочую ветку, Checkout, далее находим временную ветку, Merge ... into ...).

Force push (как перезаписать запушенную ветку)

Если вы всё-таки хотите перезаписать коммиты, запушенные на сервер, и вы уверены, что ещё никто от них не ответвился, то это можно сделать. Чтобы не потерять коммиты, рекомендуется создать временную ветку на месте вашей текущей (New branch в меню веток вверху). Далее переключитесь обратно на рабочую ветку (Checkout на рабочей ветке в меню веток) и откатите её назад к последнему правильному коммиту с помощью Reset current branch to here..., Hard (см. выше). Далее сделайте правильные коммиты вместо неправильных. Когда будете пушить ветку, нажмите на стрелочку у кнопки Push и выберите Force push. Выскочит подтверждение, согласитесь с ним.

Заключение

Итак, в нашем арсенале есть множество методов отката. Чтобы повторить все их и быстро найти нужный, используйте оглавление этой статьи.