GIT detached HEAD

12.05.2020

Описание проблемы

При рекурсивном клонировании одного репозитория, по неопытности не переключил текущую рабочую ветку в сабмодуле и начал работать в нем, в итоге, при попытке push получил ошибку:

•••
plaintext
$ git push fatal: You are not currently on a branch. To push the history leading to the current (detached HEAD) state now, use git push origin HEAD:<name-of-remote-branch>

Конечно же git предупреждал ранее в команде status:

•••
plaintext
$ git status HEAD detached at 6b4f07f ...

НАДО БЫЛО в этот момент переключиться на нужную ветку (например на master) и все было бы без проблем (при отсутсвии коммитов):

•••
plaintext
$ git checkout master

Но проблема возникла, и надо ее решать.

Немного о HEAD

Начнем с того что HEAD это специальный указатель на определенный (текущий) коммит. Этот коммит может быть в какой-то ветке, например в master, или быть вне ветки - это и есть detached HEAD.

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

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

Решение проблемы detached HEAD

Относительно проблемы, если коммит вне ветки (detached HEAD), то прямым образом он никак не может быть отправлен на сервер, один из способов решения:

  • создать новую ветку, на которую будет указывать HEAD и куда автоматически попадет вневеточный коммит - git branch temp-branch
  • переключиться на нужную ветку (например на master) - git checkout master
  • влить созданную ветку temp-branch в текущую - git merge temp-branch
  • отпраить ветку master на сервер - git push origin master

Ссылки на почитать