Вопрос: Как я могу примирить отдельную головку с мастером / источником?


Я новичок в ветвящихся сложностях Git. Я всегда работаю над одной ветвью и фиксирую изменения, а затем периодически нажимаю на свое отдаленное происхождение.

Где-то недавно я сделал сброс некоторых файлов, чтобы вытащить их из стадии фиксации, а затем сделал rebase -iчтобы избавиться от пары недавних местных коммитов. Теперь я в состоянии, я не совсем понимаю.

В моей рабочей области, git logточно показывает, что я ожидаю - я нахожусь на правильном поезде с коммитами, которые мне не нужны, а новые там и т. д.

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

Я думаю, что «master / origin» отделен от HEAD, но я не на 100% не понимаю, что это значит, как визуализировать его с помощью инструментов командной строки и как его исправить.


1254


источник


Ответы:


Сначала давайте уточним что такое HEAD и что это означает, когда он отсоединен.

HEAD - это символическое имя для текущего фиксации. Когда HEAD не отсоединяется ("нормальный" 1 ситуация: у вас вывешен филиал), HEAD фактически указывает на «ref» ветки, а ветвь указывает на фиксацию. Таким образом, ГОЛОВКА прикрепляется к ветке. Когда вы делаете новую фиксацию, ветвь, на которую указывает HEAD, обновляется, чтобы указать на новую фиксацию. HEAD следует автоматически, поскольку он просто указывает на ветку.

  • git symbolic-ref HEADдоходность refs/heads/master
    Отключена ветка с именем «master».
  • git rev-parse refs/heads/masterУступать 17a02998078923f2d62811326d130de991d1a95a
    Это фиксация является текущим концом или «головкой» ведущей ветви.
  • git rev-parse HEADтакже дает 17a02998078923f2d62811326d130de991d1a95a
    Это то, что означает «символический реф». Он указывает на объект через какую-либо другую ссылку.
    (Символьные ссылки были первоначально реализованы как символические ссылки, но позже были заменены на простые файлы с дополнительной интерпретацией, чтобы их можно было использовать на платформах, которые не имеют символических ссылок.)

У нас есть HEADrefs/heads/master17a02998078923f2d62811326d130de991d1a95a

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

  • git symbolic-ref HEADс fatal: ref HEAD is not a symbolic ref
  • git rev-parse HEADдоходность 17a02998078923f2d62811326d130de991d1a95a
    Поскольку он не является символическим ref, он должен указывать непосредственно на сам фиксат.

У нас есть HEAD17a02998078923f2d62811326d130de991d1a95a

Важная вещь, которую следует помнить с отсоединенным HEAD, состоит в том, что если фиксация, на которую указывает она, в противном случае не будет отображаться (никакой другой ref не сможет ее достичь), тогда она станет «болтаться», когда вы проверите другую фиксацию. В конце концов, такие оборванные коммиты будут обрезаны через процесс сбора мусора (по умолчанию они хранятся как минимум 2 недели и могут храниться дольше, ссылаясь на reflog HEAD).

1 Совершенно нормально выполнять «нормальную» работу с отсоединенным HEAD, вам просто нужно следить за тем, что вы делаете, чтобы не ловить рыбу из истории.


Промежуточные шаги интерактивной перестановки выполняются с отсоединенным HEAD (частично, чтобы не загрязнять рефлектор активной ветви). Если вы закончите операцию полной перезагрузки, она обновит исходную ветвь кумулятивным результатом операции rebase и вернет HEAD в исходную ветвь. Я предполагаю, что вы никогда не полностью завершили процесс переучета; это оставит вас с отсоединенным HEAD, указывая на фиксацию, которая была обработана в последнее время операцией rebase.

Чтобы оправиться от вашей ситуации, вы должны создать ветвь, указывающую на фиксацию, на которую указывает ваш выделенный HEAD:

git branch temp
git checkout temp

(эти две команды могут быть сокращены как git checkout -b temp)

Это вернет ваш HEAD к новому tempфилиал.

Затем вы должны сравнить текущую фиксацию (и ее историю) с нормальной веткой, на которой вы ожидали работать:

git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp

(Вероятно, вам захочется поэкспериментировать с параметрами журнала: add -p, оставьте --pretty=…для просмотра всего сообщения журнала и т. д.)

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

git branch -f master temp
git checkout master

(эти две команды могут быть сокращены как git checkout -B master temp)

Затем вы можете удалить временную ветку:

git branch -d temp

Наконец, вы, вероятно, захотите нажать восстановленную историю:

git push origin master

Возможно, вам придется добавить --forceдо конца этой команды нажать, если удаленная ветвь не может быть «переадресована» на новую фиксацию (т. е. вы сбросили или переписали какую-либо существующую фиксацию или иначе переписали немного истории).

Если вы были в середине операции переустановки, вы, вероятно, должны ее очистить. Вы можете проверить, выполнялась ли переформатирование, ища каталог .git/rebase-merge/, Вы можете вручную очистить обновленную базу данных, просто удалив этот каталог (например, если вы больше не помните цель и контекст активной операции переадресации). Обычно вы будете использовать git rebase --abort, но это делает некоторый дополнительный сброс, который вы, вероятно, хотите избежать (он перемещает HEAD обратно в исходную ветвь и сбрасывает его обратно на исходный коммит, что отменит часть работы, которую мы сделали выше).


2140



Просто сделайте это:

git checkout master

Или, если у вас есть изменения, которые вы хотите сохранить, сделайте следующее:

git checkout -b temp
git checkout -B master temp

505



Я столкнулся с этой проблемой, и когда я прочитал в главном голосовавшем ответе:

HEAD - это символическое имя для текущего фиксации.

Я подумал: Ах-ха! Если HEADэто символическое имя для текущей проверки, я могу смириться с ней masterпутем его master:

git rebase HEAD master

Эта команда:

  1. проверяет master
  2. определяет родительские HEADвернуться к сути HEADрасходится с master
  3. играет те коммиты на вершине master

Конечным результатом является то, что все фиксации, которые были в HEADно нет masterтогда также в master, masterостается проверенным.


Что касается пульта:

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

Удаленная история больше не может быть быстро перенаправлена ​​с использованием вашей локальной истории. Вам нужно будет принудительно нажать ( git push -f), чтобы перезаписать удаленную историю. Если у вас есть сотрудники, обычно имеет смысл согласовать это с ними, чтобы все были на одной странице.

После того, как вы masterудаленному origin, удаленная ветка отслеживания origin/masterбудет обновляться, указывая на тот же master,


96



Look here for basic explanation of detached head:

http://git-scm.com/docs/git-checkout

Command line to visualize it:

git branch

or

git branch -a

you will get output like below:

* (no branch)
master
branch1

The * (no branch) shows you are in detached head.

You could have come to this state by doing a git checkout somecommit etc. and it would have warned you with the following:

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

Now, to get them onto master:

Do a git reflog or even just git log and note your commits. Now git checkout master and git merge the commits.

git merge HEAD@{1}

Edit:

To add, use git rebase -i not only for deleting / killing commits that you don't need, but also for editing them. Just mention "edit" in the commit list and you will be able to amend your commit and then issue a git rebase --continue to go ahead. This would have ensured that you never came in to a detached HEAD.


78



Get your detached commit onto its own branch

Simply run git checkout -b mynewbranch.

Then run git log, and you'll see that commit is now HEAD on this new branch.


29



if you have just master branch and wanna back to "develop" or a feature just do this :

git checkout origin/develop

Note: checking out origin/develop.

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...

then

git checkout -b develop

It works :)


18



If you want to push your current detached HEAD (check git log before), try:

git push origin HEAD:master

to send your detached HEAD into master branch at origin. If your push gets rejected, try git pull origin master first to get the changes from origin. If you don't care about the changes from origin and it's rejected, because you did some intentional rebase and you want to replace origin/master with your currently detached branch - then you may force it (-f). In case you lost some access to previous commits, you can always run git reflog to see the history from all branches.


To get back on a master branch, while keeping the changes, try the following commands:

git rebase HEAD master
git checkout master

See: Git: "Not currently on any branch." Is there an easy way to get back on a branch, while keeping the changes?


16



If you are completely sure HEAD is the good state:

git branch -f master HEAD
git checkout master

You probably can't push to origin, since your master has diverged from origin. If you are sure no one else is using the repo, you can force-push:

git push -f

Most useful if you are on a feature branch no one else is using.


7