Проверка тега Git приводит к «отключенному состоянию HEAD»

166

Я разрабатываю сценарий развертывания для моего проекта git, и я только начал использовать теги. Я добавил новый тег под названием v2.0:

git tag -a v2.0 -m "Launching version 2.0"

И я поместил этот тег в удаленный репозиторий

git push --tags

Когда я пытаюсь выполнить сценарий развертывания и проверить v2.0тег, я получаю следующее сообщение:

Вы находитесь в состоянии «отсоединенная ГОЛОВА». Вы можете осмотреться, внести экспериментальные изменения и зафиксировать их, а также можете отменить любые коммиты, которые вы делаете в этом состоянии, не влияя на какие-либо ветви, выполнив другую проверку. Если вы хотите создать новую ветку для сохранения созданных вами коммитов, вы можете сделать это (сейчас или позже), снова используя -b с командой checkout. Пример: git checkout -b new_branch_name HEAD теперь находится на

Это нормально? Хранилище находится в подвешенном состоянии, потому что если я сделаю:

git branch

Я получаю этот вывод:

* (no branch)
  master

Извините, если это очевидно, но я не мог понять это.

Khriz
источник
Когда вы говорите «выполнить скрипт развертывания и проверить версию 2.0», ваш код выглядит как «git checkout v2.0»? Я пытаюсь обновить мой скрипт выпуска, и когда я запускаю «git checkout v2.0» с моей рабочей машины, я получаю «error: pathspec 'v2.0' не соответствует ни одному из файлов, известных git». Несмотря на то, что я запустил "git push origin --tags" на моей локальной машине, прежде чем делать "git checkout v2.0" на производстве. Я также пытался запустить "git pull --tags" и "git fetch --tags" в рабочей среде до вызова "git checkout v2.0", и это тоже не работает ... Я все еще получаю ошибка. Любые идеи?
Джон Эрк
3
Я собирался удалить вышеупомянутый комментарий, но потом решил, что его поддержание может помочь кому-то еще. Я получал сообщение об ошибке, потому что в моем имени тега был TYPO, "git checkout v2.0". Однако ошибка, связанная с опечаткой, - это та же самая ошибка, которую вы получите, запустив git checkout v2.0 БЕЗ опечатки ДО запуска «git fetch --tags». Итак, в конечном итоге, моя проблема была решена с помощью запуска "git fetch --tags" ДО запуска "git checkout v2.0" без каких-либо опечаток. Уф!
Джон Эрк
Хорошо, да, вам нужно сделать fetch --tags раньше (или git fetch, который будет извлекать все из удаленного), чтобы git мог проверить тег. Извините, я только что видел ваш комментарий сегодня.
Хриз

Ответы:

429

Хорошо, сначала несколько терминов, несколько упрощенных.

В git, tag(как и многие другие вещи) это то, что называется древовидная . Это способ ссылки на точку в истории проекта. Treeishes может быть тегом, коммитом, спецификатором даты, порядковым спецификатором или многими другими вещами.

Теперь branchтег похож на тег, но является подвижным. Когда вы «включаете» ветвь и делаете коммит, ветка перемещается на новый коммит, который вы сделали, что указывает на его текущую позицию.

Ваш HEADуказатель на ветку, которая считается "текущей". Обычно, когда вы клонируете репозиторий, он HEADбудет указывать на то, masterчто в свою очередь будет указывать на коммит. Когда вы затем делаете что-то подобное git checkout experimental, вы переключаетесь, HEADчтобы указать на experimentalветку, которая может указывать на другой коммит.

Теперь объяснение.

Когда вы делаете a git checkout v2.0, вы переключаетесь на коммит, на который не указывает a branch. HEADТеперь «отдельные» и не указывает на ветви. Если вы решите сделать коммит сейчас (как вы можете), нет указателя ветки для обновления, чтобы отслеживать этот коммит. Переключение на другой коммит заставит вас потерять этот новый коммит, который вы сделали. Вот что говорится в сообщении.

Обычно вы можете сказать git checkout -b v2.0-fixes v2.0. Это создаст новый указатель ветви на коммит, на который указывает treeish v2.0(в данном случае тег), а затем сместит ваш HEADуказатель на это. Теперь, если вы делаете коммиты, можно будет отслеживать их (используя v2.0-fixesветку), и вы можете работать как обычно. Нет ничего «плохого» в том, что вы сделали, особенно если вы просто хотите взглянуть на v2.0код. Однако, если вы хотите внести какие-либо изменения, которые вы хотите отследить, вам понадобится ветка.

Вы должны потратить некоторое время на понимание всей модели DAG в git. Это удивительно просто и делает все команды достаточно понятными.

Нуфал Ибрагим
источник
Хорошо, спасибо, мне не нужно вносить никаких изменений в код, поэтому я думаю, что все в порядке. Мне не нужно создавать филиал. Большое спасибо!
Хриз
1
Я был потерян в первый раз, когда просматривал этот ответ, но после прочтения документации по ветвлению в Git: http://git-scm.com/book/en/Git-Branching-What-a-Branch - это было намного яснее ,
Марк Стайлз
3
Потрясающий ответ, но позвольте мне добавить следующее: «Переключение на другой коммит приведет к потере этого нового коммита, который вы сделали». Вы по-прежнему можете найти коммит git reflog, о котором очень полезно знать! Если сборка мусора не произошла, казалось бы, «невозможно» потерять коммит.
Дмитрий Минковский
Нефиксированные коммиты могут быть потеряны операцией сборки мусора.
Нуфал Ибрагим
1
URL неправильный, потому что они изменили макет страницы.
'23
12

Да, это нормально. Это потому, что вы извлекаете один коммит, у которого нет головы. Тем более это (рано или поздно) не глава какой-либо отрасли.

Но обычно с этим состоянием проблем нет. Вы можете создать новую ветку из тега, если это заставляет вас чувствовать себя в большей безопасности :)

KingCrunch
источник
1
Хорошо, я буду держать это таким образом ... безопасность в любом случае переоценена;)
Хриз
Как вы прокомментировали в ответе Noufals (лучше, я должен сказать;)): Пока вы ничего не меняете, вам не о чем беспокоиться. Однако, если вы предполагаете , что вы можете что-то изменить, вы можете просто создать ветку, потому что они дешевы в git, и вы можете удалить ее (и воссоздать позже и так далее).
KingCrunch