четверг, 19 марта 2015 г.

Про отрубленную голову Git (detached HEAD state)

1400761301_tudaТы туда не ходи - ты сюда ходи. А то снег башка попадёт - совсем мёртвый будешь...

В этой статье пойдет речь про отрубленное отсоединенное состояние указателя HEAD. Надо понимать что названия веток в Git это указатели на коммиты. Имя ветки, допустим master, указывает на последний коммит в ветке master.

Существует так же множество других указателей и один из них HEAD, но это очень важный указатель. И вот о нем мы и поговорим.

 

И так у нас есть история коммитов

H0001

И сейчас указатель ветки master и указатель HEAD указывают на последний коммит С4 в ветке master.

То же самое можно увидеть в Git

H0002

Оба указателя master и HEAD указывают на коммит С4 (efaaf18).

Теперь передвинем указатель HEAD на коммит C2 командой

$ git checkout 7bbbd68

H0003

Вот мы и получили отрубленную отсоединеннуюый голову указатель HEAD. И Git нам любезно сообщил что снег башка попал…

На диаграмме это можно изобразить так

H0004

То есть команда git checkout 7bbbd68 просто перенесла указатель HEAD на коммит C2 (7bbbbd68). И вместе с этим вернула в рабочий каталог состояние файлов этого коммита. То есть мы откатились назад по истории коммитов.

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

Все это можно увидеть в Git

H0005

Состояние HEAD detached означает что HEAD указывает не на вершину какой либо ветки, а просто на какой-то коммит.

Посмотреть историю перемещения головы можно командой git reflog

H0006

На скрине мы так же посмотрели состояние Git и он нам (аж красным) сообщил, что башка отсоединена на коммит 7bbbd68.

HEAD всегда должен указывать на вершину какой-либо ветки. Это очень важно. И вот почему.

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

Давайте сделаем коммит и посмотрим что будет. Изменим файлик и посмотрим статус

H0007

Ну и делаем коммит

H0008

Из лога коммитов видно что сейчас HEAD указывает на коммит С5 (84b361c), но на этот коммит не указывает ни какая ветка, верней сказать ни какой указатель ветки.

Графически это можно изобразить так

H0009

Мы по прежнему находимся в состоянии detached HEAD, о чем нам все время напоминает Git. Еще раз напомню что это означает что HEAD указывает не на вершину какой-либо ветки, а просто на коммит. В нашем случае на коммит С5 (84b361c).

Выйти из состояния detached HEAD очень легко, для этого надо переключится на какую-либо ветку или создать новую ветку.

Давайте переключимся на ветку master командой git checkout master

H0010

При переключении на ветку master, Git заботливо нас предупредил, что мы оставляем 1 commit, который не присоединен ни к какой ветке. Сообщил нам имя этого коммита – С5 и его хэш – 84b361c. И посоветовал, что возможно уже самое время создать новую ветку командой

git branch new_branch_name 84b361c

Поскольку если мы сейчас не создадим ветку (указатель) на этом коммите, то мы можем его потерять.

Если сейчас дать команду просмотра лога коммитов, то мы коммит С5 в логе не увидим

H0011

Таким образом мы можем “потерять” коммит С5, если забудем его хэш. Конечно, как уже говорилось, что в Git какой-либо сделанный коммит сложно потерять (но можно). И в данном случае мы можем посмотреть историю перемещения HEAD

H0012

и в ней мы можем увидеть наш потерянный коммит, хотя мы его и не видели в истории коммитов (логе коммитов).

Теперь дадим команду

$ git branch lost_branch 84b361c

и посмотрим лог

H0013

Теперь, все хорошо. На коммит С5 указывает ветка lost_branch

Графически это выглядит так

H0014

Теперь мы легко можем переключится на ветку lost_branch и состояния HEAD deatached уже не будет, поскольку HEAD уже будет указывать на вершину ветки lost_branch.

H0015

Сейчас переключение произошло безболезненно, поскольку это вполне штатная работа в Git.

Ну и покажу это состояние графически

H0016

На этом, с отсоединенной головой пока все. Хотя есть еще варианты по отделению головы в Git, но об этом как-нибудь в другой раз.

33 комментария:

  1. Ясно, доступно и понятно. Спасибо за материал.

    ОтветитьУдалить
  2. Мэн. Огромное тебе спасибо. Спас.

    ОтветитьУдалить
  3. Спасибо, очень полезная и понятная статья

    ОтветитьУдалить
  4. Спасибо за труд, очень хорошо расписано

    ОтветитьУдалить
  5. Огромное спасибо за отличное объяснение.

    ОтветитьУдалить
  6. Спасибо! Очень полезный материал!

    ОтветитьУдалить
  7. Очень круто и понятно, спасибо!!!)))

    ОтветитьУдалить
  8. Топ. Все ясно и понятно.
    Респект

    ОтветитьУдалить
  9. Огромный лайк автору и спасибо, редкий доступный материал про отстреленную голову, видно что человек разбираеться о чем пишет

    ОтветитьУдалить
  10. Присоединяюсь к предыдущим ораторам :-) Изложено понятно и наглядно. Благодарю.

    ОтветитьУдалить