Git- Resolve Detached HEAD на сервере

Я довольно новичок в Git- я использую его только с тех пор, как начал работать на своего нынешнего работодателя.

Недавно я внес некоторые изменения на сервер, объединив исправление ошибки, выполненное коллегой на моей локальной машине разработки. Я сделал это, потянув их branch на котором они реализовали исправление ошибки с сервера и слили его с моим локальным master ветвь, которая была актуальной с живой версией кода. Я проверил это на своей локальной машине разработки, и все это, казалось, работало правильно, поэтому я отправил его на сервер.

Однако внесенные мною изменения, по-видимому, привели к появлению еще одной ошибки в живой версии (ошибка, которую она внесла, не была очевидна при локальном тестировании исправления и появилась только после того, как код был запущен).

Эта ошибка, которую я привел, фактически привела к недоступности интенсивно используемой части внутреннего веб-сайта компании, поэтому я сразу же проверил последние рабочие commit & перезапустил сервер, чтобы сайт снова был доступен.

Сейчас я работаю над устранением проблем, которые вызвало исправление на моей локальной машине для разработки, перед тем, как снова отправить исправление на сервер, но после проверки старого commit на сервере вышла живая версия проекта в виде detached HEAD государство. detached HEAD Укажите, что он в данный момент в основном функционален (то есть работает так же, как и до того, как мой коллега начал работать над исправлением этой ошибки, поэтому ошибка все еще присутствует).

Теперь я хочу разрешить detached HEAD на сервере, чтобы я мог снова извлечь рабочий код с сервера, чтобы начать заново с этого момента, но я не уверен, как "сопоставить" остальную часть кода с detached HEAD с которой я сейчас работаю.

Если я бегу git branch на сервере вывод показывает, что у меня есть только master ветвь (которая не работает - так как в ней есть ошибка, которую я ввел при нажатии на исходное исправление ошибки), и (detached from 0e57d3d), какой HEAD на что сейчас указывают.

Другие сообщения, на которые я смотрел, указывают на то, что я должен оформить заказ master для того, чтобы решить detached HEAD, но я не могу этого сделать, так как знаю, что master в настоящее время сломан.

Итак, как я могу прикрепить HEAD опять же, чтобы код работал так же, как и в том состоянии, в котором он находился во время commit что HEAD указывает на? Буду ли я просто запустить git branch оттуда, затем проверить, что branchи сделать это master? Или есть какой-то другой способ сделать это?

1 ответ

Решение

На первый взгляд, это выглядит как копия отсоединенной головы Fix a Git? Это в некоторых отношениях, а не в других. Кроме того, как сказал Торбьерн Равн Андерсен в различных комментариях, вы, вероятно, также захотите координировать свои действия с другими коллегами. Тем не менее, давайте сделаем несколько замечаний, которые не включены (и не соответствуют) другому вопросу.

Отдельная ГОЛОВА ничего не меняет - во всяком случае, пока

Во-первых, "отсоединенный HEAD" просто означает, что вы извлекли один конкретный коммит, часто по его хеш-идентификатору. Существует только одно функциональное различие между этим и git checkout branch-name поскольку это также проверяет один конкретный коммит, и это звучит как круговое определение, потому что оно таково: разница в том, что когда вы делаете это, вы находитесь на ветви, а когда вы делаете это, вы не находитесь на ветви, то есть, у вас есть отдельная ГОЛОВА.

Следовательно, все "отдельные головы" означает "не на ветке". То есть, если вы проверяете один конкретный коммит и попадаете на ветку, вы "на ветке", так как git status скажет; но если вы проверяете тот же конкретный коммит и не входите в ветку, у вас есть "отсоединенная голова", как git status скажет.

git checkout как вы попадаете или выключаете ветку

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

Ты бежал git checkout 1234567 или аналогичный, чтобы проверить более старый коммит, и теперь у него есть "отдельная ГОЛОВА".

Но git checkout также обновляет ваш индекс и / или рабочее дерево

(Очень короткое напоминание: рабочее дерево - это то, где Git пишет и читает обратно копии того, что вы в конечном итоге сохраняете навсегда как коммиты в хранилище. Это в форме, понятной для остальных систем компьютера, вместо Git-файла. специфическая форма. Индекс - это место, где вы и Git создаете следующий коммит, который вы сделаете, он имеет форму, очень специфичную для Git, и имеет дополнительный цикл для координации между внутренней формой, специфичной для Git, и формой "обычного использования компьютера". коммиты - это, по сути, сохраненные индексы, минус лишний цикл.)

Ваш сервер, очевидно, работает за пределами рабочего дерева - и причина, по которой вы запустили git checkout 1234567 во-первых, потому что коммит это верхушка ветви master, который является некоторым коммитом, отличным от 1234567, не работает. если ты git checkout master Вы снова сломаете сервер, восстановив коммит.

Здесь вам нужно координировать действия с другими, потому что для повторного присоединения вашей ГОЛОВКИ вы должны сделать по крайней мере одно из двух:

  • создать новую ветку, или
  • перезапустите сервер, хотя бы временно.

Чтобы создать новую ветку, используйте git checkout -b newbranch

Если вы хотите и можете, чтобы сервер находился "на ветке" без изменения коммитов, просто создайте новую ветку, подсказкой которой является текущий коммит. Для этого используйте git checkout -b:

git checkout -b mostly-working

Теперь ваша ГОЛОВА прикреплена как вы на ветке mostly-working, который вы только что создали. С индексом и рабочим деревом ничего не происходит, потому что имя новой ветви mostly-working имена совершают 1234567 (или что-то еще, что вы извлекли ранее).

Этот коммит, вероятно, где-то позади master, То есть, если бы мы рисовали часть графа коммитов, он бы выглядел так, прежде чем мы сделаем это git checkout -b вещь:

...--o--o--*--o--o   <-- master
           ^
     commit 1234567
          HEAD

Все это git checkout -b действительно, добавляет новое имя, указывающее на этот же коммит. Чтобы нарисовать его в виде обычного текста, нам нужно сдвинуть несколько коммитов вверх или вниз (я пойду вверх):

             o--o   <-- master
            /
...--o--o--*   <-- mostly-working (HEAD)
           ^
  still commit 1234567

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

Если вы делаете новые коммиты сейчас, они продвигают ветку

Просто для завершения вышесказанного, давайте посмотрим, что произойдет, если вы измените что-то в рабочем дереве, git add, а также git commit, Git сделает новый коммит в новой ветке mostly-working:

             o--o   <-- master
            /
...--o--o--o--*   <-- mostly-working (HEAD)

(кстати, я пользуюсь * здесь, чтобы отметить текущий коммит, а-ля git branch маркировка текущей ветки).

То же самое происходит с отдельной головой

Допустим, вы не сделали git checkout -b, но изменил файл и зафиксировал. Это сделало бы новый коммит как обычно, но вместо того, чтобы находиться в ветке, новый коммит был бы новым отдельным HEAD. То есть мы бы нарисовали новый коммит так:

             o--o   <-- master
            /
...--o--o--o--*   <-- HEAD

В этом и заключается разница между "на ветке" и "отделенной головой". Нет ничего особенного в том, чтобы быть "на ветке", кроме того, что новые коммиты, когда сделаны, продвигают эту ветку. Название ветви указывает на верхушку ветви. Когда ты git checkout ветвь, вы проверяете самый верхний коммит этой ветки. Когда вы делаете новые коммиты, вы добавляете их в ветку, заставляя имя указывать на новый коммит. (Новый коммит сам по себе указывает на предыдущий HEAD совершать.) С HEAD просто говорит, какая ветка является текущей, обновляя имя ветви, чтобы указать на новую фиксацию, также обновляет HEAD указать на новый коммит.

Когда у вас отсоединен HEAD, процесс точно такой же: новый коммит указывает на предыдущий коммит, а новый коммит становится новым HEAD совершить. Там просто нет названия для этого коммита (ну, кроме HEAD конечно, но HEAD меняется, когда ты git checkout!).

Другие вопросы по тегам