Я новичок в ветвящихся сложностях Git. Я всегда работаю над одной веткой и фиксирую изменения, а затем периодически нажимаю на мое удаленное начало.
Где-то недавно я сделал сброс некоторых файлов, чтобы вывести их из стадии коммитов, а позже сделал, rebase -i
чтобы избавиться от пары недавних локальных коммитов. Сейчас я нахожусь в состоянии, которое я не совсем понимаю.
В моей рабочей области git log
показывает, что именно я ожидал - я на правильном поезде с коммитами, которые я не хотел, и новыми там и т. Д.
Но я только что отправил в удаленный репозиторий, и тут есть что-то другое - пара коммитов, которые я убил в ребазе, были перенесены, а новых, зафиксированных локально, там нет.
Я думаю, что «master / origin» отделен от HEAD, но я не на 100% уверен в том, что это значит, как визуализировать его с помощью инструментов командной строки и как это исправить.
I did a reset of some files to get them out of commit staging
частично? извините за вопросы :)Ответы:
Во-первых, давайте выясним, что такое HEAD и что он означает, когда он отсоединен.
HEAD - это символическое имя для текущего извлеченного коммита. Когда HEAD не отсоединен («нормальная» 1 ситуация: у вас есть ветвь извлечена), HEAD фактически указывает на «ref» ветки, а ветвь указывает на коммит. Таким образом, HEAD «привязан» к ветке. Когда вы делаете новый коммит, ветка, на которую указывает HEAD, обновляется, чтобы указывать на новый коммит. HEAD следует автоматически, так как он просто указывает на ветку.
git symbolic-ref HEAD
доходностьrefs/heads/master
Ветвь с именем «мастер» извлечена.
git rev-parse refs/heads/master
yield17a02998078923f2d62811326d130de991d1a95a
Этот коммит является текущим наконечником или «головой» главной ветви.
git rev-parse HEAD
также дает17a02998078923f2d62811326d130de991d1a95a
это то, что значит быть «символическим реф». Он указывает на объект через какую-то другую ссылку.
(Символические ссылки изначально были реализованы как символические ссылки, но позже были заменены простыми файлами с дополнительной интерпретацией, чтобы их можно было использовать на платформах, которые не имеют символических ссылок.)
У нас есть
HEAD
→refs/heads/master
→17a02998078923f2d62811326d130de991d1a95a
Когда HEAD отсоединен, он указывает непосредственно на коммит, а не косвенно указывает на один через ветвь. Вы можете думать об отделенной голове как о неназванной ветви.
git symbolic-ref HEAD
не удается сfatal: ref HEAD is not a symbolic ref
git rev-parse HEAD
доходность17a02998078923f2d62811326d130de991d1a95a
Поскольку это не символьная ссылка, он должен указывать непосредственно на сам коммит.
У нас есть
HEAD
→17a02998078923f2d62811326d130de991d1a95a
Важно помнить с отсоединенным HEAD, что если коммит, на который он указывает, в противном случае не имеет ссылки (ни один другой реф не может его достичь), то он станет «висящим», когда вы извлекаете какой-то другой коммит. В конечном итоге такие оборванные коммиты будут удалены в процессе сборки мусора (по умолчанию они хранятся не менее 2 недель и могут храниться дольше, если на них ссылается reflog HEAD).
1 Совершенно нормально выполнять «обычную» работу с отдельным HEAD, вам просто нужно следить за тем, что вы делаете, чтобы не выискивать выпавшую историю из reflog.
Промежуточные шаги интерактивной перебазировки выполняются с помощью отдельного HEAD (частично, чтобы не загрязнять рефлог активной ветки). Если вы завершите полную операцию перебазировки, она обновит вашу исходную ветвь с совокупным результатом операции перебазирования и снова присоединит HEAD к исходной ветке. Я предполагаю, что вы никогда полностью не завершили процесс ребазирования; это оставит вас с отключенным HEAD, указывающим на коммит, который был недавно обработан операцией rebase.
Чтобы выйти из вашей ситуации, вы должны создать ветку, которая указывает на коммит, на который в данный момент указывает ваша отдельная голова:
(эти две команды могут быть сокращены как
git checkout -b temp
)Это присоединит вашу ГОЛОВУ к новой
temp
ветке.Затем вы должны сравнить текущий коммит (и его историю) с обычной веткой, над которой вы ожидали работать:
(Возможно, вы захотите поэкспериментировать с параметрами журнала: добавить
-p
, отменить,--pretty=…
чтобы просмотреть все сообщения журнала и т. Д.)Если ваша новая
temp
ветка выглядит хорошо, вы можете обновить (например),master
чтобы указать на нее:(эти две команды могут быть сокращены как
git checkout -B master temp
)Затем вы можете удалить временную ветку:
Наконец, вы, вероятно, захотите добавить восстановленную историю:
Возможно, вам придется добавить
--force
в конец этой команды команду push, если удаленная ветвь не может быть «быстро перенаправлена» к новому коммиту (т. Е. Вы удалили или переписали какой-либо существующий коммит или иным образом переписали некоторый фрагмент истории).Если вы выполняли операцию перебазирования, вам, вероятно, следует ее очистить. Вы можете проверить, была ли перебазировка в процессе поиска по каталогу
.git/rebase-merge/
. Вы можете вручную очистить выполняющуюся перебазировку, просто удалив этот каталог (например, если вы больше не помните цель и контекст активной операции перебазировки). Обычно вы использовали быgit rebase --abort
, но это делает некоторую дополнительную перезагрузку, которую вы, вероятно, хотите избежать (она перемещает HEAD обратно в исходную ветвь и сбрасывает ее обратно в исходную фиксацию, что отменит часть работы, которую мы сделали выше).источник
man git-symbolic-ref
: «В прошлом.git/HEAD
была символическая ссылка, указывающая наrefs/heads/master
. Когда мы хотели переключиться на другую ветку, мы сделалиln -sf refs/heads/newbranch .git/HEAD
, и когда мы хотели выяснить, на какой ветви мы находимся, мы сделалиreadlink .git/HEAD
. Но символические ссылки не являются полностью переносимыми поэтому теперь они устарели, и по умолчанию используются символические ссылки (как описано выше). "git branch -f master HEAD && git checkout master
достаточно - при условии, что ваша цель - сохранить текущую голову, но обозначить ее какmaster
. Другие цели также имеют смысл и требуют других рецептов.Просто сделай это:
Или, если у вас есть изменения, которые вы хотите сохранить, сделайте это:
источник
git reset
должен прийти с предупреждением «Если вы не знаете, что делаете, остановите это». Просто оправился от часа ужаса, думая, что потерял последнюю неделю работы. Спасибо!Я столкнулся с этой проблемой, и когда я прочитал в верхней голосовал ответ:
Я подумал: ах-ха! Если
HEAD
это символическое имя для фиксации текущего заказа, я могу примирить егоmaster
, перебрав его сmaster
:Эта команда:
master
HEAD
обратно в точку,HEAD
отклоненную отmaster
master
Конечным результатом является то, что все коммиты, которые были,
HEAD
но неmaster
были, также были включеныmaster
.master
остается проверенным.По поводу пульта:
Удаленную историю больше нельзя пересылать с использованием вашей локальной истории. Вам нужно будет принудительно нажать (
git push -f
), чтобы перезаписать удаленную историю. Если у вас есть соавторы, обычно имеет смысл согласовать это с ними, чтобы все были на одной странице.После того, как вы нажмете
master
на удаленныйorigin
, ваш филиал удаленного отслеживанияorigin/master
будет обновлен до точки , к тому же , как совершитьmaster
.источник
git reflog
затем сбросьте ветку к этому коммитуgit rest —hard $commit
Ищите здесь основное объяснение отстраненной головы:
http://git-scm.com/docs/git-checkout
Командная строка для визуализации:
или
вы получите вывод, как показано ниже:
В
* (no branch)
шоу вы в отдельных голове.Вы могли бы прийти в это состояние, выполнив и
git checkout somecommit
т. Д., И он предупредил бы вас следующим:Теперь, чтобы получить их на мастера:
Сделайте
git reflog
или даже простоgit log
и запишите ваши коммиты. Теперьgit checkout master
иgit merge
коммиты.Редактировать:
Чтобы добавить, используйте
git rebase -i
не только для удаления / уничтожения коммитов, которые вам не нужны, но и для их редактирования. Просто упомяните «edit» в списке коммитов, и вы сможете изменить свой коммит, а затем выпустить a,git rebase --continue
чтобы продолжить. Это гарантировало бы, что вы никогда не входите в отдельную ГОЛОВУ.источник
Получите ваш отдельный коммит на свою ветку
Просто беги
git checkout -b mynewbranch
.Затем запустите
git log
, и вы увидите, что коммит теперь находитсяHEAD
в этой новой ветви.источник
mynewbranch
прикрепляется ли к чему-либо?если у вас есть только основная ветвь и вы хотите вернуться к «разработке» или функции, просто сделайте это:
Примечание: проверка происхождения / развития .
Вы в отдельном состоянии ГОЛОВА . Вы можете осмотреться, внести экспериментальные изменения и зафиксировать их, а также можете отменить любые коммиты, которые вы делаете в этом состоянии, не влияя ни на какие ветви, выполнив другую проверку ...
тогда
Оно работает :)
источник
Если вы хотите выдвинуть вашу текущую отдельную ГОЛОВКУ (проверьте
git log
раньше), попробуйте:отправить свою отдельную ГОЛОВУ в главную ветку в источнике. Если ваш толчок отклонен, попробуйте
git pull origin master
сначала получить изменения от источника. Если вас не волнуют изменения от источника, и они отклонены, потому что вы сделали некоторую преднамеренную перебазировку и хотите заменить origin / master своей отсоединенной в данный момент ветвью - тогда вы можете принудительно сделать это (-f
). В случае, если вы потеряли некоторый доступ к предыдущим коммитам, вы всегда можете запуститьgit reflog
просмотр истории всех ветвей.Чтобы вернуться в основную ветку, сохранив изменения, попробуйте следующие команды:
Смотрите: Git: «В настоящее время нет ни на одной ветке». Есть ли простой способ вернуться на ветку, сохранив изменения?
источник
Я нашел этот вопрос при поиске
You are in 'detached HEAD' state.
Проанализировав, что я сделал, чтобы попасть сюда, по сравнению с тем, что я делал в прошлом, я обнаружил, что допустил ошибку.
Мой нормальный поток:
На этот раз я сделал:
Проблема в том, что я случайно сделал:
Скорее, чем:
Исправление (в моей ситуации) состояло в том, чтобы просто выполнить вышеупомянутую команду и затем продолжить поток:
источник
У меня сработало следующее (используя только ветку master):
Первый толкает отсоединенную ГОЛОВУ к удаленному источнику.
Второй переходит к мастеру ветки.
Третий восстанавливает ГОЛОВУ, которая становится присоединенной к хозяину ветви.
Проблемы могут возникнуть при первой команде, если толчок отклонен. Но это больше не будет проблемой отсоединенной головки, а связано с тем, что отсоединенная головка не знает о некоторых удаленных изменениях.
источник
Я только что столкнулся с этой проблемой сегодня и уверен, что решил ее, выполнив:
Я был на своем рабочем компьютере, когда понял, как это сделать, и теперь у меня такая же проблема на моем персональном компьютере. Так что придется подождать до понедельника, когда я вернусь за рабочий компьютер, чтобы посмотреть, как именно я это сделал.
источник
Если вы абсолютно уверены, что HEAD - это хорошее состояние:
Вы, вероятно, не можете подтолкнуть к происхождению, поскольку ваш мастер отклонился от источника. Если вы уверены, что никто не использует репо, вы можете принудительно нажать:
Наиболее полезно, если вы находитесь в функциональной ветке, которой больше никто не пользуется.
источник
Все, что вам нужно сделать, это «git checkout [имя-ветви]», где [имя-ветви] - это имя исходной ветви, из которой вы попали в состояние отсоединенного заголовка. (Отдельно от asdfasdf) исчезнет.
Так, например, в ветке 'dev' вы извлекаете коммит asdfasd14314 ->
вы сейчас находитесь в отстраненном состоянии
'git branch' перечислит что-то вроде ->
но выйти из состояния отстраненной головы и вернуться к dev ->
и тогда 'git branch' отобразит список ->
но это, конечно, если вы не намерены сохранять какие-либо изменения от отсоединенного состояния головы, но я обнаруживаю, что делаю это много, не намереваясь вносить какие-либо изменения, а просто посмотреть на предыдущий коммит
источник
Как указал Крис, у меня была следующая ситуация
git symbolic-ref HEAD
не удается сfatal: ref HEAD is not a symbolic ref
Однако
git rev-parse refs/heads/master
указывал на хороший коммит, откуда я мог бы восстановить (В моем случае последний коммит, и вы можете увидеть этот коммит, используяgit show [SHA]
После этого я сделал много беспорядочных вещей, но то, что, похоже, исправило, это просто
git symbolic-ref HEAD refs/heads/master
И голова прикреплена!
источник
Вместо того чтобы делать
git checkout origin/master
просто делать
git checkout master
затем
git branch
подтвердит вашу ветку.источник
У меня была эта проблема сегодня, когда я обновил подмодуль, но не был ни в одной ветке. Я уже совершил, так что копить, проверять, расстегивать не получится. Я закончил тем, что выбрал коммит из оторванной головы. Итак, сразу после того, как я совершил (когда толчок не удался), я сделал:
Мое мышление пошло: я нахожусь на отдельной голове, но я хочу быть на хозяине. Предполагая, что мое отдельное состояние не очень отличается от мастера, если бы я мог применить свой коммит к мастеру, я был бы настроен. Это именно то, что делает вишня.
источник
Если вы сделали несколько коммитов поверх мастера и просто хотите «слить назад»
master
(т.е. вы хотитеmaster
указать на нихHEAD
), однострочник будет:master
, даже если она уже существует (что похоже на перемещениеmaster
и это то, что мы хотим).HEAD
, где вы находитесь.master
.Я нашел это особенно полезным в случае суб-репозиториев, которые также часто оказываются в отдельном состоянии.
источник
У меня была та же проблема, и я решил ее, выполнив следующие шаги.
Если вам нужно сохранить ваши изменения
git checkout master
команду, чтобы вернуть вас в основную ветку.git checkout -b changes
иgit checkout -B master changes
Если вам не нужны ваши изменения
Для удаления всех неотслеживаемых файлов из вашей ветки запустите
git clean -df
.Затем вам нужно очистить все неустановленные изменения в вашем хранилище. Для этого нужно бежать
git checkout --
Наконец, вы должны вернуть свою ветку в основную ветку с помощью
git checkout master
команды.источник
Для меня это было так же просто, как снова удалить локальную ветку, так как у меня не было локальных коммитов, которые я хотел нажать:
Так я и сделал:
А затем снова проверяем ветку:
источник
Когда я лично нахожусь в ситуации, когда оказывается, что я внес некоторые изменения, пока я не нахожусь
master
(тоHEAD
есть отсоединен прямо надmaster
и между ними нет коммитов), может помочь запоминание:источник
Проще говоря, состояние отсоединенного HEAD означает, что вы не проверены на HEAD (или чаевые) какой-либо ветви .
Понять с примером
Ветвь в большинстве случаев является последовательностью нескольких коммитов, таких как:
Фиксация 1: master -> branch_HEAD (123be6a76168aca712aea16076e971c23835f8ca)
Фиксация 2: мастер -> 123be6a76168aca712aea16076e971c23835f8ca -> branch_HEAD (100644a76168aca712aea16076e971c23835f8ca)
Как вы можете видеть выше в случае последовательности коммитов, ваша ветвь указывает на ваш последний коммит. Таким образом, в этом случае, если вы оформите заказ на фиксацию 123be6a76168aca712aea16076e971c23835f8ca, то вы окажетесь в состоянии отсоединенной головы, так как HEAD вашей ветви указывает на 100644a76168aca712aea16076e971c23835f8ca и технически вы проверены в HEAD ни одной ветви. Следовательно, вы находитесь в отключенном состоянии HEAD.
Теоретическое объяснение
В этом блоге четко указано, что Git-репозиторий является деревом коммитов, причем каждый коммит, указывающий на своего предка, обновляется с каждым указателем коммита, и эти указатели на каждую ветку хранятся в подкаталогах .git / refs. Теги хранятся в .git / refs / tags, а ветки хранятся в .git / refs /head. Если вы посмотрите на любой из файлов, то обнаружите, что каждый тег соответствует одному файлу с хэш-фиксацией из 40 символов и, как объяснено выше @Chris Johnsen и @Yaroslav Nikitenko, вы можете проверить эти ссылки.
источник
Я попал в действительно глупое состояние, я сомневаюсь, что кто-то еще найдет это полезным .... но на всякий случай
который я в конце концов исправил
источник
Это сработало для меня отлично:
1.
git stash
сохранить ваши локальные модификацииЕсли вы хотите отменить изменения,
git clean -df
git checkout -- .
git clean удалит все неотслеживаемые файлы (предупреждение: хотя он не удалит проигнорированные файлы, упомянутые непосредственно в .gitignore, он может удалить игнорируемые файлы, находящиеся в папках), а git checkout удалит все неотмеченные изменения.
2.
git checkout master
переключиться на основную ветку (при условии, что вы хотите использовать master)3.
git pull
извлечь последний коммит из основной ветви4.
git status
чтобы проверить, все ли выглядит отличноисточник
В моем случае я запустил
git status
и увидел, что у меня есть несколько неотслеживаемых файлов в моем рабочем каталоге.Чтобы заставить ребейс работать, мне просто нужно было их почистить (так как они мне не нужны).
источник
Если вы используете EGit в Eclipse: предположите, что ваш мастер - ваша основная ветка разработки
После этого вы сможете снова подключиться к origin-master.
источник
У меня такая же проблема. Я спрятал свои изменения
git stash
и жестко переустановил ветвь локально для предыдущего коммита (я думал, что это вызвало это), затем сделал,git pull
и я не получаю эту голову отсоединенной сейчас. Не забудьтеgit stash apply
снова внести изменения.источник
источник