web-dev-qa-db-fra.com

Comment trier les balises git par ordre de chaîne de version du formulaire rc-X.Y.Z.W?

Lorsque j'entre une commande:

git tag -l

J'obtiens de tels résultats:

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

Au lieu de cela, je veux:

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

Comment est-il possible de trier la liste actuelle pour obtenir de tels résultats?

89

Utiliser le tri des versions

git tag -l | sort -V

ou pour la version git> = 2.0

git tag -l --sort=v:refname
git tag -l --sort=-v:refname # reverse
114
Robert Mutke

Avec Git 2.0 (juin 2014), vous pourrez spécifier un ordre de tri!

Voir commit b6de0c6 , de commit 9ef176b , rédigé par Nguyễn Thái Ngọc Duy (pclouds) :

 --sort=<type>

Trier dans un ordre spécifique .
Le type pris en charge est:

  • "refname" (ordre lexicographique),
  • "version:refname" Ou "v:refname" (Les noms de balises sont traités comme des versions).

Ajoutez "-" Pour inverser l'ordre de tri.


Donc, si vous avez:

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

Voici ce que vous obtiendriez:

# 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

Depuis commit b150794 (par Jacob Keller, git 2.1.0, août 2014), vous pouvez spécifier cet ordre par défaut:

tag.sort

Cette variable contrôle l'ordre de tri des balises lorsqu'elle est affichée par git-tag .
Sans l'option "--sort=<value>" Fournie, la valeur de cette variable sera utilisée par défaut.

robinstcommentaires :

l'ordre de tri des versions peut maintenant (Git 2.1+) être configuré par défaut:

git config --global tag.sort version:refname

Avec Git 2.4 (Q2 2015) , la variable de configuration versionsort.prerelease Peut être utilisée pour spécifier que v1.0-pre1 Précède v1.0.

Voir commit f57610a by Junio ​​C Hamano (gitster) .

Remarque (voir ci-dessous) versionsort.prereleaseSuffix Est désormais (2017) un alias obsolète pour versionsort.suffix.


git 2.7.1 (février 2016) améliorera la sortie de git tag lui-même.

Voir commit 0571979 (26 janvier 2016), et commit 1d094db (24 janvier 2016) par Jeff King (peff) .
(Fusionné par Junio ​​C Hamano - gitster - in commit 8bad3de , 01 février 2016)

tag: n'affiche pas les noms de balises ambigus comme "tags/foo"

Depuis b7cc53e (tag.c: Utilisez les API 'ref-filter', 2015-07-11), git tag A commencé à afficher des balises avec des noms ambigus (c.-à-d. , lorsque "heads/foo" et "tags/foo" existe) sous la forme "tags/foo" au lieu de "foo".
C'est à la fois:

  • inutile; la sortie de "git tag" ne comprend que refs/tags, donc nous savons que "foo" signifie celui de "refs/tags".
  • et ambigu; dans la sortie d'origine, nous savons que la ligne "foo" signifie que "refs/tags/foo" existe. Dans la nouvelle sortie, il n'est pas clair si nous voulons dire "refs/tags/foo" Ou "refs/tags/tags/foo".

La raison pour laquelle cela se produit est que la validation b7cc53e a commuté git tag Pour utiliser le formatage de sortie "%(refname:short)" du filtre ref, qui a été adapté de for-each-ref. Ce code plus général ne sait pas que nous nous soucions uniquement des balises et utilise shorten_unambiguous_ref Pour obtenir le short-name.
Nous devons lui dire que nous ne nous soucions que de "refs/tags/", Et il devrait raccourcir par rapport à cette valeur.

ajoutons un nouveau modificateur au langage de formatage, "strip", pour supprimer un ensemble spécifique de composants de préfixe.
Cela corrige "git tag" Et permet aux utilisateurs d'invoquer le même comportement à partir de leurs propres formats personnalisés (pour "tag" ou "for-each-ref") Tout en quittant ":short" Avec sa même signification cohérente dans tous les endroits.

Si strip=<N> Est ajouté, les composants de chemin séparés par une barre oblique <N> Sont supprimés de l'avant du nom de référence (par exemple, %(refname:strip=2) transforme refs/tags/foo En foo.
<N> Doit être un entier positif.
Si une référence affichée a moins de composants que <N>, La commande s'interrompt avec une erreur.

Pour git tag, Lorsqu'il n'est pas spécifié, la valeur par défaut est %(refname:strip=2).


Mettre à jour Git 2.12 (T1 2017)

Voir commit c026557 , commit b178464 , commit 51acfa9 , commit b823166 , commit 109064a , commit 0c1b487 , commit 9ffda48 , commit eba286e (08 décembre 2016) par SZEDER Gábor (szeder) .
(Fusionné par Junio ​​C Hamano - gitster - in commit 1ac244d , 23 janvier 2017)

versionsort.prereleaseSuffix Est un alias obsolète pour versionsort.suffix.

La fonction prereleaseSuffix de la comparaison de version utilisée dans "git tag -l" Ne fonctionnait pas correctement lorsque deux ou plusieurs versions préliminaires pour la même version étaient présentes (par exemple lorsque 2.0, 2.0-beta1 Et 2.0-beta2 Sont là et le code doit comparer 2.0-beta1 Et 2.0-beta2).

73
VonC

Selon cela réponse , sur les plates-formes qui ne prennent pas en charge sort -V comme Windows et OSX, vous pouvez utiliser

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

12
Cédric

Combiner les réponses déjà ici:

Dépôt local

git -c 'versionsort.suffix=-' tag --list --sort=-v:refname
  • suffix=- empêchera 2.0-rc venant "après" 2.0
  • --sort=- mettra le numéro de version le plus élevé en haut.

Référentiel distant

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

L'avantage est qu'aucun objet n'est téléchargé depuis la télécommande.

Pour plus d'informations, voir cette réponse .

6
Tom Hale

Pour obtenir un tri inverse avec le sort -V approche:

git tag -l | sort -V --reverse
2
modle13

J'ai fini par écrire un simple script Shell pour simplifier cette tâche.

#!/usr/bin/env bash

TAGS=$(git tag)
CODE=$?

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

exit $CODE

Je l'ai enregistré sous git-tags dans mon $PATH et courir git tags chaque fois que je dois lister les tags.

1
Kevin Herrera

Adapt ce script Perl , qui trie les balises qui ressemblent à client_release/7.2/7.2.25, à votre schéma de marquage spécifique.

1
David Tonhofer