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

Quando eu entro em um comando:

git tag -l 

Eu recebo 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?

Use a sorting da versão

 git tag -l | sort -V 

ou para a versão git> = 2.0

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

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

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

  --sort= 

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

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

Prefira ” - ” para inverter a ordem de sorting.


Então, se você tem:

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

Aqui está o que você teria:

 # 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 ordenação de tags quando exibida por git-tag .
Sem a opção ” --sort= ” fornecida, o valor dessa variável será usado como padrão.

robinst comentários :

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

 git config --global tag.sort version:refname 

Com o Git 2.4 (Q2 2015) , a variável de configuração versionsort.prerelease pode ser usada para especificar que a v1.0-pre1 vem antes da v1.0 .

Veja commit f57610a por Junio ​​C Hamano ( gitster ) .

Nota (veja abaixo) versionsort.prereleaseSuffix é agora (2017) um alias obsoleto para versionsort.suffix .


O git 2.7.1 (fevereiro de 2016) irá melhorar a saída do próprio git tag .

Veja commit 0571979 (26 Jan 2016) e commit 1d094db (24 Jan 2016) por Jeff King ( peff ) .
(Mesclado por Junio ​​C Hamano – gitster – em commit 8bad3de , 01 fev 2016)

tag : não mostre nomes de tags ambíguos como ” tags/foo

Desde b7cc53e ( tag.c : use APIs ‘ ref-filter ‘, 2015-07-11), a git tag começou a mostrar tags com nomes ambíguos (ou seja, quando ambos ” 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 , então sabemos que ” foo ” significa aquele 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 pela qual isso acontece é que commit b7cc53e mudou a git tag para usar a formatação de saída ” %(refname:short) ” do ref-filter, que foi adaptada de for-each-ref . Esse código mais geral não sabe que nos importamos apenas com tags e usa shorten_unambiguous_ref para obter o short-name .
Precisamos dizer que nos preocupamos apenas com ” refs/tags/ “, e deve encurtar 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 “) enquanto deixam ” :short ” com o mesmo significado consistente em todos os lugares.

Se strip= for anexado, retira componentes de caminho separados por barra da frente do nome de referência (por exemplo, %(refname:strip=2) transforma refs/tags/foo em foo .
deve ser um inteiro positivo.
Se um ref exibido tiver menos componentes que , o comando será anulado com um erro.

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


Atualização do Git 2.12 (1º trimestre de 2017)

Veja cometer c026557 , cometer b178464 , cometer 51acfa9 , cometer b823166 , cometer 109064a , cometer 0c1b487 , cometer 9ffda48 , cometer eba286e (08 de dezembro de 2016) por SZEDER Gábor ( szeder ) .
(Mesclado por Junio ​​C Hamano – gitster – em commit 1ac244d , 23 jan 2017)

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

O recurso prereleaseSuffix da comparação de versão usada em ” git tag -l ” não foi correto quando dois ou mais pré-lançamentos para o mesmo lançamento estavam presentes (por exemplo, quando 2.0 , 2.0-beta1 e 2.0-beta2 estão lá e o código precisa compare 2.0-beta1 e 2.0-beta2 ).

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

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

Adapte este script perl , que classifica as tags que se parecem com client_release/7.2/7.2.25 , para o seu esquema de marcação específico.

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 em meu $PATH e executo git tags sempre que preciso listar tags.

Para obter uma sorting inversa com a abordagem de sort -V :

 git tag -l | sort -V --reverse