Почему мой репозиторий Git перешел в отключенное состояние HEAD?

387

Сегодня у меня была отстраненная голова, та же проблема, которая описана в: git push говорит, что все в курсе, хотя у меня есть локальные изменения

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

Так, как я закончил с detached HEAD?

Адам Бергмарк
источник
18
Проверка удаленной ветки кажется наиболее распространенным способом сделать это случайно; Другим распространенным способом является проверка branch-name@{n}n-й предыдущей позиции branch-name. Но несмотря ни на что, в какой-то момент должно было быть git checkout <rev>. Если это не звучит как колокольчик, то, вероятно, вы сделали то, что упомянул Уилл - попытались сделать git checkout <file>и смогли указать ревизию случайно.
Каскабель
3
Для отмены отсоединенного состояния HEAD см. Исправление отсоединенной головки Git? ,
Мой репо оказался в этом состоянии, когда возникли конфликты во время перебазирования. К счастью, Гит сказал мне, что делать, когда я побежал git status:all conflicts fixed: run "git rebase --continue"
Пол
2
Также происходит, если вы случайно набрали git checkout remotes/origin/my-branchвместо git checkout my-branchили git checkout origin/my-branch.
Адам Либуша
@adam Libusa, Спасибо, это сработало для меня. В чем разница между git checkout remotes / origin / my-branch и git checkout my-branch. Разве это не то же самое. но то, что ты сказал, сработало для меня. Из любопытства прошу.
Карунакар Бхогьяри

Ответы:

281

Любая проверка коммита, который не является именем одной из ваших веток, даст вам отдельную ГОЛОВУ. SHA1, который представляет вершину ветви, все еще дает отделенную ГОЛОВУ. Только проверка названия локального филиала позволяет избежать этого режима.

Смотрите совершение с отстраненной головой

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

альтернативный текст

Например, если вы извлекаете «удаленную ветку», не отслеживая ее в первую очередь, вы можете получить отсоединенную головку.

Смотрите git: переключите ветку без отсоединения головы


С Git 2.23 (август 2019 г.) вам больше не нужно вводить в заблуждение git checkoutкоманду .

git switch Также можно оформить ветку и получить отсоединить ГОЛОВУ, кроме:

  • у него есть явная --detachопция

Чтобы проверить фиксацию HEAD~3для временной проверки или эксперимента без создания новой ветви:

git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'
  • он не может по ошибке отсоединить удаленную ветку отслеживания

Видеть:

C:\Users\vonc\arepo>git checkout origin/master
Note: switching to 'origin/master'.

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 by switching back to a branch.

Против используя новыйgit switch команду:

C:\Users\vonc\arepo>git switch origin/master
fatal: a branch is expected, got remote branch 'origin/master'

Если вы хотите создать новую локальную ветку, отслеживающую удаленную ветку:

git switch <branch> 

Если <branch>не найдено, но существует ветвь отслеживания ровно в одном удаленном (вызовите его<remote> ) с совпадающим именем, обрабатывайте как эквивалент

git switch -c <branch> --track <remote>/<branch>

Нет больше ошибки!
Нет больше нежелательной головы!

VonC
источник
12
Другой способ ввода состояния отдельного заголовка - это если вы находитесь в середине интерактивной перебазировки и хотите отредактировать один из коммитов. Когда Git бросит вас при коммите для редактирования, вы будете находиться в состоянии отсоединенной головы, пока не закончите ребаз.
В этом визуальном руководстве есть объяснение: git commit files creates a new commit containing the contents of the latest commit, plus a snapshot of files taken from the working directory. Additionally, files are copied to the stage.что означает «файлы копируются на сцену»? Я думал, что файлы зафиксированы, что означает, что сцена очищена?
максимум
16
Фактически, вы получите отдельный HEAD всякий раз, когда вы проверяете любой коммит его SHA1, независимо от того , находится ли он в конце ветви; Единственная вещь, которую вы можете оформить, не получив отсоединенную головку, - это имя филиала. Например, несмотря masterна то, что находится на ed489диаграмме выше, git checkout ed489вы получите отдельную ГОЛОВКУ, а git checkout masterне -.
Musiphil
8
"You can think of this as an anonymous branch":) Мне нравится аналогия
Адриен Бе
118

Я воспроизвел это только сейчас случайно:

  1. списки удаленных филиалов

    git branch -r
          origin/Feature/f1234
          origin/master
    
  2. Я хочу оформить заказ на месте, поэтому я вырезал пасту:

    git checkout origin/Feature/f1234
    
  3. Presto! Отделенное состояние HEAD

    You are in 'detached HEAD' state. [...])
    

Решение № 1:

Не включать origin/ в начало моей спецификации ветки при проверке:

git checkout Feature/f1234

Решение № 2:

Добавить -b параметр, который создает локальную ветку с удаленного

git checkout -b origin/Feature/f1234 или

git checkout -b Feature/f1234 он автоматически вернется к исходному состоянию

Оуэн
источник
14
Это почти отличный ответ, но не объясняет, почему вы попали в отстраненное состояние головы.
Гусь
5
Я согласен, но он обеспечивает решение, которое я искал. Спасибо!!
Kilmazing
Я видел в этом другом ответе, что git checkout -b Feature/f1234<=> git branch Feature/f1234и git checkout Feature/f1234.
Armfoot
1
по умолчанию он выглядит как источник, поэтому, когда вы даете origin/branchname, он ищет, origin/origin/branchnameчто первым является удаленное имя, которое вы используете -b, если вы не создадите anonymousветвь, которая отсоединена. Точно так же для проверки с другого пульта вы должны упомянуть -bпараметр, иначе у git нет способа узнать, что это с нового пульта, он будет искать origin/remote/branchname.
garg10may
Вы святой!
Харви Лин
12

пытаться

git reflog 

это дает вам историю того, как ваши заголовки и указатели веток перемещались в прошлом.

например:

88ea06b HEAD @ {0}: оформление заказа: переход от DEVELOPMENT к удаленным устройствам / origin / SomeNiceFeature e47bf80 HEAD @ {1}: извлечение источника DEVELOPMENT: ускоренная перемотка вперед

верхняя часть этого списка - одна из причин, по которой можно встретить состояние DETACHED HEAD ... проверить ветку удаленного отслеживания.

Андре Р.
источник
7

Это может легко произойти, если вы попытаетесь отменить внесенные вами изменения, повторно извлекая файлы и не совсем понимая синтаксис.

Вы можете посмотреть на вывод git log- вы можете вставить хвост журнала сюда со времени последнего успешного коммита, и мы все увидим, что вы сделали. Или вы можете вставить его и красиво спросить #gitна IRC-сервере freenode.

Будет
источник
5

Это может произойти, если у вас есть тег с именем, аналогичным ветви.

Пример: если «release / 0.1» является именем тега, то

git checkout release/0.1

выдает отдельную ГОЛОВКУ при «выпуске / 0,1». Если вы ожидаете, что release / 0.1 будет именем ветви, то вы запутаетесь.

radzimir
источник
1
Да. Но как это исправить? Как вы относитесь к кассе филиала?
Мартин
5

Detached HEAD означает, что то, что в настоящее время проверено, не является локальной ветвью.

Некоторые сценарии, которые приведут к Detached HEADсостоянию:

  • Если вы заказываете удаленную ветку , скажем origin/master. Это ветка только для чтения. Таким образом, при создании коммита origin/masterон будет свободно плавающим , т.е. не связан ни с одной веткой.

  • Если вы извлекаете конкретный тег или фиксируете . Когда вы делаете новый коммит отсюда, он снова будет свободно плавающим , то есть не связанным ни с одной веткой. Обратите внимание, что когда ветка извлекается, новые коммиты всегда автоматически помещаются в подсказку.

    Если вы хотите вернуться назад и извлечь определенный коммит или тэг, чтобы начать работать оттуда, вы можете создать новую ветку, исходящую из этого коммита, и переключиться на нее git checkout -b new_branch_name. Это предотвратит Detached HEADсостояние, поскольку теперь у вас есть проверенная ветвь, а не фиксация.

Тим Сков Якобсен
источник
3

Простой случайный способ - git checkout headэто опечатка HEAD.

Попробуй это:

git init
touch Readme.md
git add Readme.md
git commit
git checkout head

который дает

Note: checking out 'head'.

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 by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 9354043... Readme
Томас Веллер
источник
Также упоминается в longair.net/blog/2012/05/07/the-most-confusing-git-terminology (ищите «HEAD» и «head»)
VonC
@VonC: спасибо за эту ссылку. Я готовлю Git-тренинг, и я также хочу указать, почему это иногда так запутанно. У меня уже есть много примеров (например, checkout -bкоторые выглядят как оформление заказа, но на самом деле ветки), но другой список просто приветствуется.
Томас Веллер
2

Другой способ войти в состояние git - это попытаться зафиксировать удаленную ветвь. Что-то вроде:

git fetch
git checkout origin/foo
vi bar
git commit -a -m 'changed bar'

Обратите внимание, что если вы сделаете это, любая дальнейшая попытка извлечения origin / foo вернет вас обратно в отдельное состояние головы!

Решение состоит в том, чтобы создать свою собственную локальную ветку foo, которая отслеживает origin / foo, а затем при необходимости нажать.

Вероятно, это не имеет ничего общего с вашей первоначальной проблемой, но на этой странице много хитов Google для "git detached head", и этот сценарий недостаточно документирован.

dspeyer
источник
Эта ситуация, кажется, является тем, о чем говорит ответ Оуэна выше - где вырезание и вставка «origin / foo» заставляет git думать об этом как «origin / origin / foo».
Мванле
1

Когда вы извлекаете коммит git checkout <commit-hash>или в удаленную ветку, ваш HEAD отключается и пытается создать новый коммит на нем.

Запреты, недоступные для какой-либо ветви или тега, будут собираться и удаляться из хранилища через 30 дней.

Еще один способ решить эту проблему - создать новую ветку для вновь созданного коммита и оформить заказ. git checkout -b <branch-name> <commit-hash>

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

Неша Зорич
источник