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