Как получить последний тег Git, соответствующий критериям регулярных выражений


Мне нужна команда Git, чтобы получить/найти последний тег, начинающийся с 'v', чтобы получить последний версионный коммит (я использую теги с буквой v в начале для тегирования следующей версии приложения (пример: v0.9.1 beta).

Есть ли способ сделать это?

8 29

8 ответов:

Для этого я использую следующую команду:

git describe --match "v[0-9]*" --abbrev=4 HEAD

Он также изменит версию, если вы что-то сделали с исходным деревом с момента вашего последнего версионного тега.

Обратите внимание, что это Не регулярное выражение, а глобус, но работает для приведенного примера.

git tag -l -n v*

Ответ КАРАСЦИ Иштвана уже объясняет, как найти теги, соответствующие глобусу, что обычно достаточно хорошо. Если вам когда-нибудь понадобится настоящее регулярное выражение, хотя:

for tag in $(git tag | grep YOURREGEX); do
    git describe --tags --long --match="$tag" 2>/dev/null
done | sort -k2 -t"-" | head -n1
  • Если вам нужен только ближайший тег (то есть то, чего достигнет --abrev=0), добавьте | cut -d"-" -f1
  • Если вы не хотите, чтобы поведение --long также выводило точно соответствующий тег, включая часть -0-hash, добавьте вместо этого | sed -e's/-0-.*$//'.

Тег примера вопроса, вероятно, будет используйте регулярное выражение ^v\d+\.\d+\.\d+\D*$ (хотя \D*$ может быть необязательным).

git describe --match v*

Используйте это.

Хотя здесь достаточно одного регулярного выражения --match "v[0-9]*", знайте, что Git 2.13 (Q2 2017) улучшит это:

"git describe" и еще "git name-rev" были научены брать несколько шаблонов имен рефов, чтобы ограничить набор рефов, чтобы основать их именование вывода на, а также научился принимать негативные паттерны к ссылки имен не должны использоваться для именования через их опцию " --exclude".

См. commit 77d21f2, совершить 43f8080, совершить 96415b4, совершить 290be66, commit 4a68748 (18 Jan 2017) by Jacob Keller (jacob-keller).
(объединено Junio C Hamano -- gitster -- in commit 1b32498 , 27 Feb 2017)

Теперь вы можете иметь шаблон множественного совпадения:

--match <pattern>:

Рассматривайте только теги, соответствующие заданному шаблону glob(7), исключая префикс "refs/tags/".
Это можно использовать, чтобы избежать утечки личных тегов из хранилище.

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

И у вас также есть исключите шаблон (или несколько) теперь !

--exclude <pattern>::

Не рассматривайте теги, соответствующие заданному шаблону glob(7), исключая префикс " refs / tags/".

Это можно использовать для сужения пространства тегов и находите только теги, соответствующие некоторым значимым критериям.
Если задано несколько раз, список шаблонов будет накапливаться и теги, соответствующие любому из шаблонов, будут исключены.
В сочетании с --match тег будет рассматриваться, когда он соответствует хотя бы одному шаблону --match и не соответствует ни одному из шаблонов --exclude.
Используйте --no-exclude для очистки и сброса списка шаблонов.

Проблема с использованием git describe, как и другие ответы, заключается в том, что git describe покажет вам теги, доступные из HEAD (или фиксации, которую вы указываете.)

Представьте, что у вас есть 3 тега: v1, v2 и v3. Если HEAD находится в точке между v2 и v3, git describe вернет v2, а не v3.

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

Тогда эта команда сделает это:

git for-each-ref --sort=-taggerdate --count=1 refs/tags/v*

Я использую

git tag -l --format "%(objecttype) %(refname:short)" --sort=-version:refname --merged HEAD "v*"

git tag интерпретирует паттерн как глобус. Таким образом, вы не можете указать полное регулярное выражение. Просто используйте минимальный Глоб (v*) или даже не Глоб вообще. Вы получите больше, чем только один соответствующий тег в отсортированном порядке (сначала самая высокая версия тега), и вы сможете повторно использовать выходные данные после этого.

Также с помощью Git descript вы можете получить последний тег, который не просто доступен из головы:

git describe --match "v*" --abbrev=0 --tags $(git rev-list --tags --max-count=1)