Comencemos explicando qué es una etiqueta en git
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.
No podrá retirar las etiquetas si no está localmente en su repositorio, así que primero debe colocar fetch
las 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 origin
usar 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.
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
¿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 checkout
comando. Como se explicó anteriormente, las etiquetas son como cualquier otra confirmación, por lo que podemos usar checkout
y, 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 --branch
comando 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/tags
lugar de solo especificar el <tagname>
.
¿Por qué? - Se recomienda su uso, refs/tags
ya 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-tags
empuja 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)
Desde Git 2.4 puedes configurarlo usando la configuración
$ git config --global push.followTags true
Cheatsheet:
git checkout A
. lo que esA
? ¿Cómo creasteA
?A
es un hash de compromisogit 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.(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 losrefs/heads/
nombres de una rama; una cadena que comienza conrefs/remotes/
nombres de una rama de seguimiento remoto; y una cadena que comienza con losrefs/tags/
nombres de una etiqueta. El nombrerefs/stash
es la referencia de alijo (como se usa engit 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
, yCHERRY_PICK_HEAD
, en particular, son también nombres que pueden referirse a commit específicos (aunqueHEAD
normalmente contiene el nombre de una rama, es decir, contiene ). Pero en general, las referencias comienzan con .ref: refs/heads/branch
refs/
Una cosa que Git hace para hacer que esto sea confuso es que le permite omitir
refs/
la palabra, y a menudo la siguienterefs/
. Por ejemplo, puede omitirrefs/heads/
orefs/tags/
al referirse a una rama o etiqueta local, ¡y de hecho debe omitirrefs/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
fetch
ypush
operaciones. También se puede utilizargit ls-remote
ogit remote show
para verlos, perofetch
ypush
son los puntos más interesantes de contacto.Refspecs
Durante
fetch
ypush
, 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. Sinfetch
embargo, hay algo de magia especial aquí , y afecta tanto a los nombres de ramas como a los nombres de etiquetas.Debería pensar
git fetch
en 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 dentrorefs/heads/
y todo dentrorefs/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
: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 arefs/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
origin
las ramas se convierten en sus ramas de seguimiento remoto para control remotoorigin
. El nombre de la sucursal se convierte en el nombre de la sucursal de seguimiento remoto, con el nombre del remoto, en este casoorigin
, 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--tags
tiene el efecto de agregarrefs/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 remotoEditar, enero de 2017: a partir de Git 2.10 , las pruebas muestran que--tags
actualiza 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
origin
tiene etiquetaxyzzy
, y usted no, y ustedgit fetch origin "refs/tags/*:refs/tags/*"
, se lerefs/tags/xyzzy
agrega a su repositorio (señalando el mismo compromiso que en el control remoto). Si usa+refs/tags/*:refs/tags/*
su etiquetaxyzzy
, si tiene una, se reemplaza por la deorigin
. 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
--tags
opción ni la--no-tags
opción,git fetch
toma 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 repositorioEditar, 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 fetch
está examinando, su Git agrega T a sus etiquetas con o sin--tags
. Agregar--tags
hace 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 --tags
para 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 ejecutarlasgit 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 fetch
hará 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, yrefs/heads/
, yrefs/tags/
, y así sucesivamente mayor parte del tiempo. Pero cuando no puedes?La respuesta completa (o casi completa) está en la
gitrevisions
documentació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 etiquetaxyzzy
y una ramaxyzzy
, y apuntan a confirmaciones diferentes, entonces:le dará la identificación a la que apunta la etiqueta. Sin embargo, y esto es lo que falta
gitrevisions
,git checkout
prefiere los nombres de las ramas, porgit checkout xyzzy
lo 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/xyzzy
orefs/tags/xyzzy
. (Tenga en cuenta que esto hace el trabajo congit checkout
, pero de una manera tal vez inesperada:git checkout refs/heads/xyzzy
hace un check out-cabeza separada en lugar de una obtención rama Esto es por lo que sólo hay que notar que.git checkout
Va a utilizar el nombre corto como nombre de la sucursal en primer lugar: así es como se revisa la ramaxyzzy
incluso si la etiquetaxyzzy
existe. Si quieres revisar la etiqueta, puedes usarlarefs/tags/xyzzy
).Debido a que (como
gitrevisions
notas) 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/name
tags/xyzzy
xyzzy
xyzzy
$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 fetch
y 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.
fuente
git fetch
solo buscará las etiquetas del control remoto dado el--tags
argumento.--tags
,--no-tags
y 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.Para pagar una etiqueta git, debe ejecutar el siguiente comando
por ejemplo, como se menciona a continuación.
Para obtener todas las etiquetas, use el comando
fuente
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
fuente