(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/stash
es 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 HEAD
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 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 fetch
y push
operaciones. También se puede utilizar git ls-remote
o git remote show
para verlos, pero fetch
y push
son los puntos más interesantes de contacto.
Refspecs
Durante fetch
y 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 fetch
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 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 origin
las 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 --tags
tiene 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 --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 etiqueta xyzzy
, y usted no, y usted git fetch origin "refs/tags/*:refs/tags/*"
, se le refs/tags/xyzzy
agrega 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 --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 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 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 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 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, 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 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 etiqueta xyzzy
y 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 checkout
prefiere los nombres de las ramas, por git 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
o 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/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 rama xyzzy
incluso si la etiqueta xyzzy
existe. Si quieres revisar la etiqueta, puedes usarla refs/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.
git checkout A
. lo que esA
? ¿Cómo creasteA
?