¿Cómo obtener el último nombre de etiqueta en la rama actual en Git?

463

¿Cuál es la forma más sencilla de obtener la etiqueta más reciente en Git?

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

salida:

a
b
c

¿Debo escribir un script para obtener la fecha y hora de cada etiqueta y compararlas?

culebrón
fuente
1
última etiqueta creada o última etiqueta ordenada por fecha de confirmación? Su respuesta aceptada muestra la última etiqueta creada. Esto podría ser un problema si uno decide alterar las etiquetas existentes ...
Paebbels

Respuestas:

412

Puedes echar un vistazo git describe, lo que hace algo parecido a lo que estás pidiendo.

JB
fuente
194
Con --abbrev=0él debería devolver la etiqueta anotada más cercana
Jakub Narębski
13
Devuelve la última etiqueta en la rama actual.
brittohalloran
42
Para obtener la última etiqueta anotada que se dirige solo a la confirmación actual en la rama actual , use git describe --exact-match --abbrev=0.
Naftuli Kay
55
Esta respuesta, con comentarios, no me proporcionó la etiqueta correcta. @kilianic proporcionó una solución correcta.
Herman J. Radtke III
21
git describe --tagsy comparar com última etiqueta en la página de lanzamiento de github
Adriano Resende
628

Para obtener la etiqueta más reciente:

git describe --tags

Para obtener la etiqueta anotada más reciente :

git describe --abbrev=0
acassis
fuente
2
Sí, como git describedice la página del manual : --abbrev=<n> [...] An <n> of 0 will suppress long format, only showing the closest tag.
Giorgos Kylafas
22
O simplementegit describe --tags
james_womack
55
Esta respuesta (y probablemente las otras) tiene problemas si tiene dos etiquetas que apuntan a la misma confirmación. A menos que las etiquetas sean etiquetas anotadas, creo que no hay forma de que git distinga cuál de las dos se creó anteriormente.
Paul Lynch
10
Esta debería ser la respuesta aceptada. Gracias por enviar
crmpicco
66
si desea git checkout $(git describe --abbrev=0 --tags)
verificar
321

Producirá la etiqueta del último commit etiquetado en todas las ramas

git describe --tags $(git rev-list --tags --max-count=1)
kilianc
fuente
8
o TAG=$(git describe --tags $(git rev-list --tags --max-count=1))@ william-pursell
kilianc
20
Esta es la mejor respuesta. En realidad, obtiene etiquetas en todas las ramas, no solo en la rama actual, como hace la respuesta "correcta" actual.
brittohalloran
61
Excepto que la pregunta específicamente pregunta por la rama actual.
michaeltwofish
3
@michaeltwofish, en el momento en que no lo sabía, lo descubrí más tarde y corregí en consecuencia mi respuesta. Lo siento por eso.
kilianc
3
Notas: Este comando devuelve la etiqueta "más reciente", incluso si esta etiqueta está en otra rama.
Alan Zhiliang Feng
47

Para obtener la etiqueta más reciente, puede hacer:

$ git para las referencias / etiquetas de cada referencia --sort = -taggerdate --format = '% (refname)' --count = 1

Por supuesto, puede cambiar el argumento de conteo o el campo de clasificación según lo desee. Parece que es posible que haya querido hacer una pregunta ligeramente diferente, pero esto responde la pregunta tal como la interpreto.

William Pursell
fuente
2
Esto es casi exactamente lo que estaba buscando (la etiqueta más reciente en todas las ramas), pero al menos con mi versión de git (1.7.7.6) las etiquetas se producen en el mismo orden para ambos --sort=-authordatey--sort=authordate .
larsks
3
Ajá, porque lo que realmente quieres es --sort=-taggerdate. Para las etiquetas, authordatey committerdateestán vacías (tan inútiles como las claves de clasificación).
lanza el
8
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1es aún mejor :)
Christophe Eblé
55
Realmente, ¿votando una respuesta perfectamente correcta que tiene casi 5 años sin un comentario? Eso es simplemente grosero.
William Pursell
1
Y --points-at=$SHAle dará la etiqueta para un hash de confirmación.
Ryan
35

¿Qué tal esto?

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

Técnicamente, no necesariamente obtendrá la última etiqueta, sino la última confirmación que está etiquetada, que puede o no ser lo que está buscando.

Wincent Colaiuta
fuente
Este no recibe la última etiqueta en la rama actual sino para cualquier rama. Lo cual es genial, porque es exactamente lo que necesitaba. Gracias Wincent
jasongregori
2
Si usted necesita para obtener el patrón correspondiente etiqueta se puede utilizar --tags=<pattern>en rev-list. Por ejemplo, obtenga la última etiqueta de versióngit 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
Gracias, funcionó, pero tuve que agregar --tags git describe --tags $(git rev-list --tags --max-count=1)
Gianluca Casati
25

Puede ejecutar: git describe --tags $(git rev-list --tags --max-count=1)hablado aquí: ¿Cómo obtener el último nombre de etiqueta?

xserrat
fuente
Comencé con la respuesta superior / aceptada y trabajé hacia abajo. Esta es la primera respuesta que realmente me da la última etiqueta (¡¿no estoy seguro de por qué, pero el viejo git describe ...devuelve una etiqueta anterior ?!)
Jeremy Davis el
Este es el único que funciona para mí. Intenté algunas de las --abbrev=0respuestas y cortaron parte de la etiqueta que quiero.
Luke Davis el
22

"Más reciente" podría tener dos significados en términos de git.

Podría decir, "qué etiqueta tiene la fecha de creación más reciente en el tiempo", y la mayoría de las respuestas aquí son para esa pregunta. En términos de su pregunta, le gustaría devolver la etiqueta c.

O podría decir "qué etiqueta es la más cercana en el historial de desarrollo a alguna rama con nombre", generalmente la rama en la que se encuentra, HEAD . En su pregunta, esto devolvería la etiqueta a.

Estos pueden ser diferentes, por supuesto:

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

Imagine que el desarrollador etiquetó Zcomo v0.2el lunes y luego etiquetó Qcomo v0.1el martes. v0.1es el más reciente, pero v0.2está más cerca en la historia del desarrollo de HEAD, en el sentido de que el camino en el que se inicia comienza en un punto más cercano a HEAD.

Creo que generalmente quieres esta segunda respuesta, más cerca en la historia del desarrollo. Puede averiguarlo utilizando git log v0.2..HEADetc. para cada etiqueta. Esto le da el número de confirmaciones en HEAD desde que la ruta termina env0.2 divergió de la ruta seguida por HEAD.

Aquí hay un script de Python que lo hace iterando a través de todas las etiquetas que ejecutan esta verificación y luego imprimiendo la etiqueta con la menor cantidad de confirmaciones en HEAD ya que la ruta de la etiqueta divergió:

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

git describehace algo ligeramente diferente, en el sentido de que rastrea desde (por ejemplo) HEAD para encontrar la primera etiqueta que está en un camino hacia atrás en el historial desde HEAD. En términos de git, git describebusca etiquetas que sean "accesibles" desde HEAD. Por lo tanto, no encontrará etiquetas como v0.2esa que no estén en el camino de regreso de HEAD, sino en un camino que se separó de allí.

Matthew Brett
fuente
21

git describe --tags

devuelve la última etiqueta que puede ver la rama actual

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

SI NECESITA MÁS DE UNA ÚLTIMA ETIQUETA

(git describe --tags a veces da hashes incorrectos, no sé por qué, pero para mí --max-count 2 no funciona)

así es como puede obtener la lista con los últimos 2 nombres de etiquetas en orden cronológico inverso, funciona perfectamente en git 1.8.4. Para versiones anteriores de git (como 1.7. *), No hay una cadena "tag:" en la salida: simplemente elimine la última llamada sed

Si desea más de 2 últimas etiquetas, cambie este "sed 2q" a "sed 5q" o lo que necesite

Luego puede analizar fácilmente cada nombre de etiqueta a variable más o menos.

este
fuente
Esto es realmente útil, muchos desarrolladores intentarán automatizar el proceso de lanzamiento retrocediendo a la etiqueta anterior si se rompe la implementación. ¡¡¡Cosas geniales!!!
AkD
1
Para llevar esto más lejos: git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p' donde en %Dexcluye los ()caracteres que lo rodean , y el seds que comienza 5q deja 4 líneas antes de 5, luego imprime todos los caracteres entre 'tag: `y el primero', '. Entonces ... suponiendo que no se usen comas dentro de la etiqueta, esto funciona perfectamente.
Cometsong
14

¿Qué hay de malo con todas las sugerencias (excepto la explicación de Matthew Brett , actualizada de esta publicación de respuestas)?

Simplemente ejecute cualquier comando proporcionado por otro en el historial de jQuery Git cuando esté en un punto diferente del historial y verifique el resultado con la representación visual del historial de etiquetado (lo hice por eso es que ve esta publicación):

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

Hoy en día, muchos proyectos realizan lanzamientos (y, por lo tanto, etiquetado) en una rama separada de la línea principal .

Hay una fuerte razón para esto. Simplemente busque cualquier proyecto JS / CSS bien establecido. Para convenciones de usuarios, llevan archivos de lanzamiento binarios / minificados en DVCS. Naturalmente, como mantenedor del proyecto, no desea desechar su historial de diferencias de la línea principal con blobs binarios inútiles y realizar la confirmación de los artefactos de compilación fuera de la línea principal .

Debido a que Git usa DAG y no un historial lineal, es difícil definir la métrica de distancia, por lo que podemos decir: oh, esa revolución es la más cercana aHEAD !

Comienzo mi propio viaje en (mira adentro, no copié imágenes de prueba elegantes en esta larga publicación):

¿Cuál es la etiqueta más cercana en el pasado con respecto a la ramificación en Git?

Actualmente tengo 4 definiciones razonables de distancia entre etiqueta y revisión con disminución de utilidad:

  • longitud del camino más corto desde HEADa base de fusión con la etiqueta
  • fecha de combinación de base entre HEADy etiqueta
  • Número de revoluciones a las que se puede acceder desde HEAD pero no se puede acceder desde la etiqueta
  • fecha de etiqueta independientemente de la base de fusión

No sé cómo calcular la longitud del camino más corto .

Script que ordena las etiquetas según fecha de la base de fusión entre HEADy la etiqueta:

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

Se puede usar en la mayoría de los proyectos.

Script que clasifica las etiquetas de acuerdo con el número de revoluciones a las que se puede acceder desde HEAD pero no se puede acceder desde la etiqueta:

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

Si el historial de su proyecto tiene fechas extrañas en las confirmaciones (debido a rebases u otra reescritura del historial o algún imbécil se olvida de reemplazar la batería del BIOS u otras magias que hace en el historial) use el script anterior.

Para la última opción ( fecha de etiqueta independientemente base de fusión ) para obtener una lista de etiquetas ordenadas por uso de fecha:

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

Para conocer la fecha de revisión actual, use:

$ git log --max-count=1

Tenga en cuenta que git describe --tagstiene uso en sus propios casos, pero no para encontrar la etiqueta humana más cercana esperada en el historial del proyecto .

NOTA Puede usar las recetas anteriores en cualquier revisión, ¡simplemente reemplace HEADcon lo que quiera!

gavenkoa
fuente
12

git describe --abbrev=0 --tags

Si no ve la última etiqueta, asegúrese de buscar el origen antes de ejecutar eso:

git remote update

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

Obtenga la última etiqueta con el prefijo "ac" . Por ejemplo, etiqueta nombrada con ac1.0.0o ac1.0.5. Otras etiquetas con nombre 1.0.0, 1.1.0serán ignorados.

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

Obtenga la última etiqueta, cuyo primer carácter es 0-9. Entonces, esas etiquetas con el primer carácter a-zserán ignoradas.

Más información

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

git tag -l <pattern>

Enumere etiquetas con nombres que coincidan con el patrón dado (o todos si no se da ningún patrón). Ejecutar "git tag" sin argumentos también enumera todas las etiquetas. El patrón es un comodín de shell (es decir, emparejado usando fnmatch (3)). Se pueden dar múltiples patrones; Si alguno de ellos coincide, se muestra la etiqueta.


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

Actualizar

Con git tag --help, sobre el sortargumento. Se usará lexicorgraphic orderpor defecto, si la tag.sortpropiedad no existe.

El orden de clasificación predeterminado es el valor configurado para la variable tag.sort si existe, o el orden lexicográfico de lo contrario. Ver git-config (1).

Después de google, alguien dijo que el soporte de git 2.8.0 seguía la sintaxis.

git tag --sort=committerdate
AechoLiu
fuente
no es wok para mí, la última etiqueta es 2.11.174, pero esta impresión porque 11/02/99 especie no como en versiones
Ali.MD
8
git tag --sort=committerdate | tail -1
usuario2957741
fuente
Explique cómo este fragmento de código resolverá el problema, en lugar de publicar una respuesta de solo código.
Arun Vinoth
5

Lo siguiente funciona para mí en caso de que necesite las últimas dos etiquetas (por ejemplo, para generar un registro de cambios entre la etiqueta actual y la etiqueta anterior). Lo probé solo en situaciones donde la última etiqueta fue 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_"`

Se adapta a mis necesidades, pero como no soy un mago git, estoy seguro de que podría mejorarse aún más. También sospecho que se romperá en caso de que el historial de confirmación avance. Solo estoy compartiendo en caso de que ayude a alguien.

Ivan Vučica
fuente
4

Mi primer pensamiento es que podría usar git rev-list HEAD, que enumera todas las revoluciones en orden cronológico inverso, en combinación con git tag --contains. Cuando encuentra una referencia donde git tag --containsproduce una lista no vacía, ha encontrado las etiquetas más recientes.

Greg Hewgill
fuente
4

Si desea encontrar la última etiqueta que se aplicó en una rama específica, puede intentar lo siguiente:

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

Si necesita un revestimiento único que obtenga el último nombre de etiqueta (por fecha de etiqueta) en la rama actual :

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

Usamos esto para establecer el número de versión en la configuración.

Ejemplo de salida:

v1.0.0

Funciona también en Windows.

Markus
fuente
1
En Linux (Debian Stretch) me sale-bash: syntax error near unexpected token '('
Jeremy Davis
1
Si envuelvo esa parte entre comillas (es decir --format="%(refname:short)") y omito --points-at=HEAD, funciona. Con ese último interruptor, no devuelve nada, supongo porque mi HEADno está etiquetado.
Jeremy Davis, el
@JeremyDavis, sí, creo que es porque tu HEADno está etiquetado.
Markus
2

Este es un hilo viejo, pero parece que a muchas personas les falta la respuesta más simple, fácil y correcta a la pregunta de OP: para obtener la última etiqueta para la rama actual , usagit describe HEAD . Hecho.

Editar: también puede proporcionar cualquier nombre de referencia válido, incluso controles remotos; es decir, git describe origin/masterle indicará la última etiqueta a la que se puede acceder desde origen / maestro.

dohpaz42
fuente
Nada garantiza que "la etiqueta más reciente" sea manejada por ninguna sucursal. Las dos soluciones de trabajo son el for-each-refcomando ( stackoverflow.com/a/5261470/515973 ) y la combinación derev-list y describe( stackoverflow.com/a/7979255/515973 )
Julien Carsique
1
Esta no es la etiqueta más reciente para mí.
K - La toxicidad en SO está creciendo.
git describe branchname --tagsfunciona para mí obtener la última etiqueta en la rama (git versión 2.12.2)
Rob_M
0

Para obtener la última etiqueta solo en el nombre de la rama / etiqueta actual que tiene prefijos con la rama actual, tuve que ejecutar lo siguiente

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

Maestro de rama:

git checkout master

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

master-1448

Rama personalizada:

git checkout 9.4

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

9.4-6

Y mi necesidad final de incrementar y obtener la etiqueta +1 para el próximo etiquetado.

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

Para la pregunta que se le hizo,

Cómo obtener el último nombre de etiqueta en la rama actual

usted quiere

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

--first-parentle dice que git logno detalle ninguna historia fusionada, le --pretty=%ddice que muestre solo las decoraciones, es decir, los nombres locales para cualquier confirmación. grep -m1dice "coincide solo con uno", por lo que obtienes la etiqueta más reciente.

jthill
fuente
0

Si sus etiquetas son ordenables:

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

No hay mucha mención de etiquetas no anotadas versus etiquetas anotadas aquí. 'describe' funciona en etiquetas anotadas e ignora las no anotadas.

Esto es feo pero cumple con el trabajo solicitado y no encontrará ninguna etiqueta en otras ramas (y no en la especificada en el comando: master en el ejemplo a continuación)

El filtrado debería ser optimizado (consolidado), pero nuevamente, esto parece ser el trabajo.

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

Las críticas son bienvenidas ya que voy a poner esto en uso :)

Rondó
fuente
-2

Otra forma sencilla de obtener el último nombre de etiqueta es con

git tag | tail -1

o

TAG=$(git tag | tail -1)

para almacenarlo en una variable.

git tagenumera todas las etiquetas disponibles y devolverá la última fila si el resultado.tail-1

Xaver
fuente
44
Sin clasificar, este es un mal movimiento.
mjd2