Если Git показывает HEAD detached, ваши файлы по-прежнему извлечены на определенном коммите, но новые коммиты не будут продвигать ветку, пока вы ее не создадите. На Mac откройте Терминал, перейдите в репозиторий, проверьте наличие незакоммиченных изменений, а затем либо прикрепите текущую работу к новой ветке, либо безопасно вернитесь к нужной ветке. Команда Git switch поддерживает оба пути. Руководство Apple по Терминалу объясняет, как открыть Терминал; документация по Git switch описывает поведение веток и состояние detached HEAD.

1. Проверьте, что именно извлечено в Git

Откройте Терминал из папки «Программы» > «Утилиты», затем перейдите в свой репозиторий. Замените путь из примера на папку, где находится ваш проект; кавычки позволяют использовать пробелы в пути. Терминал macOS по умолчанию использует zsh, и эти команды работают как в zsh, так и в других распространенных командных оболочках.

cd "/path/to/your/repository"
git status

Если git status сообщает «HEAD detached» или «not on any branch», вы находитесь в состоянии detached HEAD. Git выполнил checkout напрямую на коммит, а не на ветку. Сам коммит и рабочие файлы остаются доступными; риск заключается в том, что сделанные здесь коммиты не привязываются к ветке автоматически. Руководство по Git checkout описывает это состояние и то, как ветка позволяет сохранить сделанные в нем коммиты.

Перед переключением куда-либо изучите остальной вывод git status. Если в нем перечислены измененные или неотслеживаемые файлы, это изменения, которые еще не были закоммичены. Вы можете продолжить работу на месте или создать ветку прямо сейчас; создание ветки на текущем коммите само по себе не удаляет правки. Избегайте параметров принудительного выполнения или отмены изменений во время восстановления.

2. Сохраните текущую работу в ветке

Если вы сделали коммит в состоянии detached HEAD или хотите продолжить работу именно с этого слепка, создайте ветку прямо там, где вы находитесь:

git switch -c recovered-work
git status

Используйте понятное имя ветки вместо recovered-work. Git создаст ветку на текущем коммите и переключится на нее, поэтому последующие коммиты будут относиться к этой ветке. Убедитесь, что git status теперь указывает имя ветки. Это самый быстрый способ восстановления, если слепок в состоянии detached HEAD — это как раз та работа, которую вы хотите сохранить. В документации Git указано, что switch -c создает ветку и переключается на нее.

Если у вас есть незакоммиченные правки, они обычно сохраняются в рабочей директории при создании ветки. Проверьте git status после этого, чтобы убедиться, что они на месте. Если команда выдает ошибку из-за того, что ветка с таким именем уже существует, выберите другое имя; не используйте флаг -C, так как он может сбросить существующую ветку на новую начальную точку.

3. Вернитесь к ветке, которую вы собирались использовать

Если вы просто просматривали коммит и у вас нет изменений, которые нужно сохранить, переключитесь на нужную ветку по имени. Например:

git switch main

Используйте фактическое имя ветки вашего репозитория, если это не main. Если Git сообщает, что локальные изменения будут перезаписаны, остановитесь и сначала сохраните их: создайте ветку для восстановления, как описано выше, или закоммитьте работу. Обычно Git блокирует переключение веток, если это приведет к потере локальных правок; избегайте флага --discard-changes во время восстановления, поскольку он сбрасывает индекс и рабочее дерево в соответствии с целевой веткой. Руководство по git switch объясняет эти механизмы защиты и доступные параметры.

Если вы только что переключились с ветки по ошибке, команда git switch - вернет вас к предыдущей ветке или коммиту, зафиксированному в недавней истории переключений Git. После переключения выполните git status, чтобы подтвердить свое текущее состояние.

4. Найдите коммит из detached HEAD, оставленный ранее

Если вы уже переключились и не помните, где остался ваш коммит из состояния detached HEAD, проверьте локальный журнал reflog:

git reflog

Reflog записывает недавние обновления локальных ссылок, а reflog для HEAD также фиксирует переключения веток. Найдите запись с сообщением коммита или временем, соответствующим вашей работе. Чтобы просмотреть подходящий вариант, ничего не меняя, скопируйте его короткий идентификатор коммита (ID) из reflog и выполните:

git show --stat COMMIT_ID

Замените COMMIT_ID фактическим идентификатором — не вводите этот плейсхолдер буквально. Если это нужный коммит, сохраните его, создав ветку на этом коммите:

git switch -c recovered-work COMMIT_ID

Это снова сделает коммит доступным через ветку. Журналы reflog хранятся локально, и срок действия записей может истекать; в документации Git они описываются как записи недавних обновлений ссылок, и там же отмечены правила истечения их срока. См. git reflog.

5. Проверьте результат перед продолжением

Выполните git status и git log -1 --oneline, чтобы подтвердить текущую ветку и последний коммит. Если ваша работа не была закоммичена, убедитесь, что соответствующие файлы по-прежнему отображаются в выводе статуса. Если подходящий вариант не отображается в reflog, для восстановления может потребоваться поиск висячих объектов (dangling objects); это отдельный шаг, требующий большей осторожности, и во время поиска следует избегать запуска команд очистки, таких как git gc.

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

Источники