¿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?
¿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?
Respuestas:
Puedes echar un vistazo git describe
, lo que hace algo parecido a lo que estás pidiendo.
--abbrev=0
él debería devolver la etiqueta anotada más cercana
git describe --exact-match --abbrev=0
.
git describe --tags
y comparar com última etiqueta en la página de lanzamiento de github
Para obtener la etiqueta más reciente:
git describe --tags
Para obtener la etiqueta anotada más reciente :
git describe --abbrev=0
git describe
dice la página del manual : --abbrev=<n> [...] An <n> of 0 will suppress long format, only showing the closest tag.
git describe --tags
git checkout $(git describe --abbrev=0 --tags)
Producirá la etiqueta del último commit etiquetado en todas las ramas
git describe --tags $(git rev-list --tags --max-count=1)
TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
@ william-pursell
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.
--sort=-authordate
y--sort=authordate
.
--sort=-taggerdate
. Para las etiquetas, authordate
y committerdate
están vacías (tan inútiles como las claves de clasificación).
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1
es aún mejor :)
--points-at=$SHA
le dará la etiqueta para un hash de confirmación.
¿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.
--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)
git describe --tags $(git rev-list --tags --max-count=1)
Puede ejecutar: git describe --tags $(git rev-list --tags --max-count=1)
hablado aquí: ¿Cómo obtener el último nombre de etiqueta?
git describe ...
devuelve una etiqueta anterior ?!)
--abbrev=0
respuestas y cortaron parte de la etiqueta que quiero.
"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ó Z
como v0.2
el lunes y luego etiquetó Q
como v0.1
el martes. v0.1
es el más reciente, pero v0.2
está 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..HEAD
etc. 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 describe
hace 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 describe
busca etiquetas que sean "accesibles" desde HEAD. Por lo tanto, no encontrará etiquetas como v0.2
esa que no estén en el camino de regreso de HEAD, sino en un camino que se separó de allí.
git describe --tags
devuelve la última etiqueta que puede ver la rama actual
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.
git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p'
donde en %D
excluye los ()
caracteres que lo rodean , y el sed
s 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.
¿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:
HEAD
a base de fusión con la etiquetaHEAD
y etiquetaNo 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 HEAD
y 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 --tags
tiene 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 HEAD
con lo que quiera!
git tag -l ac* | tail -n1
Obtenga la última etiqueta con el prefijo "ac" . Por ejemplo, etiqueta nombrada con ac1.0.0
o ac1.0.5
. Otras etiquetas con nombre 1.0.0
, 1.1.0
será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-z
serán ignoradas.
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
Con git tag --help
, sobre el sort
argumento. Se usará lexicorgraphic order
por defecto, si la tag.sort
propiedad 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
git tag --sort=committerdate | tail -1
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.
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 --contains
produce una lista no vacía, ha encontrado las etiquetas más recientes.
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.
-bash: syntax error near unexpected token '('
--format="%(refname:short)"
) y omito --points-at=HEAD
, funciona. Con ese último interruptor, no devuelve nada, supongo porque mi HEAD
no está etiquetado.
HEAD
no está etiquetado.
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/master
le indicará la última etiqueta a la que se puede acceder desde origen / maestro.
for-each-ref
comando ( stackoverflow.com/a/5261470/515973 ) y la combinación derev-list
y describe
( stackoverflow.com/a/7979255/515973 )
git describe branchname --tags
funciona para mí obtener la última etiqueta en la rama (git versión 2.12.2)
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}'
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-parent
le dice que git log
no detalle ninguna historia fusionada, le --pretty=%d
dice que muestre solo las decoraciones, es decir, los nombres locales para cualquier confirmación. grep -m1
dice "coincide solo con uno", por lo que obtienes la etiqueta más reciente.
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 :)