Обычно .git/HEAD содержит ссылку на ветку:
ref: refs/heads/main
В detached-режиме там лежит сам SHA коммита:
a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
То есть HEAD не привязан ни к одной ветке. Все команды, которые
пишут «в текущую ветку» (git commit, git pull), перестают
иметь чёткое целевое место.
Как попасть
git switch --detach v1.0 # явно, на тег
git checkout HEAD~3 # неявно, на старый коммит
git checkout origin/main # неявно, на удалённую ветку
git checkout <sha> # неявно, на конкретный коммит
Все эти ситуации легитимны. Просмотреть код в момент релиза, найти бажный коммит через bisect, поэкспериментировать локально.
Что внутри безопасно
- Читать файлы.
- Запускать тесты, билды.
- Делать локальные правки в рабочем дереве (но не коммитить!).
Что опасно
- Коммитить. Коммит создастся, HEAD двинется на него - но
никакая ветка на новый коммит не указывает. Как только
переключишься на любую ветку, новый коммит станет недостижимым
и через 30 дней пропадёт в
git gc.
Если коммитил - как спасти
Создать ветку прямо из текущего HEAD:
git switch -c rescue
# или
git branch rescue
Теперь rescue указывает на твои коммиты, они в безопасности.
Дальше можно git switch main && git merge rescue или
cherry-pick.
Подводные камни
- Git предупреждает большим текстом при входе в detached. Не игнорируй - потом тяжелее искать «куда делись коммиты».
git reflogвсё помнит. Даже если коммиты «потерялись», reflog покажет SHA, и можно создать ветку постфактум.- Прерванный
git rebaseиногда оставляет detached. Если видишь непонятный detached после rebase -git rebase --abortили восстанови через reflog.