Вы легко можете увидеть историю коммитов своей ветки с помощью команды
git log
Но что если вам нужно "попасть" на предыдущий коммит? Или гораздо раньше? В этом вам поможет команда:
git reset --hard HEAD~1
где число 1 в нашем случае - это количество коммитов на которые мы хотим переместиться в прошлое. HEAD - это служебное слово обозначающее коммит на котором мы сейчас находимся, обычно это последний коммит в вашей текущей ветке. Давайте посмотрим на то, как это выглядит для самого git'а
на изображении видно что произошло, указатель HEAD подвинулся в прошлое, об этом говорит надпись reset: moving to HEAD~1 и слева видно, что хеш коммита 8a4c9be теперь снова равен "старому" значению. Обратите внимание, что самый последний коммит не пропал, ссылка на него есть, достаточно просто перейти на него обратно, например так:
git reset --hard 4692297
Все, теперь мы "откатили" действие перемещения по истории назад, восстановили коммит. Есть способ ещё проще:
git reset --hard HEAD@{1}
Снова мы видим цифру 1 в фигурных скобках, в этой команде она означает количество коммитов на которые нужно переместиться "вперед", в нашем случае это 1 коммит. Этот способ проще, потому что не нужно получать ID хеша коммита и вставлять его в команду, здесь достаточно изменить одну цифру.
Зачем это вообще нужно?
Например, вам нужно посмотреть что изменится если перейти на коммит назад? Это может помочь при отладке какой-то проблемы, ведь так можно найти "плохой" коммит, то есть тот, на котором что-то сломалось. Хотя для этого существует команда git bisect о которой я расскажу позже. А ещё, можно сохранить коммит, переместить его в другую, временную, ветку. Поясню этот сценарий подробнее:
- мы поняли что то, что мы сейчас делали в ветке с называнием old_branch стоит "положить" в другую ветку чтобы потом доделать, а текущую ветку отправить на сервер (для ревью или тестов)
- для этого создадим новую ветку в которой потом продолжим нашу работу
git checkout -b new_branch
новая ветка new_branch - это копия прошлой ветки, оставим ее как есть - переключимся обратно на старую ветку old_branch
git checkout old_branch - "забываем" про наш недоделанный коммит который теперь живет в ветке new_branch
git reset --hard HEAD~1 - отправляем изменения на сервер, все кроме последнего, недоделанного, коммита
git push
В результате наш недоделанный коммит будет жить в ветке new_branch, мы к нему вернёмся потом, а текущая ветка отправится на сервер.