Comment obtenir le dernier nom de tag dans la branche actuelle de Git?

463

Quelle est la manière la plus simple d'obtenir la balise la plus récente dans Git?

git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag

production:

a
b
c

Dois-je écrire un script pour obtenir la date et l'heure de chaque balise et les comparer?

culebrón
la source
1
dernière balise créée ou dernière balise classée par date de validation? Votre réponse acceptée affiche la dernière balise créée. Cela pourrait être un problème si l'on décide de modifier les balises existantes ...
Paebbels

Réponses:

412

Vous pouvez jeter un œil à git describece qui correspond à ce que vous demandez.

JB.
la source
194
Avec --abbrev=0elle devrait retourner la balise annotée la plus proche
Jakub Narębski
13
Renvoie la dernière balise de la branche actuelle.
brittohalloran
42
Pour obtenir la dernière balise annotée qui cible uniquement la validation actuelle dans la branche actuelle , utilisez git describe --exact-match --abbrev=0.
Naftuli Kay
5
Cette réponse, avec des commentaires, ne m'a pas fourni la bonne balise. @kilianic a fourni une solution correcte.
Herman J. Radtke III
21
git describe --tagset comparer la dernière balise com dans la page de sortie de github
Adriano Resende
628

Pour obtenir la balise la plus récente:

git describe --tags

Pour obtenir la balise annotée la plus récente :

git describe --abbrev=0
acassis
la source
2
Oui, comme le dit la page de manuel git describe: --abbrev=<n> [...] An <n> of 0 will suppress long format, only showing the closest tag.
Giorgos Kylafas
22
Ou tout simplementgit describe --tags
james_womack
5
Cette réponse (et probablement les autres) rencontre des problèmes si vous avez deux balises pointant vers le même commit. À moins que les balises soient des balises annotées, je pense qu'il n'y a aucun moyen pour git de distinguer lequel des deux a été créé plus tôt.
Paul Lynch
10
Ce devrait être la réponse acceptée. Merci de nous avoir soumis.
crmpicco
6
si vous souhaitez git checkout $(git describe --abbrev=0 --tags)
retirer
322

Affichera la balise du dernier commit balisé dans toutes les branches

git describe --tags $(git rev-list --tags --max-count=1)
kilianc
la source
8
ou TAG=$(git describe --tags $(git rev-list --tags --max-count=1))@ william-pursell
kilianc
20
C'est la meilleure réponse. Il obtient en fait des balises dans toutes les branches, pas seulement la branche actuelle, comme le fait la réponse "correcte" actuelle.
brittohalloran
61
Sauf que la question demande spécifiquement la branche actuelle.
michaeltwofish
3
@michaeltwofish, au moment où je ne le savais pas, je l'ai compris plus tard et corrigé en conséquence ma réponse. Désolé pour ça.
kilianc
3
Remarques: Cette commande renvoie la balise "la plus récente" même si cette balise se trouve sur une autre branche.
Alan Zhiliang Feng
47

Pour obtenir la balise la plus récente, vous pouvez faire:

$ git pour chaque référence refs / tags --sort = -taggerdate --format = '% (refname)' --count = 1

Bien sûr, vous pouvez modifier l'argument count ou le champ de tri comme vous le souhaitez. Il semble que vous vouliez peut-être poser une question légèrement différente, mais cela répond à la question telle que je l'interprète.

William Pursell
la source
2
C'est presque exactement ce que je cherchais (la balise la plus récente dans toutes les branches), mais au moins avec ma version de git (1.7.7.6), les balises sont produites dans le même ordre pour les deux --sort=-authordateet --sort=authordate.
larsks
3
Aha, parce que ce que tu veux vraiment, c'est --sort=-taggerdate. Pour les balises, authordateet committerdatesont vides (donc inutiles comme clés de tri).
larsks
8
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1c'est encore mieux :)
Christophe Eblé
5
Vraiment, downvoting une réponse parfaitement correcte qui a près de 5 ans sans commentaire? C'est juste désagréable.
William Pursell
1
Et --points-at=$SHAvous donnera la balise pour un hachage de validation.
Ryan
35

Que dis-tu de ça?

TAG=$(git describe $(git rev-list --tags --max-count=1))

Techniquement, vous n'obtiendrez pas nécessairement la dernière balise, mais la dernière validation qui est balisée, qui peut ou non être la chose que vous recherchez.

Wincent Colaiuta
la source
Celui-ci n'obtient pas la dernière balise de la branche actuelle mais pour toutes les branches. Ce qui est génial, car c'est exactement ce dont j'avais besoin. Merci Wincent.
jasongregori
2
Si vous avez besoin d'obtenir un modèle de correspondance de balises, vous pouvez l'utiliser --tags=<pattern>dans rev-list. Par exemple, obtenez la dernière balise de versiongit describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)
Wirone
1
$ (git describe --contains $ (git rev-parse HEAD))
Vaidas Zilionis
Merci, cela a fonctionné, mais j'ai dû ajouter --tags git describe --tags $(git rev-list --tags --max-count=1)
Gianluca Casati
25

Vous pouvez exécuter: git describe --tags $(git rev-list --tags --max-count=1)parlé ici: Comment obtenir le dernier nom de tag?

xserrat
la source
J'ai commencé avec la réponse la plus élevée / acceptée et j'ai descendu. C'est la première réponse qui me donne en fait le dernier tag (je ne sais pas pourquoi mais plain old git describe ...renvoie un tag plus tôt?!)
Jeremy Davis
C'est le seul qui fonctionne pour moi. --abbrev=0J'ai essayé certaines des réponses et ils ont coupé une partie de la balise que je voulais.
Luke Davis
22

"Le plus récent" pourrait avoir deux significations en termes de git.

Vous pourriez vouloir dire "quelle balise a la date de création la plus récente", et la plupart des réponses ici sont pour cette question. En ce qui concerne votre question, vous voudriez renvoyer la balise c.

Ou vous pourriez dire « quelle balise est le plus proche dans l' histoire du développement à une branche nommée », généralement la branche que vous êtes, HEAD. Dans votre question, cela retournerait une balise a.

Celles-ci pourraient bien sûr être différentes:

A->B->C->D->E->F (HEAD)
       \     \
        \     X->Y->Z (v0.2)
         P->Q (v0.1)

Imaginez le développeur tag'ed Zcomme v0.2le lundi, puis tag'ed Qcomme v0.1le mardi. v0.1est la plus récente, mais elle v0.2est plus proche dans l'histoire du développement de HEAD, en ce sens que le chemin sur lequel elle se trouve commence à un point plus proche de HEAD.

Je pense que vous voulez généralement cette deuxième réponse, plus proche dans l'histoire du développement. Vous pouvez le découvrir en utilisant git log v0.2..HEADetc pour chaque balise. Cela vous donne le nombre de validations sur HEAD depuis le chemin se terminant à v0.2divergé du chemin suivi par HEAD.

Voici un script Python qui fait cela en parcourant toutes les balises exécutant cette vérification, puis en imprimant la balise avec le moins de validations sur HEAD depuis que le chemin de balise a divergé:

https://github.com/MacPython/terryfy/blob/master/git-closest-tag

git describefait quelque chose de légèrement différent, en ce sens qu'il revient (par exemple) à HEAD pour trouver la première balise qui se trouve sur un chemin de retour à partir de HEAD. En termes git, git describerecherche les balises "accessibles" depuis HEAD. Il ne trouvera donc pas de telles balises v0.2qui ne sont pas sur le chemin du retour de HEAD, mais un chemin qui en a divergé.

Matthew Brett
la source
21

git describe --tags

retourne la dernière balise visible par la branche courante

behere4hours
la source
15
git log --tags --no-walk --pretty="format:%d" | sed 2q | sed 's/[()]//g' | sed s/,[^,]*$// | sed  's ......  '

SI VOUS AVEZ BESOIN DE PLUS D'UN DERNIER ÉTIQUETTE

(git décrit --tags donne parfois des hachages incorrects, je ne sais pas pourquoi, mais pour moi --max-count 2 ne fonctionne pas)

c'est ainsi que vous pouvez obtenir une liste avec les 2 derniers noms de balises dans l'ordre chronologique inverse, fonctionne parfaitement sur git 1.8.4. Pour les versions antérieures de git (comme 1.7. *), Il n'y a pas de chaîne "tag:" en sortie - supprimez simplement le dernier appel sed

Si vous voulez plus de 2 dernières balises - changez ce "sed 2q" en "sed 5q" ou tout ce dont vous avez besoin

Ensuite, vous pouvez facilement analyser chaque nom de balise en variable.

est
la source
ceci est vraiment utile, de nombreux développeurs essaieront d'automatiser le processus de publication en revenant à la balise précédente en cas de rupture du déploiement. Des trucs géniaux !!!
AkD
1
Pour aller plus loin: git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p' où in %Dexclut les ()caractères environnants , et le sed5q de départ s laisse 4 lignes avant 5, puis imprime tous les caractères entre 'tag: `et le premier', '. Donc ... en supposant qu'aucune virgule ne soit utilisée à l'intérieur de la balise, cela fonctionne parfaitement.
Cometsong
14

Quel est le problème avec toutes les suggestions (sauf l' explication de Matthew Brett , à jour de ce message de réponse)?

Il suffit d'exécuter n'importe quelle commande fournie par d'autres sur l'historique jQuery Git lorsque vous êtes à un point différent de l'historique et de vérifier le résultat avec une représentation historique de l'étiquetage visuel (je l'ai fait, c'est pourquoi vous voyez ce post):

$ git log --graph --all --decorate --oneline --simplify-by-decoration

Aujourd'hui, de nombreux projets effectuent des versions (et donc du balisage) dans une branche distincte de la ligne principale .

Il y a une bonne raison à cela. Regardez simplement tous les projets JS / CSS bien établis. Pour les conventions utilisateur, ils portent des fichiers de version binaires / minifiés dans DVCS. Naturellement, en tant que responsable de projet, vous ne voulez pas gâcher votre historique de différences de ligne principale avec des objets binaires inutiles et effectuer la validation des artefacts de génération en dehors de la ligne principale .

Parce que Git utilise DAG et non un historique linéaire - il est difficile de définir la métrique de distance afin que nous puissions dire - oh ce régime est le plus proche de mon HEAD!

Je commence mon propre voyage en (regardez à l'intérieur, je n'ai pas copié d'images à l'épreuve de fantaisie dans ce long post):

Quelle est la balise la plus proche dans le passé en ce qui concerne la ramification dans Git?

Actuellement, j'ai 4 définitions raisonnables de la distance entre le tag et la révision avec une diminution de l'utilité:

  • longueur du chemin le plus court à partir HEADde la base de fusion avec étiquette
  • date de fusion de la base entre HEADet tag
  • nombre de tours atteignables depuis HEAD mais pas accessibles depuis la balise
  • date du tag quelle que soit la base de fusion

Je ne sais pas comment calculer la longueur du chemin le plus court .

Script qui trie les balises en fonction de la date de la base de fusion entre HEADet balise:

$ git tag \
     | while read t; do \
         b=`git merge-base HEAD $t`; \
         echo `git log -n 1 $b --format=%ai` $t; \
       done | sort

Il est utilisable sur la plupart des projets.

Script qui trie les balises en fonction du nombre de tours accessibles depuis HEAD mais pas accessible depuis la balise:

$ git tag \
    | while read t; do echo `git rev-list --count $t..HEAD` $t; done \
    | sort -n

Si l'historique de votre projet a des dates de validation étranges (en raison de rebases ou d'une autre réécriture de l'histoire ou d'un crétin oubliez de remplacer la batterie du BIOS ou d'autres magies que vous faites sur l'historique), utilisez le script ci-dessus.

Pour la dernière option ( date de balise indépendamment de la base de fusion ) pour obtenir la liste des balises triées par date, utilisez:

$ git log --tags --simplify-by-decoration --pretty="format:%ci %d" | sort -r

Pour obtenir la date de révision actuelle connue, utilisez:

$ git log --max-count=1

Notez qu'ils git describe --tagsont une utilisation dans leurs propres cas, mais pas pour trouver la balise la plus proche attendue humaine dans l'historique du projet .

REMARQUE Vous pouvez utiliser les recettes ci-dessus sur n'importe quelle révision, remplacez-les simplement HEADpar ce que vous voulez!

gavenkoa
la source
12

git describe --abbrev=0 --tags

Si vous ne voyez pas la dernière balise, assurez-vous de récupérer l'origine avant de l'exécuter:

git remote update

Walter B
la source
12
git tag -l ac* | tail -n1

Obtenez la dernière balise avec le préfixe "ac" . Par exemple, balise nommée avec ac1.0.0, ou ac1.0.5. Autres tags nommés 1.0.0, 1.1.0seront ignorés.

git tag -l [0-9].* | tail -n1

Obtenez la dernière balise, dont le premier caractère est 0-9. Ainsi, ces balises avec le premier caractère a-zseront ignorées.

Plus d'informations

git tag --help # Help for `git tag`

git tag -l <pattern>

Liste des balises avec des noms qui correspondent au modèle donné (ou tous si aucun modèle n'est donné). L'exécution de "git tag" sans arguments répertorie également toutes les balises. Le modèle est un caractère générique du shell (c'est-à-dire, apparié à l'aide de fnmatch (3)). Plusieurs modèles peuvent être donnés; si l'un d'eux correspond, la balise est affichée.


tail -n <number> # display the last part of a file
tail -n1 # Display the last item 

Mise à jour

Avec git tag --help, sur l' sortargument. Il utilisera lexicorgraphic orderpar défaut, si la tag.sortpropriété n'existe pas.

L'ordre de tri par défaut est la valeur configurée pour la variable tag.sort si elle existe, ou l'ordre lexicographique sinon. Voir git-config (1).

Après google, quelqu'un a dit que git 2.8.0 supporte la syntaxe suivante.

git tag --sort=committerdate
AechoLiu
la source
ce n'est pas un wok pour moi, la dernière balise est le 2.11.174 mais cette impression 2.11.99 parce que le tri n'est pas en tant que versioning
Ali.MD
8
git tag --sort=committerdate | tail -1
user2957741
la source
Veuillez expliquer comment cet extrait de code résoudra le problème, au lieu de publier une réponse uniquement en code.
Arun Vinoth
5

Ce qui suit fonctionne pour moi si vous avez besoin des deux dernières balises (par exemple, afin de générer un journal des modifications entre la balise actuelle et la balise précédente). Je ne l'ai testé que dans le cas où le dernier tag était le HEAD.

PreviousAndCurrentGitTag=`git describe --tags \`git rev-list --tags --abbrev=0 --max-count=2\` --abbrev=0`
PreviousGitTag=`echo $PreviousAndCurrentGitTag | cut -f 2 -d ' '`
CurrentGitTag=`echo $PreviousAndCurrentGitTag | cut -f 1 -d ' '`

GitLog=`git log ${PreviousGitTag}..${CurrentGitTag} --pretty=oneline | sed "s_.\{41\}\(.*\)_; \1_"`

Cela convient à mes besoins, mais comme je ne suis pas un sorcier, je suis sûr qu'il pourrait être encore amélioré. Je soupçonne également qu'il se cassera au cas où l'historique des validations irait de l'avant. Je partage juste au cas où cela aiderait quelqu'un.

Ivan Vučica
la source
4

Ma première pensée est que vous pourriez utiliser git rev-list HEAD, qui répertorie toutes les révolutions dans l'ordre chronologique inverse, en combinaison avec git tag --contains. Lorsque vous trouvez une référence où git tag --containsproduit une liste non vide, vous avez trouvé les balises les plus récentes.

Greg Hewgill
la source
4

Si vous souhaitez rechercher la dernière balise appliquée sur une branche spécifique, vous pouvez essayer ce qui suit:

git describe --tag $(git rev-parse --verify refs/remotes/origin/"branch_name")
Scyssion
la source
3

Si vous avez besoin d'un liner qui obtient le dernier nom de tag (par date de tag) sur la branche actuelle :

git for-each-ref refs/tags --sort=-taggerdate --format=%(refname:short) --count=1 --points-at=HEAD

Nous l'utilisons pour définir le numéro de version dans la configuration.

Exemple de sortie:

v1.0.0

Fonctionne également sur Windows.

Markus
la source
1
Sous Linux (Debian Stretch), je reçois-bash: syntax error near unexpected token '('
Jeremy Davis
1
Si j'enveloppe cette partie entre guillemets (c.-à-d. --format="%(refname:short)") Et que --points-at=HEADje saute, cela fonctionne. Avec ce dernier interrupteur, il ne renvoie rien, je suppose que mon HEADn'est pas étiqueté?
Jeremy Davis
@JeremyDavis, oui je pense que c'est parce que vous n'êtes HEADpas tagué.
Markus
2

C'est un vieux fil, mais il semble que beaucoup de gens manquent la réponse la plus simple, la plus simple et la plus correcte à la question d'OP: pour obtenir la dernière balise de la branche actuelle , vous utilisez git describe HEAD. Terminé.

Modifier: vous pouvez également fournir n'importe quel nom de référence valide, même des télécommandes; c'est-à git describe origin/master-dire, vous indiquera la dernière balise qui peut être atteinte à partir de l'origine / master.

dohpaz42
la source
Rien ne garantit que "la balise la plus récente" est gérée par n'importe quelle branche. Les deux solutions de travail sont la for-each-refcommande ( stackoverflow.com/a/5261470/515973 ) et la combinaison de rev-listet describe( stackoverflow.com/a/7979255/515973 )
Julien Carsique
1
Cela ne me permet pas d'obtenir la balise la plus récente.
K - La toxicité du SO augmente.
git describe branchname --tagsfonctionne pour moi pour obtenir la dernière balise sur la branche (git version 2.12.2)
Rob_M
0

Pour obtenir la dernière balise uniquement sur la branche actuelle / le nom de la balise qui préfixe la branche actuelle, j'ai dû exécuter ce qui suit

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH

Maître de succursale:

git checkout master

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags 
--abbrev=0 $BRANCH^ | grep $BRANCH

master-1448

Branche personnalisée:

git checkout 9.4

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags 
--abbrev=0 $BRANCH^ | grep $BRANCH

9.4-6

Et mon dernier besoin d'augmenter et d'obtenir le tag +1 pour le prochain tag.

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags  --abbrev=0 $BRANCH^ | grep $BRANCH | awk -F- '{print $NF}'
Sankarganesh Eswaran
la source
0

Pour la question posée,

Comment obtenir le dernier nom de balise dans la branche actuelle

tu veux

git log --first-parent --pretty=%d | grep -m1 tag:

--first-parentindique de git logne pas détailler les histoires fusionnées, --pretty=%ddit de ne montrer que les décorations, c'est-à-dire les noms locaux pour les commits. grep -m1dit "correspondre à un seul", vous obtenez donc la balise la plus récente.

jthill
la source
0

si vos tags sont triables:

git tag --merged $YOUR_BRANCH_NAME | grep "prefix/" | sort | tail -n 1
Clintm
la source
0

Pas beaucoup de mention des balises non annotées par rapport aux balises annotées ici. «décrire» fonctionne sur les balises annotées et ignore celles qui ne le sont pas.

C'est moche mais fait le travail demandé et il ne trouvera aucune balise sur les autres branches (et pas sur celle spécifiée dans la commande: master dans l'exemple ci-dessous)

Le filtrage devrait probablement être optimisé (consolidé), mais encore une fois, cela semble faire l'affaire.

git log  --decorate --tags master |grep '^commit'|grep 'tag:.*)$'|awk '{print $NF}'|sed 's/)$//'|head -n 1

Les critiques sont les bienvenues car je vais maintenant mettre cela à profit :)

Rondo
la source
-2

Un autre moyen simple d'obtenir le dernier nom de balise est de

git tag | tail -1

ou

TAG=$(git tag | tail -1)

pour le stocker dans une variable.

git tagrépertorie toutes les balises disponibles et renverra la toute dernière ligne si le résultat.tail-1

Xaver
la source
4
Sans tri, c'est une mauvaise décision.
mjd2