Какой самый надежный способ получить имя ссылки, на которую последний раз указал 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>...]'
Поэтому, если ветвь будет удалена или изменена с помощью коммита, я думаю, что метод потерпит неудачу.