Отделённый HEAD -- Понимание и восстановление
Отделённый HEAD означает, что ваш указатель HEAD не находится на ветке -- он указывает непосредственно на конкретный коммит. Это не ошибка, но любые сделанные коммиты могут быть потеряны, если вы переключитесь, не сохранив их в ветку.
Как обычно выглядит HEAD?
HEAD ──→ main ──→ commit C
HEAD указывает на ветку, а ветка указывает на коммит. Когда вы делаете новый коммит, ветка перемещается вперёд, и HEAD следует за ней.
Что такое отделённый HEAD?
HEAD ──→ commit B (нет ветки!)
main ──→ commit C
HEAD указывает непосредственно на коммит, минуя любую ветку. Это происходит, когда вы переключаетесь на конкретный коммит, тег или удалённую ветку.
Как попасть в состояние отделённого HEAD?
git checkout abc1234 # переключение на конкретный хеш коммита
git checkout v1.0 # переключение на тег
git checkout origin/main # переключение на удалённую ветку
Git предупредит вас:
You are in 'detached HEAD' state. You can look around, make
experimental changes and commit them, and you can discard any
commits you make in this state without impacting any branches...
Опасность
Если вы сделаете коммиты в отделённом HEAD и затем переключите ветку, эти коммиты станут осиротевшими -- ни одна ветка не указывает на них. Сборщик мусора Git в конечном счёте удалит их.
HEAD ──→ commit X ──→ commit Y (осиротевшие!)
main ──→ commit C
Как восстановиться
Создайте ветку из отделённого HEAD, чтобы сохранить свою работу:
git branch my-rescue-branch
git checkout my-rescue-branch
Или в одно действие:
git checkout -b my-rescue-branch
Если вы уже переключились и потеряли коммит, используйте git reflog, чтобы найти его:
git reflog
# найдите хеш коммита
git checkout -b rescue abc1234
Попробуйте!
Потренируйтесь входить в состояние отделённого HEAD и восстанавливаться из него:
- Создайте файл и сделайте коммит:
echo "first" > file.txt, затемgit add file.txt, затемgit commit -m "First commit" - Сделайте второй коммит:
echo "second" >> file.txt, затемgit add file.txt, затемgit commit -m "Second commit" - Найдите хеш первого коммита:
git log --oneline - Переключитесь на этот коммит:
git checkout <хеш-первого-коммита>-- теперь вы в отделённом HEAD - Проверьте:
git statusпокажет "HEAD detached at ..." - Сделайте коммит здесь:
echo "detached work" >> file.txt, затемgit add file.txt, затемgit commit -m "Work in detached HEAD" - Сохраните свою работу, создав ветку:
git checkout -b rescue-branch - Убедитесь, что ветка существует:
git branch-- вы должны увидетьrescue-branchс вашим коммитом - Вернитесь на main:
git checkout main
Ключевая идея
Отделённый HEAD не страшен, если вы его понимаете. Он просто означает "вы не на ветке". Решение всегда одно: создайте ветку, чтобы сохранить свою работу, прежде чем переключаться.