Git: HEAD исчез, хотите объединить его в мастер

reflog vs GITK http://siteroller.net/archive/images/Forums/headless%20GIT.png

Верхним изображением является вывод: git reflog.
Дно - это то, что GITK в git GUI (msysgit) показывает мне, когда я смотрю на всю историю ветвей.

Последние несколько коммитов не отображаются в git GUI.

  • Почему они не отображаются на GITK (по крайней мере, как ветка или что-то еще)?
  • Как объединить их в master?
  • Я понял, что это произошло, когда я проверил тег 0.42. Почему это не то же самое, что и мастер? (Я пометил мастера в его последнем состоянии)
  • Когда я нажимаю push, почему удаленное репо заявляет, что оно актуально.. не следует ли пытаться обновить эти коммиты в любую ветвь, в которой они находятся?

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

Если имеет значение увидеть предыдущую историю, проект представляет собой [довольно мощный] JS-выбор цвета, который может быть просмотрен здесь в его целостность.

Ответ 1

зачем обновлять эти коммиты в любую ветвь, в которой они находятся?

Это просто: вы не в какой-либо отрасли, но в настоящее время работаете над отсоединенной головой:

начиная с версии 1.5.0, приведенная выше команда отделяет ваш HEAD от текущей ветки и напрямую указывает на фиксацию, названную тегом.

Вы можете увидеть это, если вы выполните gitk --all

Один способ исправить это (если вы все сделали)

$ git log -1
# note the SHA-1 of latest commit
$ git checkout master
# reset your branch head to your previously detached commit
$ git reset --hard <commit-id>

Другим способом было бы объединить вашу работу с текущим мастер-заголовком, который находится в теге:

 $ git checkout -m 0.42

но это теряет историю ваших фиксаций, сделанных на отдельной головке.


Я понял, что это произошло, когда я проверил тег 0.42. Почему это не то же самое, что и мастер? (Я отметил мастер в своем последнем состоянии)

Нет, это не то же самое, что и мастер. Поскольку Jefromi указывает в комментариях, ветка может перемещаться (или переименовываться или удаляться, или...)
master ссылался на ту же фиксацию, что и тег '0.42', но это не всегда так. При проверке тега вы не проверяете ветку, следовательно, состояние "отсоединенного HEAD".


Примечание: как упоминалось в этом SO-ответе, обозначение @{1}, которое вы видите, $(git symbolic-ref HEAD)@{1}, то есть использует reflog для текущей (здесь отдельной) ветки, а не HEAD reflog.

Ответ 2

В Git фиксируется формальный ациклический граф, где каждая фиксация указывает на один или более родителей. В дополнение к объектам commit вы также имеете ссылки ref (например, reference): ветки и теги. Они указывают на различные коммиты в графе фиксации. Ваша проблема в том, что вы не были на ветке, когда делали коммиты, и ни одна ветка (или тег) не указывала на них. В любое время вы можете использовать команды

git status

и

git branch

чтобы проверить, находитесь ли вы в ветке или нет.

Почему они не отображаются на GITK (по крайней мере, как ветка или что-то еще)?

Насколько я знаю, Gitk ищет объекты фиксации, начиная с ref. Если никакие рефлексы не указывают на ваши коммиты (или направленный ациклический граф коммитов, который ведет к ним), они фактически невидимы.

Как объединить их в master?

К счастью, средство reflog отслеживает операции, такие как проверки и фиксации (среди прочего). В своем листинге reflog вы можете увидеть запись для своего последнего фиксации:

1b8c11d HEAD @{1} commit: Укороченная функция toRgb()

Вы можете объединить коммиты в свою основную ветку с помощью идентификатора SHA1, который вы видите в рефлоге:

git checkout master
git merge 1b8c11d

Я понял, что это произошло, когда я проверил тег 0.42. Почему это не то же самое, что и мастер? (Я отметил мастер в своем последнем состоянии)

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

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

Ваши коммиты не находятся ни в одной ветке. Сначала вам необходимо объединить их с веткой (например, с мастером), как показано выше. После этого толчок должен работать нормально.

Ответ 3

Самый простой способ воскресить свои коммиты - указать на них какую-то ветвь. Вы знаете SHA, так что это легко:

git branch resurrected_junk 1b8c11d

(это SHA, прочитанное с вашего снимка экрана), также может быть

git branch resurrected_junk [email protected]

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

В вашем случае, я думаю, вы получите такую ​​историю:

Master --> Optimize toRGB --> ... ---> shortened toRGB = resurrected_junk

Затем обновите представление gitk, и коммиты должны появиться. (Я использую qgit, поэтому я просто догадываюсь)

После этого вы сможете объединить/нажать/все, что вам нужно (как вам нравится).