Git опишите с двумя тегами на том же коммите - PullRequest
12 голосов
/ 11 ноября 2011

Иногда у нас есть два тега на одном коммите. Когда мы используем git description для этого коммита, git description всегда возвращает первый тег. Мое чтение справочной страницы git-description, похоже, указывает на то, что должен быть возвращен второй тег (что более логично).

  SEARCH STRATEGY
     For each committish supplied, git describe will first look for a tag which tags
     exactly that commit. Annotated tags will always be preferred over lightweight tags, 
     and tags with newer dates will always be preferred over tags with older dates. 
     If an exact match is found, its name will be output and searching will stop.

Есть ли способ заставить git describe вернуть второй тег?

Ответы [ 3 ]

4 голосов
/ 11 ноября 2011

Вы пробовали какие-либо опции для описания git?

   --all
       Instead of using only the annotated tags, use any ref found in .git/refs/. This option enables
       matching any known branch, remote-tracking branch, or lightweight tag.

   --tags
       Instead of using only the annotated tags, use any tag found in .git/refs/tags. This option
       enables matching a lightweight (non-annotated) tag.
0 голосов
/ 08 мая 2019

Поведение Git в этом случае странное и запутанное.

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

На практике это не так.

Допустим, я зафиксировал ABCD. Я делаю два тега (аннотированные), v1.0 и v2.0.

У меня тогда есть что-то подобное ..

master -> ABCD hotfix -> ABCD v1.0 (3423) -> ABCD v1.0 (4234) -> ABCD

Когда я извлекаю ветку, такую ​​как master или hotfix, я замечаю, что git просто сохраняет в .git/HEAD ссылку на ветку, так что все хорошо, это не неоднозначная, а конкретная ветка.

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

Когда вы извлекаете тег, такой как v1.0 или v2.0, HEAD не будет содержать тег ref или тэг commit, а вместо идентификатора коммита, как если бы вы извлекли коммит напрямую!

В этом случае возникает путаница: если вы извлекаете ветку, такую ​​как master, то при проверке тега, состояния git и description вы увидите правильный тег, который вы извлекли, даже если он неоднозначный!

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

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

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

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

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

В этом случае ваши сценарии должны будут попытаться получить единственный лучший идентификатор, но если идентификатор неоднозначный, это должно привести к ошибке. Вы не можете полагаться на такие вещи, как состояние git или описание, поскольку иногда они не будут генерировать то, что было в последний раз извлечено, как видно при переключении с тега на тег, а не переходить на тег.

Это можно увидеть в .git/logs/HEAD, который, кажется, содержит отчеты о переходах по тегам, но как только вы попали в тег, ничего не регистрируется.

Describe всегда возвращает самый последний аннотированный (не легкий) тег. Если вы смешиваете типы тегов, вы не должны принимать последовательное поведение. Облегченные теги, по-видимому, также используют самую последнюю версию (предположительно, основанную на отметке времени файла, а не на времени фиксации), но не ищутся без --all или --tags. Даже с параметром --all аннотированные теги имеют преимущество перед более поздними облегченными тегами.

Единственный удобный способ получить все идентификаторы для текущего тега, который я могу найти, - это запустить git show-ref с разыменованием и выполнить grep для вашего текущего коммита. Это не будет включать метки времени для сортировки.

0 голосов
/ 31 августа 2018

Из всего, что я могу сказать, «git description» не может устранить неоднозначность легких тегов и поэтому печатает первый, с которым сталкивается.В этом фрагменте предполагается, что теги следуют шаблону, сортируемому с помощью `sort -R ', и будут возвращать тег« самый последний »для данного SHA:

git tag --contains SHA | sort -R | tail -1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...