¿Qué es la etiqueta git, cómo crear etiquetas y cómo retirar las etiquetas remotas git?

524

cuando pago la etiqueta remota de git, use un comando como este:

git checkout -b local_branch_name origin/remote_tag_name

Tengo un error como este:

error: pathspec `origin/remote_tag_name` did not match any file(s) known to git.

Puedo encontrar remote_tag_name cuando uso el comando git tag.

Ryanqy
fuente

Respuestas:

1154

Comencemos explicando qué es una etiqueta en git

ingrese la descripción de la imagen aquí

Se usa una etiqueta para etiquetar y marcar una confirmación específica en el historial.
Por lo general, se usa para marcar puntos de liberación (por ejemplo, v1.0, etc.).

Aunque una etiqueta puede parecer similar a una rama, una etiqueta, sin embargo, no cambia . Apunta directamente a un compromiso específico en la historia.

ingrese la descripción de la imagen aquí


No podrá retirar las etiquetas si no está localmente en su repositorio, así que primero debe colocar fetchlas etiquetas en su repositorio local.

Primero, asegúrese de que la etiqueta existe localmente haciendo

# --all will fetch all the remotes.
# --tags will fetch all tags as well
$ git fetch --all --tags --prune

Luego revisa la etiqueta ejecutando

$ git checkout tags/<tag_name> -b <branch_name>

En lugar de originusar el tags/prefijo.


En este ejemplo tiene 2 etiquetas versión 1.0 y versión 1.1, puede verificarlas con cualquiera de los siguientes:

$ git checkout A  ...
$ git checkout version 1.0  ...
$ git checkout tags/version 1.0  ...

Todo lo anterior hará lo mismo ya que la etiqueta es solo un puntero a una confirmación dada.

ingrese la descripción de la imagen aquí
origen: https://backlog.com/git-tutorial/img/post/stepup/capture_stepup4_1_1.png


¿Cómo ver la lista de todas las etiquetas?

# list all tags
$ git tag

# list all tags with given pattern ex: v-
$ git tag --list 'v-*'

¿Cómo crear etiquetas?

Hay 2 formas de crear una etiqueta:

# lightweight tag 
$ git tag 

# annotated tag
$ git tag -a

La diferencia entre los 2 es que al crear una etiqueta anotada puede agregar metadatos como lo ha hecho en un git commit:
nombre, correo electrónico, fecha, comentario y firma

ingrese la descripción de la imagen aquí

¿Cómo borrar etiquetas?

# delete any (local) given tag
$ git tag -d <tag name>

# Delete a tag from the server with push tags
$ git push --delete origin <tag name>

¿Cómo clonar una etiqueta específica?

Para obtener el contenido de una etiqueta dada, puede usar el checkoutcomando. Como se explicó anteriormente, las etiquetas son como cualquier otra confirmación, por lo que podemos usar checkouty, en lugar de usar el SHA-1, simplemente reemplazarlo con el nombre de etiqueta

Opción 1:

# Update the local git repo with the latest tags from all remotes
$ git fetch --all

# checkout the specific tag
$ git checkout tags/<tag> -b <branch>

Opcion 2:

Usar el comando clonar

Dado que git admite el clon superficial agregando el --branchcomando clone, podemos usar el nombre de la etiqueta en lugar del nombre de la rama. Git sabe cómo "traducir" el SHA-1 dado a la confirmación correspondiente

# Clone a specific tag name using git clone 
$ git clone <url> --branch=<tag_name>

git clone --branch =

--branch También puede tomar etiquetas y separa el HEAD en ese commit en el repositorio resultante.


¿Cómo empujar etiquetas?

git push --tags

Para empujar todas las etiquetas:

# Push all tags
$ git push --tags 

Usando el en refs/tagslugar de solo especificar el <tagname>.

¿Por qué? - Se recomienda su uso, refs/tagsya que a veces las etiquetas pueden tener el mismo nombre que sus ramas y el simple git push empujará la rama en lugar de la etiqueta

Para insertar etiquetas anotadas y etiquetas de cadena de historial actual, use:

git push --follow-tags

Este indicador --follow-tagsempuja las confirmaciones y solo las etiquetas que son ambas:

  • Etiquetas anotadas (para que pueda omitir las etiquetas de compilación locales / temporales)
  • Etiquetas alcanzables (un antepasado) desde la rama actual (ubicada en el historial)

ingrese la descripción de la imagen aquí

Desde Git 2.4 puedes configurarlo usando la configuración

$ git config --global push.followTags true

Cheatsheet: ingrese la descripción de la imagen aquí


CodeWizard
fuente
3
bonito. git checkout A. lo que es A? ¿Cómo creaste A?
Miel
3
@CodeWizard ¡Buen diagrama de flujo! ¿Qué software usaste para producirlo?
Giovanni Lovato
44
@Honey Aes un hash de compromiso
Alex Baklanov
2
@GiovanniLovato El diagrama de flujo es de terceros. El enlace a la imagen es backlog.com/git-tutorial/img/post/stepup/… que es de esta página backlog.com/git-tutorial/stepup/stepup4_1.html del sitio web llamado Git Beginner's Guide for Dummies (backlog .com).
George
2
Vale la pena señalar que git checkout tags/<tag_name> -b <branch_name>requiere el -b <branch_name>. git checkout tags/<tag_name>me dio una cabeza desprendida. Según este artículo sobre cabeza separada , evita una cabeza separada al crear y eliminar temporalmente una rama. Este es un flujo de trabajo bastante extraño. Claramente, como usuario de git necesito acostumbrarme a crear y eliminar ramas para divertirnos y obtener ganancias.
icc97
194

(Esta respuesta tardó un tiempo en escribirse, y la respuesta de codeWizard es correcta en cuanto a objetivo y esencia, pero no del todo completa, así que publicaré esto de todos modos).


No existe una "etiqueta Git remota". Solo hay "etiquetas". Señalo todo esto no ser pedante, 1 sino porque hay una gran confusión acerca de esto con los usuarios ocasionales de Git, y la documentación Git no es muy útil 2 para los principiantes. (No está claro si la confusión se debe a una documentación deficiente, o la documentación deficiente se debe a que esto es intrínsecamente algo confuso, o qué).

No son "ramas remotas", más propiamente llamados "ramas" de seguimiento remoto, pero vale la pena señalar que estos son en realidad entidades locales. Sin embargo, no hay etiquetas remotas (a menos que las (re) invente). Solo hay etiquetas locales, por lo que debe obtener la etiqueta localmente para poder usarla.

La forma general de nombres para confirmaciones específicas, que Git llama referencias, es cualquier cadena que comience con refs/. Una cadena que comienza con los refs/heads/nombres de una rama; una cadena que comienza con refs/remotes/nombres de una rama de seguimiento remoto; y una cadena que comienza con los refs/tags/nombres de una etiqueta. El nombre refs/stashes la referencia de alijo (como se usa en git stash; tenga en cuenta la falta de una barra inclinada final).

Hay algunos nombres de casos especiales inusuales que no comienzan con refs/: HEAD, ORIG_HEAD, MERGE_HEAD, y CHERRY_PICK_HEAD, en particular, son también nombres que pueden referirse a commit específicos (aunque HEADnormalmente contiene el nombre de una rama, es decir, contiene ). Pero en general, las referencias comienzan con .ref: refs/heads/branchrefs/

Una cosa que Git hace para hacer que esto sea confuso es que le permite omitir refs/la palabra, y a menudo la siguiente refs/. Por ejemplo, puede omitir refs/heads/o refs/tags/al referirse a una rama o etiqueta local, ¡y de hecho debe omitir refs/heads/al retirar una sucursal local! Puede hacer esto siempre que el resultado sea inequívoco o, como acabamos de señalar, cuando debe hacerlo (para ).git checkout branch

Es cierto que las referencias existen no solo en su propio repositorio, sino también en repositorios remotos. Sin embargo, Git le da acceso a las referencias de un repositorio remoto solo en momentos muy específicos: a saber, durante fetchy pushoperaciones. También se puede utilizar git ls-remoteo git remote showpara verlos, pero fetchy pushson los puntos más interesantes de contacto.

Refspecs

Durante fetchy push, Git usa cadenas que llama refspecs para transferir referencias entre el repositorio local y remoto. Por lo tanto, es en estos momentos, y a través de las especificaciones técnicas, que dos repositorios de Git pueden sincronizarse entre sí. Una vez que sus nombres estén sincronizados, puede usar el mismo nombre que usa alguien con el control remoto. Sin fetchembargo, hay algo de magia especial aquí , y afecta tanto a los nombres de ramas como a los nombres de etiquetas.

Debería pensar git fetchen indicarle a su Git que llame (o quizás envíe un mensaje de texto) a otro Git, el "control remoto", y que tenga una conversación con él. Al principio de esta conversación, el control remoto enumera todas sus referencias: todo dentro refs/heads/y todo dentro refs/tags/, junto con cualquier otra referencia que tenga. Tu Git escanea a través de estos y (según la referencia de búsqueda habitual) cambia el nombre de sus ramas.

Echemos un vistazo a la especificación de referencia normal para el control remoto llamado origin:

$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$ 

Esta especificación de referencia le indica a su Git que tome cada coincidencia de nombre refs/heads/*, es decir, cada rama en el control remoto, y cambie su nombre a refs/remotes/origin/*, es decir, mantenga la parte coincidente igual, cambiando el nombre de la rama ( refs/heads/) a un nombre de rama de seguimiento remoto ( refs/remotes/específicamente , refs/remotes/origin/).

Es a través de esta especificación de referencia que originlas ramas se convierten en sus ramas de seguimiento remoto para control remoto origin. El nombre de la sucursal se convierte en el nombre de la sucursal de seguimiento remoto, con el nombre del remoto, en este caso origin, incluido. El signo más +en el frente de la especificación de referencia establece la bandera de "fuerza", es decir, su rama de seguimiento remoto se actualizará para que coincida con el nombre de la rama del control remoto, independientemente de lo que haga falta para que coincida. (Sin las +actualizaciones de rama se limitan a cambios de "avance rápido", y las actualizaciones de etiquetas simplemente se ignoran desde la versión 1.8.2 de Git más o menos, antes de eso se aplicaban las mismas reglas de avance rápido).

Etiquetas

¿Pero qué hay de las etiquetas? No hay ninguna especificación de referencia para ellos, al menos, no de manera predeterminada. Puede configurar uno, en cuyo caso la forma de la especificación de referencia depende de usted; o puedes correr git fetch --tags. El uso --tagstiene el efecto de agregar refs/tags/*:refs/tags/*a la especificación de referencia, es decir, trae todas las etiquetas ( pero no actualiza su etiqueta si ya tiene una etiqueta con ese nombre, independientemente de lo que dice la etiqueta del control remoto Editar, enero de 2017: a partir de Git 2.10 , las pruebas muestran que --tagsactualiza por la fuerza sus etiquetas de las etiquetas del control remoto, como si se leyera la especificación de referencia +refs/tags/*:refs/tags/*; esto puede ser una diferencia en el comportamiento de una versión anterior de Git).

Tenga en cuenta que no hay cambio de nombre aquí: si el control remoto origintiene etiqueta xyzzy, y usted no, y usted git fetch origin "refs/tags/*:refs/tags/*", se le refs/tags/xyzzyagrega a su repositorio (señalando el mismo compromiso que en el control remoto). Si usa +refs/tags/*:refs/tags/*su etiqueta xyzzy, si tiene una, se reemplaza por la de origin. Es decir, la +bandera de fuerza en una especificación de referencia significa "reemplazar el valor de mi referencia con el que mi Git obtiene de su Git".

Etiquetas automáticas durante la recuperación

Por razones históricas, 3 si no utiliza la --tagsopción ni la --no-tagsopción, git fetchtoma medidas especiales. Recuerde que dijimos anteriormente que el control remoto comienza mostrándole a su Git local todas sus referencias, ya sea que su Git local quiera verlas o no. 4 Your Git toma nota de todas las etiquetas que ve en este momento. Luego, a medida que comienza a descargar los objetos de confirmación que necesita para manejar lo que sea que esté obteniendo, si una de esas confirmaciones tiene la misma ID que cualquiera de esas etiquetas, git agregará esa etiqueta, o esas etiquetas, si varias etiquetas tienen esa ID, a tu repositorio

Editar, enero de 2017: las pruebas muestran que el comportamiento en Git 2.10 es ahora: si su Git proporciona una etiqueta llamada T , y no tiene una etiqueta llamada T , y el ID de confirmación asociado con T es un antepasado de una de sus ramas que git fetchestá examinando, su Git agrega T a sus etiquetas con o sin --tags. Agregar --tagshace que su Git obtenga todas sus etiquetas y también fuerce la actualización.

Línea de fondo

Puede que tenga que usar git fetch --tagspara obtener sus etiquetas. Si sus nombres de etiqueta entran en conflicto con sus nombres de etiqueta existentes, puede (dependiendo de la versión de Git) incluso tener que eliminar (o renombrar) algunas de sus etiquetas, y luego ejecutarlas git fetch --tags, para obtener sus etiquetas. Dado que las etiquetas, a diferencia de las ramas remotas, no tienen cambio de nombre automático, los nombres de las etiquetas deben coincidir con sus nombres, por lo que puede tener problemas con los conflictos.

Sin embargo, en la mayoría de los casos normales, un simple git fetchhará el trabajo, presentando sus commits y sus etiquetas coincidentes, y dado que ellos, sean quienes sean, etiquetarán los commits en el momento en que publiquen esos commits, usted se mantendrá al día con sus etiquetas. Si no crea sus propias etiquetas, ni combina su repositorio y otros repositorios (a través de múltiples controles remotos), tampoco tendrá colisiones de nombres de etiquetas, por lo que no tendrá que preocuparse por eliminar o cambiar el nombre de las etiquetas para obtener sus etiquetas.

Cuando necesitas nombres calificados

He mencionado antes que se puede omitir refs/casi siempre, y refs/heads/, y refs/tags/, y así sucesivamente mayor parte del tiempo. Pero cuando no puedes?

La respuesta completa (o casi completa) está en la gitrevisionsdocumentación . Git resolverá un nombre a una ID de confirmación utilizando la secuencia de seis pasos que se proporciona en el enlace. Curiosamente, las etiquetas anulan las ramas: si hay una etiqueta xyzzyy una rama xyzzy, y apuntan a confirmaciones diferentes, entonces:

git rev-parse xyzzy

le dará la identificación a la que apunta la etiqueta. Sin embargo, y esto es lo que falta gitrevisions, git checkoutprefiere los nombres de las ramas, por git checkout xyzzylo que lo colocará en la rama, sin tener en cuenta la etiqueta.

En caso de ambigüedad, casi siempre puede deletrear el nombre de referencia usando su nombre completo, refs/heads/xyzzyo refs/tags/xyzzy. (Tenga en cuenta que esto hace el trabajo con git checkout, pero de una manera tal vez inesperada: git checkout refs/heads/xyzzyhace un check out-cabeza separada en lugar de una obtención rama Esto es por lo que sólo hay que notar que. git checkoutVa a utilizar el nombre corto como nombre de la sucursal en primer lugar: así es como se revisa la rama xyzzyincluso si la etiqueta xyzzyexiste. Si quieres revisar la etiqueta, puedes usarla refs/tags/xyzzy).

Debido a que (como gitrevisionsnotas) Git lo intentará , también puede simplemente escribir para identificar el commit etiquetado . (Si alguien ha conseguido escribir una referencia válida nombrado en , sin embargo, esto se resuelve como . Pero normalmente sólo los diversos nombres debe estar en .)refs/nametags/xyzzyxyzzyxyzzy$GIT_DIR$GIT_DIR/xyzzy*HEAD$GIT_DIR


1 Bien, bien, "no solo para ser pedante". :-)

2 Algunos dirían "muy poco útil" y, en realidad, tendería a estar de acuerdo.

3 Básicamente, git fetchy todo el concepto de controles remotos y refspecs, fue una adición tardía a Git, que sucedió en la época de Git 1.5. Antes de eso, solo había algunos casos especiales ad-hoc, y la búsqueda de etiquetas era uno de ellos, por lo que se introdujo mediante un código especial.

4 Si ayuda, piense en el Git remoto como un flasher , en el sentido de la jerga.

torek
fuente
Gran redacción. Un pequeño error: git fetchsolo buscará las etiquetas del control remoto dado el --tagsargumento.
quincenal
@cweekly: el comportamiento de --tags, --no-tagsy por defecto es en realidad bastante complicado. El valor predeterminado es traer etiquetas que no tiene que están en las confirmaciones que está trayendo. (Vea la edición de enero de 2017). Pero también hay fallas aquí, y Git moderno está teniendo sus --tags / El código de manejo sin etiquetas se revisó una vez más, lo que probablemente conducirá a casos de esquina aún más especiales.
torek
1

Para pagar una etiqueta git, debe ejecutar el siguiente comando

git checkout tags/tag-name -b branch-name

por ejemplo, como se menciona a continuación.

 git checkout tags/v1.0 -b v1.0-branch

Para obtener todas las etiquetas, use el comando

git fetch --all --tags
mani
fuente
0

Para obtener el código de etiqueta específico, intente crear una nueva rama y agregue el código de etiqueta. Lo hice por orden:$git checkout -b newBranchName tagName

Rahul Khatri
fuente