Как отсортировать теги git по порядку строк версии формы rc-XYZW?

Когда я ввожу команду:

git tag -l

Я получаю такие результаты:

rc-0.9.0.0
rc-0.9.0.1
rc-0.9.0.10
rc-0.9.0.11
rc-0.9.0.12
rc-0.9.0.2
rc-0.9.0.3
rc-0.9.0.4
rc-0.9.0.5
rc-0.9.0.6
rc-0.9.0.7
rc-0.9.0.8
rc-0.9.0.9

Вместо этого я хочу:

rc-0.9.0.0
rc-0.9.0.1
rc-0.9.0.2
rc-0.9.0.3
rc-0.9.0.4
rc-0.9.0.5
rc-0.9.0.6
rc-0.9.0.7
rc-0.9.0.8
rc-0.9.0.9
rc-0.9.0.10
rc-0.9.0.11
rc-0.9.0.12

Как можно отсортировать текущий список, чтобы получить такие результаты?

9 ответов

Решение

Использовать сортировку версий

git tag -l | sort -V

или для git версии>= 2.0

git tag -l --sort=v:refname
git tag -l --sort=-v:refname # reverse

С Git 2.0 (июнь 2014 г.) вы сможете указать порядок сортировки!

См. Commit b6de0c6, из commit 9ef176b, автор Nguy Nn Thái Ngọc Duy ( pclouds ):

 --sort=<type>

Сортировка в определенном порядке.
Поддерживаемый тип:

  • " refname "(лексикографический порядок),
  • " version:refname " или же " v:refname "(имена тегов рассматриваются как версии).

Prepend " - "изменить порядок сортировки.


Итак, если у вас есть:

git tag foo1.3 &&
git tag foo1.6 &&
git tag foo1.10

Вот что вы получите:

# lexical sort
git tag -l --sort=refname "foo*"
foo1.10
foo1.3
foo1.6

# version sort
git tag -l --sort=version:refname "foo*"
foo1.3
foo1.6
foo1.10

# reverse version sort
git tag -l --sort=-version:refname "foo*"
foo1.10
foo1.6
foo1.3

# reverse lexical sort
git tag -l --sort=-refname "foo*"
foo1.6
foo1.3
foo1.10

Так как commit b150794 (автор Jacob Keller, git 2.1.0, август 2014), вы можете указать порядок по умолчанию:

tag.sort

Эта переменная контролирует порядок сортировки тегов при отображении git-tag,
Без " --sort=<value> "при условии, что значение этой переменной будет использоваться по умолчанию.

robinst комментарии:

теперь порядок сортировки версий (Git 2.1+) можно настроить по умолчанию:

git config --global tag.sort version:refname

С Git 2.4 (2 квартал 2015 года) versionsort.prerelease переменная конфигурации может быть использована для указания того, что v1.0-pre1 приходит раньше v1.0,

Смотрите коммит f57610a от Junio ​​C Hamano ( gitster )

Примечание (см. Ниже) versionsort.prereleaseSuffix сейчас (2017) устарел псевдоним для versionsort.suffix ,


Git 2.7.1 (февраль 2016 года) улучшит выход git tag сам.

См. Commit 0571979 (26 января 2016 г.) и commit 1d094db (24 января 2016 г.) Джеффом Кингом ( peff )
(Объединено Юнио С Хамано - gitster - в коммите 8bad3de, 01 февраля 2016 г.)

tag: не показывать двусмысленные имена тегов как " tags/foo "

С b7cc53e (tag.c: использовать ref-filter API, 2015-07-11), git tag начал показывать теги с неоднозначными именами (т.е. когда оба " heads/foo " а также " tags/foo "существует) как" tags/foo "вместо просто" foo ".
Это оба:

  • бессмысленно; вывод " git tag "включает только refs/tags так что мы знаем, что foo "означает тот, кто в" refs/tags ".
  • и неоднозначный; в исходном выводе мы знаем, что строка " foo" Значит это " refs/tags/foo "существует. В новом выводе неясно, имеем ли мы в виду" refs/tags/foo " или же " refs/tags/tags/foo ".

Это происходит потому, что коммит b7cc53e переключен git tag использовать ref-filter's " %(refname:short) "форматирование вывода, которое было адаптировано из for-each-ref, Этот более общий код не знает, что мы заботимся только о тегах, и использует shorten_unambiguous_ref чтобы получить short-name,
Нам нужно сказать, что мы заботимся только о refs/tags/ ", и оно должно сокращаться по отношению к этой стоимости.

давайте добавим новый модификатор к языку форматирования " strip msgstr ", чтобы удалить определенный набор префиксных компонентов.
Это исправляет git tag "и позволяет пользователям вызывать то же поведение из своих собственных пользовательских форматов (для" tag " или же " for-each-ref ") пока ухожу" :short "с одинаковым постоянным значением во всех местах.

Если strip=<N> прилагается, полоски <N> Компоненты пути, разделенные косой чертой, от передней части refname (например, %(refname:strip=2) витки refs/tags/foo в foo,
<N> должно быть положительным целым числом.
Если отображаемая ссылка имеет меньше компонентов, чем <N>, команда прерывается с ошибкой.

За git tag если не указано, по умолчанию %(refname:strip=2),


Обновление Git 2.12 (1 квартал 2017 года)

См. Коммит c026557, коммит b178464, коммит 51acfa9, коммит b823166, коммит 109064a, коммит 0c1b487, коммит 9ffda48, коммит eba286e ( 08.12.2016) от SZEDER Gábor ( szeder )
(Объединено Юнио С Хамано - gitster - в коммите 1ac244d, 23 января 2017 г.)

versionsort.prereleaseSuffix является устаревшим псевдонимом для versionsort.suffix,

prereleaseSuffix особенность сравнения версий, которая используется в git tag -l "неправильно, когда присутствовали два или более пререлизов для одного и того же выпуска (например, когда 2.0, 2.0-beta1, а также 2.0-beta2 есть и код нужно сравнить 2.0-beta1 а также 2.0-beta2).

Совмещаем ответы уже здесь:

Локальный репозиторий

git -c 'versionsort.suffix=-' tag --list --sort=-v:refname
  • suffix=- помешает 2.0-rc приход "после" 2.0
  • --sort=- поместит наивысший номер версии вверху.

Удаленный репозиторий

git -c 'versionsort.suffix=-' ls-remote -t --exit-code --refs --sort=-v:refname "$repo_url" \
    | sed -E 's/^[[:xdigit:]]+[[:space:]]+refs\/tags\/(.+)/\1/g'

Преимущество этого состоит в том, что никакие объекты не загружаются с пульта.

Для получения дополнительной информации см. Этот ответ.

Согласно этому ответу, на платформах, которые не поддерживают sort -V как Windows и OSX, вы можете использовать

git tag -l | sort -n -t. -k1,1 -k2,2 -k3,3 -k4,4

Чтобы получить обратную сортировку с sort -V подход:

git tag -l | sort -V --reverse

Адаптируйте этот Perl-скрипт, который сортирует теги, которые выглядят как client_release/7.2/7.2.25, к вашей конкретной схеме пометки.

В итоге я написал простой сценарий оболочки, чтобы упростить эту задачу.

#!/usr/bin/env bash

TAGS=$(git tag)
CODE=$?

if [ $CODE = 0 ]; then
    echo "$TAGS" | sort -V
fi

exit $CODE

Я сохранил это как git-tags в моем $PATH и беги git tags всякий раз, когда мне нужно перечислить теги.

Если вы работаете в Linux и используете ZSH; Просто используйте gtlкоманда. Он должен быть предварительно определен как псевдоним для вас.

Код псевдонима:
gtl='gtl(){ git tag --sort=-v:refname -n -l "${1}*" }; noglob gtl'

попробуйте список для специального форматирования с последним

git tag -l --sort=refname | grep -E '^\d+\.\d+\.\d+.*' | tail -n 1

или первый

git tag -l --sort=refname | grep -E '^\d+\.\d+\.\d+.*' | head -n 1

Другие вопросы по тегам