Как получить последний тег Git, соответствующий критериям регулярных выражений
Мне нужна команда Git, чтобы получить/найти последний тег, начинающийся с 'v', чтобы получить последний версионный коммит (я использую теги с буквой v в начале для тегирования следующей версии приложения (пример: v0.9.1 beta).
Есть ли способ сделать это?
8 ответов:
Для этого я использую следующую команду:
git describe --match "v[0-9]*" --abbrev=4 HEAD
Он также изменит версию, если вы что-то сделали с исходным деревом с момента вашего последнего версионного тега.
Обратите внимание, что это Не регулярное выражение, а глобус, но работает для приведенного примера.
Ответ КАРАСЦИ Иштвана уже объясняет, как найти теги, соответствующие глобусу, что обычно достаточно хорошо. Если вам когда-нибудь понадобится настоящее регулярное выражение, хотя:
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*$
может быть необязательным).
Хотя здесь достаточно одного регулярного выражения
--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
для очистки и сброса списка шаблонов.
Проблема с использованием
Представьте, что у вас есть 3 тега: v1, v2 и v3. Если HEAD находится в точке между v2 и v3,git describe
, как и другие ответы, заключается в том, чтоgit describe
покажет вам теги, доступные из HEAD (или фиксации, которую вы указываете.)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*) или даже не Глоб вообще. Вы получите больше, чем только один соответствующий тег в отсортированном порядке (сначала самая высокая версия тега), и вы сможете повторно использовать выходные данные после этого.