Что означают «теги, чьи коммиты достижимы из указанного коммита»? - PullRequest
0 голосов
/ 04 февраля 2020

В одном из моих проектов я пытаюсь получить самый последний тег после проверки ветки или из origin/master. Если я запускаю git tag -l --sort=-creatordate --merged | head -n1 или git describe, я получаю тот же результат, но из тега из далекого прошлого. Если я избавлюсь от --merged, он покажет правильный, самый последний тег в проекте.

Извлечение указанной ветви c возвращает мне правильный, последний известный тег в репо, но если он из origin/master или FETCH_HEAD, он возвращает мне один в прошлом.

Мне в основном интересно, как работает флаг --merged, потому что на страницах справочника просто написано Only list tags whose commits are reachable from the specified commit.

1 Ответ

1 голос
/ 04 февраля 2020

Это две части:

  • общая концепция достижимость и
  • как работает git tag -l --merged, которая использует саму концепцию.

Достижимость является свойством графа или, в случае Git, ориентированного графа . Обратитесь к статье Википедии или Думайте как (а) Git, для правильного объяснения. (Или посмотрите один из моих многочисленных ответов StackOverflow, показывающих, как определить, какие ветви содержат различных коммитов.) В остальном предполагается, что вы уже понимаете достижимость.

A tag в Git это просто причудливый указатель: по сути, стрелка, указывающая на один конкретный коммит. Но есть еще одна особенность тегов в Git: они могут указывать на объект тега , а не непосредственно на коммит. 1 Объект тега имеет аннотации для git tag -a или сообщение для git tag -m. Затем объект тега содержит необработанный идентификатор ha sh базового коммита.

Это приводит нас к формулировке в документации:

на страницах справочника просто сказано [--merged]

Список только тех тегов, чьи коммиты достижимы из указанного коммита.

Мы запускаем:

git tag -l --merged <commit-specifier>

, поэтому мы выбираем один коммит Это «указанный коммит».

Операция git tag -l теперь будет проходить через каждый тег. Тег указывает либо на коммит, либо на аннотированный объект тега, который указывает на коммит. Этот коммит существует где-то в общем графе Git коммитов. Вопрос, который применяется --merged, таков: можем ли мы достичь отмеченного коммита из указанного коммита?

Если мы сможем достичь помеченного коммита, git tag -l списков тег Если нет (или если мы должны пропустить тег, потому что он не помечает коммит в конце концов), git tag -l опускает тег.


1 Имя тега фактически разрешено указывать на объект дерева или блоба, а также на объект фиксации или аннотированный тег. В этом случае фиксация вообще отсутствует, и git tag -l --merged просто проигнорирует этот тег. Кроме того, аннотированный тег-объект может фактически ссылаться на любой другой тип объекта, а не только на объект фиксации. Таким образом, истинное правило для разрешения имени тега:

  • Если имя тега относится к аннотированному объекту тега, переключитесь на этот аннотированный объект тега.
  • Пока у нас есть аннотированный объект тега , переключитесь на объект, который является целью этого аннотированного тега. (Git обозначает это внутренне как шелушение меток, аналогично шелушению лука, слой за слоем.)
  • Стоп: у нас есть объект.

Теперь мы знаем объект, к которому относится тег. Если это коммит, он является кандидатом на этот --merged листинг. Если нет, то это не так.

...