Какой самый надежный способ получить имя ссылки, на которую последний раз указал HEAD?

После операции, которая движется HEAD (такие как checkout, reset и т. д.), вы всегда можете получить HEAD указали перед этой операцией, запустив, например,

git rev-parse @{1}

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

Тогда я проверяю develop ветвь, запустив

git checkout develop

и в конечном итоге

Как я могу получить информацию из внутренностей моего репо о том, что HEAD указывал на master перед этой последней проверкой?

Этот ответ предлагает извлечь имя из reflog с awk как возможность; например, с

git reflog -1 | awk '{ print $6; exit }'

(спасибо Эд и Этан за их предложения).

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

Тем не менее, ФП выражает обеспокоенность по поводу надежности и обратной совместимости в своем комментарии:

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

Являются ли опасения ОП законными? Какой самый надежный способ сделать это?

2 ответа

Решение

В некоторых быстрых тестах это, кажется, работает довольно хорошо (хотя тесты не были совсем тщательными или подчеркивали странные сценарии):

git rev-parse --symbolic-full-name @{-1}

Я был в середине публикации комментария к ответу @EmilDavtyan, в котором говорилось, что проблема с несколькими ссылками является проблематичной, поскольку я не думаю, что git заботится (и поэтому не отслеживает) последнее местоположение HEAD реф, но потом я вспомнил @{-1} и как это было бы гораздо менее полезно, если бы он не мог справиться с этой ситуацией, и поэтому после быстрого теста кажется, что он как-то справляется (вполне возможно, что он разберет сообщение в reflog для всего, что я знаю).

Я должен также указать, что связанный OP является правильным, что ручной синтаксический анализ reflog не является надежным. Фактически, когда я пошел тестировать фрагмент awk здесь, я не получил правильных результатов. Оказывается, это потому, что у меня есть --decorate по умолчанию, который заполнял строку дополнительными полями и сбрасывал счетчик.

Я бы просто использовал:

git branch --contains HEAD@{1}

Это даст вам ветки, которые содержат ранее извлеченный коммит.


Провел небольшой тест, используя ответ @Etan, и я не думаю, что он разбирает сообщение в git reflog для ветки, он просто ищет его:

emil ~ git checkout -b temp2
Switched to a new branch 'temp2'
emil ~ git rev-parse --symbolic-full-name @{-1}
refs/heads/temp
emil ~ git branch -d temp
Deleted branch temp (was f3163f9).
emil ~ git rev-parse --symbolic-full-name @{-1}
@{-1}
fatal: ambiguous argument '@{-1}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

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

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