Как сортировать теги git по порядку строк версии формы rc-X. Y. Z. W?


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

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

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

6 67

6 ответов:

использовать версию вроде

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ễn Thái Ngọc Duy (pclouds):

 --sort=<type>

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

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

вставить "- " чтобы изменить порядок сортировки.


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

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 (Q2 2015),the versionsort.prerelease переменная конфигурации может использоваться для указания этого v1.0-pre1 приходит раньше v1.0.

посмотреть commit f57610a by Junio C Hamano (gitster).

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


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

посмотреть совершить 0571979 (26 янв 2016), и commit 1d094db (24 янв 2016) by Джефф Король (peff).
(слитый Junio C Hamano--gitster-- in commit 8bad3de, 01 фев 2016)

tag: не показывайте неоднозначные имена тегов как"tags/foo"

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

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

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

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


Обновление Git 2.12 (Q1 2017)

посмотреть commit c026557,commit b178464,commit 51acfa9,commit b823166,commit 109064a,commit 0c1b487,commit 9ffda48,commit eba286e (08 дек 2016) by SZEDER Gábor (szeder).
(слитый Junio C Hamano--gitster-- in commit 1ac244d, 23 янв 2017)

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

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

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

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

адаптации это 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 всякий раз, когда мне нужно перечислить теги.

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

git tag -l | sort -V --reverse