Como classificar as tags git por ordem de string de versão do formulário rc-XYZW?


109

Quando eu insiro um comando:

git tag -l

Eu obtenho esses resultados:

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

Em vez disso, eu quero:

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

Como é possível classificar a lista atual para obter esses resultados?


1
Com o Git 2.0, você logo será capaz de fazer um git tag -l --sort=version:refname "rc-*"e obter a saída que deseja. veja minha resposta abaixo
VonC

1
Git 2.0 já foi lançado, e todas as respostas abaixo usando 'sort' não são mais necessárias. --sortestá disponível para git tag
VonC de

Respostas:


157

Usar classificação de versão

git tag -l | sort -V

ou para git versão> = 2.0

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

@miku verifique! para mim, sim
Robert Mutke

5
O argumento -V não está disponível na versão fornecida pelo OS X (10.8) (5.93). :(
Julien

2
você pode usar homebrew ou macports para instalar a versão GNU do sort. brew install gsortentão você pode modificar a linha acima para git tag -l | gsort -Ve deve funcionar para você.
Goran

4
Eu tive que usar brew install coreutilspara obter o gsortcomando. brew install gsortfalhou, dizendo que nenhum pacote foi chamado gsort.
nwinkler

Sem sorte no msysgit também
cchamberlain

78

Com o Git 2.0 (junho de 2014), você poderá especificar uma ordem de classificação!

Consulte commit b6de0c6 , do commit 9ef176b , de autoria de Nguyễn Thái Ngọc Duy ( pclouds) :

 --sort=<type>

Classifique em uma ordem específica .
O tipo suportado é:

  • " refname" (ordem lexicográfica),
  • " version:refname" ou " v:refname" (nomes de tag são tratados como versões).

Anexe " -" para inverter a ordem de classificação.


Então, se você tem:

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

Aqui está o que você obteria:

# 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

Desde o commit b150794 (por Jacob Keller, git 2.1.0, agosto de 2014), você pode especificar essa ordem padrão:

tag.sort

Esta variável controla a ordem de classificação das tags quando exibidas por git-tag.
Sem a --sort=<value>opção " " fornecida, o valor desta variável será usado como o padrão.

comentários de robinst :

a ordem de classificação da versão agora pode (Git 2.1+) ser configurada como padrão:

git config --global tag.sort version:refname

Conforme observado por Leo Galleguillos nos comentários :

Para configurar o Git para mostrar as tags mais recentes primeiro ( ordem decrescente ), basta adicionar um hífen antes da versão .
O comando se torna:

git config --global tag.sort -version:refname

Com Git 2.4 (2º trimestre de 2015) , a versionsort.prereleasevariável de configuração pode ser usada para especificar o que v1.0-pre1vem antesv1.0 .

Veja o commit f57610a de Junio ​​C Hamano ( gitster) .

Observação (veja abaixo) versionsort.prereleaseSuffixagora (2017) é um alias obsoleto para versionsort.suffix.


git 2.7.1 (fevereiro de 2016) melhorará a git tagprópria produção .

Consulte o commit 0571979 (26 de janeiro de 2016) e o commit 1d094db (24 de janeiro de 2016) de Jeff King ( peff) .
(Fundido por Junio ​​C Hamano - gitster- no commit 8bad3de , 01 de fevereiro de 2016)

tag: não mostra nomes de tag ambíguos como " tags/foo"

Desde b7cc53e ( tag.c: use ' ref-filter' APIs, 2015-07-11), git tagcomeçou a mostrar tags com nomes ambíguos (ou seja, quando " heads/foo" e " tags/foo" existem) como " tags/foo" em vez de apenas " foo".
Isso é ambos:

  • sem sentido; a saída de " git tag" inclui apenas refs/tags, portanto, sabemos que " foo" significa aquela em " refs/tags".
  • e ambíguo; na saída original, sabemos que a linha " foo" significa que " refs/tags/foo" existe. Na nova saída, não está claro se queremos dizer " refs/tags/foo" ou " refs/tags/tags/foo".

A razão disso acontecer é que o commit b7cc53e mudou git tagpara usar a %(refname:short)formatação de saída " " do filtro ref , que foi adaptado de for-each-ref. Este código mais geral não sabe que nos preocupamos apenas com as tags e usa shorten_unambiguous_refpara obter o short-name.
Precisamos dizer a ele que nos preocupamos apenas com " refs/tags/" e que deve ser reduzido em relação a esse valor.

vamos adicionar um novo modificador à linguagem de formatação, " strip", para remover um conjunto específico de componentes de prefixo.
Isso corrige " git tag" e permite que os usuários invoquem o mesmo comportamento de seus próprios formatos personalizados (para " tag" ou " for-each-ref"), deixando " :short" com o mesmo significado consistente em todos os lugares.

Se strip=<N>for anexado, <N>remove os componentes do caminho separados por barra da frente do refname (por exemplo,%(refname:strip=2) transforma refs/tags/fooem foo.
<N>Deve ser um número inteiro positivo.
Se um ref exibido tiver menos componentes do que <N>, o comando aborta com um erro.

Para git tag, quando não especificado, o padrão é %(refname:strip=2).


Atualizar Git 2.12 (primeiro trimestre de 2017)

Consulte commit c026557 , commit b178464 , commit 51acfa9 , commit b823166 , commit 109064a , commit 0c1b487 , commit 9ffda48 , commit eba286e (08 de dezembro de 2016) por SZEDER Gábor ( szeder) .
(Incorporado por Junio ​​C Hamano -gitster - no commit 1ac244d , 23 de janeiro de 2017)

versionsort.prereleaseSuffixé um alias obsoleto para versionsort.suffix.

O prereleaseSuffixrecurso de comparação de versão que é usado em " git tag -l" não funcionava corretamente quando dois ou mais pré-lançamentos para o mesmo lançamento estavam presentes (por exemplo 2.0, quando,, 2.0-beta1e 2.0-beta2 estão lá e o código precisa ser comparado 2.0-beta1e 2.0-beta2).


--sortnão existe no git 1.9.1. (trabalhado em 2.0.0)
Tibor Vass

@TeaBee true, editei a resposta de acordo, já que o Git 2.0 foi lançado agora.
VonC

1
Com o Git 2.1.0, a ordem de classificação da versão agora pode ser configurada como padrão:git config --global tag.sort version:refname
robinst

1
Vale a pena explicar por que isso é melhor do que sort -V. A única vantagem que vejo é a portabilidade para sistemas que não possuem classificação GNU. Mas se você tem | sort -Vgolfe melhor. O fato é: este método de classificação não usa nenhuma informação específica do Git (ao contrário, por exemplo, da ordem topológica do objeto apontado como stackoverflow.com/questions/6900328/… )
Ciro Santilli 郝海东 冠状 病 六四 六四 法轮功

1
@LeoGalleguillos Obrigado. Eu incluí seu comentário na resposta para mais visibilidade.
VonC

12

De acordo com esta resposta , em plataformas que não suportam, sort -Vcomo Windows e OSX, você pode usar

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


1
@ Ovi-WanKenobi você precisa executá-lo no shell Cygwin (ou mingw).
Cédric

10

Combinando as respostas já aqui:

Repositório local

git -c 'versionsort.suffix=-' tag --list --sort=-v:refname
  • suffix=-evitará 2.0-rcvir "depois"2.0
  • --sort=- colocará o número da versão mais alto no topo.

Repositório remoto

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

A vantagem disso é que nenhum objeto é baixado do controle remoto.

Para mais informações veja esta resposta .


Uso muito interessante de versionsort.suffix. +1.
VonC

2

Para obter uma classificação reversa com a sort -Vabordagem:

git tag -l | sort -V --reverse


1

Acabei escrevendo um script de shell simples para simplificar essa tarefa.

#!/usr/bin/env bash

TAGS=$(git tag)
CODE=$?

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

exit $CODE

Eu salvei isso como git-tags no meu $PATHe executei git tagssempre que precisar listar as tags.


2
tag git | sort -V; saída $ PIPESTATUS
luxigo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.