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, поэтому я просто догадываюсь)
После этого вы сможете объединить/нажать/все, что вам нужно (как вам нравится).