usar tipos tener tag sirve repositorio qué proyecto podemos partir para otro oneline nuevo nuestros nos mayor log herramienta hacer hace existen etiquetas cuando crear creamos control git bash shell

tipos - ¿qué hace git log-oneline?



Cómo determinar mediante programación si el proceso de pago de Git es una etiqueta y, de ser así, cuál es el nombre de la etiqueta (6)

En un entorno de scripting Unix o GNU (por ejemplo, una distribución Linux, Cygwin, OSX), ¿cuál es la mejor manera de determinar si el pago actual es una etiqueta Git? Si es una etiqueta, ¿cómo puedo determinar el nombre de la etiqueta?

Un uso de esta técnica sería etiquetar automáticamente un lanzamiento (como svnversion haría con Subversion).

Vea mi pregunta relacionada sobre detectar programáticamente la rama de Git .


Aquí hay un breve script de shell (probado en Bash, no confirmado si funciona en cenizas, etc.). Establecerá la variable git_tag con el nombre de la etiqueta actualmente desprotegida, o la dejará en blanco si la extracción no está etiquetada.

git_tag='''' this_commit=`git log --pretty=format:%H%n HEAD^..` for tag in `git tag -l`; do tag_commit=`git log --pretty=format:%H%n tags/$tag^..tags/$tag` if [ "$this_commit" = "$tag_commit" ]; then # This is a tagged commit, so use the tag. git_tag="$tag" fi done

Comentario de Jakub Narębski :

Esta solución reduce el bucle sobre todas las etiquetas y comprueba si apuntan a la confirmación corrent, es decir, al objeto señalado por HEAD. Usando comandos de plomería, es decir, comandos para scripting, esto se puede escribir como:

this_commit=$(git rev-parse --verify HEAD) git for-each-ref --format="%(*objectname) %(refname:short)" refs/tags/ | while read tagged_object tagname do if test "$this_commit" = "$tagged_object" then echo $tagname fi done

Esto imprimiría todas las etiquetas que apuntan a la confirmación actual.


La mejor forma de hacerlo es usar el comando git describe :

git-describe - Muestra la etiqueta más reciente a la que se puede acceder desde una confirmación

El comando encuentra la etiqueta más reciente a la que se puede acceder desde una confirmación. Si la etiqueta apunta a la confirmación, solo se muestra la etiqueta. De lo contrario, incluye el nombre de la etiqueta con el número de confirmaciones adicionales en la parte superior del objeto etiquetado y el nombre abreviado del objeto de la confirmación más reciente.


Una mejor solución (de la respuesta de Greg Hewgill en la otra pregunta) sería:

git name-rev --name-only --tags HEAD

Si devuelve "indefinido", entonces no está en una etiqueta. De lo contrario, devuelve el nombre de la etiqueta. Entonces, un proyecto de una línea para hacer algo como mi otra respuesta sería:

git_tag=`git name-rev --name-only --tags HEAD | sed ''s/^undefined$//''`

Ejemplo interactivo de shell de cómo funciona:

$ git checkout master Already on "master" $ git name-rev --name-only --tags HEAD undefined $ git checkout some-tag Note: moving to "some-tag" which isnt a local branch If you want to create a new branch from this checkout, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new_branch_name> HEAD is now at 1234567... Some comment blah blah $ git name-rev --name-only --tags HEAD some-tag


La solución a su pregunta es usar

git describe --exact-match HEAD

(que consideraría solo las etiquetas anotadas , pero debe usar etiquetas anotadas y probablemente incluso firmadas para las versiones de etiquetado).

Si desea considerar todas las etiquetas, también ligeras (que generalmente se usan para el etiquetado local), puede usar la opción --tags :

git describe --exact-match --tags HEAD

Pero creo que tiene un " problema XY " aquí, en el sentido de que está haciendo una pregunta sobre la posible solución al problema, en lugar de hacer una pregunta sobre un problema ... que puede tener una mejor solución.

La solución a su problema es ver cómo Git lo hace en el script GIT-VERSION-GEN , y cómo lo usa en su Makefile .


El uso de git-name-rev es preferible para las secuencias de comandos, ya que es parte de git fontanería , mientras que git-describe es parte de la porcelana .

Utilice este comando para imprimir el nombre de la etiqueta si HEAD apunta a uno, de lo contrario, nada.

git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null | sed -n ''s/^/([^^~]/{1,/}/)/(/^0/)/{0,1/}$//1/p''

Tenga en cuenta la redirección de stderr a / dev / null; de lo contrario, aparecerá un mensaje de error que dice:

fatal: cannot describe ''SOMESHA''"

EDITAR: Se corrigió la expresión regular en sed para admitir etiquetas ligeras y anotadas / firmadas.


No puede determinar si el pago actual "es una etiqueta". Solo puede determinar si el pago actual fue un compromiso que tiene etiquetas.

La diferencia es: si hay varias etiquetas que señalan este compromiso , git no puede decirle cuál usó para pagar, ni si realmente usó uno para llegar allí.

La respuesta de Jakub aquí basada en git describe --exact-match (--tags) te da "la primera" de todas las etiquetas (anotadas).

Y git describe ordena así:

  • etiquetas anotadas primero
    • clasificado primero el más joven
  • etiquetas livianas vienen después
    • binario ordenado por nombre de etiqueta (que significa alfabéticamente si está codificado en inglés en ASCII)
    • git no almacena metadatos con etiquetas livianas, por lo que no se puede realizar el "más joven primero"