Error "etiqueta ya existe en el control remoto" después de recrear la etiqueta git

142

Recibo el siguiente error después de ejecutar los pasos a continuación:

To [email protected]:username/repo-name.git
 ! [rejected]        dev -> dev (already exists)
error: failed to push some refs to '[email protected]:username/repo-name.git'
hint: Updates were rejected because the tag already exists in the remote.
  1. Creado el repositorio
  2. Cloné el repositorio en la máquina local.
  3. Modificó el archivo README, confirmó los cambios y envió el commit.
  4. Etiqueta creada dev :git tag dev
  5. Etiquetas empujadas: git push --tags
  6. Modificó el archivo README, confirmó los cambios y envió el commit.
  7. Etiqueta eliminada dev, la creó nuevamente y presionó etiquetas:

    git tag -d dev
    git tag dev
    git push --tags
    

¿Por qué está pasando esto?

Estoy en Mac Mis amigos que usan Linux (Ubuntu) no tienen este problema. Sé que puedo usar git push --tags -fpara forzar la actualización de la etiqueta, pero esto es peligroso (por ejemplo, reescribir una confirmación realizada por error solo en la etiqueta, no en la rama).

Luca Boieru
fuente
1
Los commits no se hacen "en etiquetas" o "en ramas" (aunque parece seguro que este es el caso). De hecho, los nombres de etiquetas y ramas simplemente apuntan a (uno, único) commit. Ver la respuesta a continuación.
torek
8
esto funcionó para mí git pull --tagsentoncesgit push origin --tags
sab

Respuestas:

175

Edición, 24 de noviembre de 2016: esta respuesta es aparentemente popular, así que agrego una nota aquí. Si reemplazas una etiqueta en un servidor central, cualquiera que tenga la edad de marcado y cualquier clon de ese repositorio-servidor central que ya tiene la etiqueta-podría retener su antigua etiqueta . Entonces, si bien esto te dice cómo hacerlo, asegúrate de que quieres hacerlo. Deberá hacer que todos los que ya tienen la etiqueta "incorrecta" eliminen su "etiqueta incorrecta" y reemplazarla con la nueva "etiqueta correcta".

Las pruebas en Git 2.10 / 2.11 muestran que retener la etiqueta anterior es el comportamiento predeterminado para los clientes que se ejecutan git fetch, y la actualización es el comportamiento predeterminado para los clientes que se ejecutan git fetch --tags.

(La respuesta original sigue.)


Cuando solicita insertar etiquetas, git push --tagsenvía (junto con las confirmaciones y otros objetos necesarios y cualquier otra actualización de referencia desde la configuración de inserción) al remoto una solicitud de actualización del formulario . (Bueno, envía muchos: uno para cada etiqueta).new-sha1 refs/tags/name

El control remoto modifica la solicitud de actualización para agregar un old-sha1(o de nuevo, uno para cada etiqueta), luego se entrega a los ganchos de pre-recepción y / o actualización (los que existan en el control remoto). Esos ganchos pueden decidir si permitir o rechazar la etiqueta crear / eliminar / actualizar.

El old-sha1valor es SHA-1 "nulo" todo ceros si se está creando la etiqueta. El new-sha1es el SHA-1 nulo si se elimina la etiqueta. De lo contrario, ambos valores SHA-1 son valores reales y válidos.

Incluso sin ganchos, hay una especie de "gancho incorporado" que también se ejecuta: el control remoto se negará a mover una etiqueta a menos que use la bandera "forzar" (aunque el "gancho incorporado" siempre está bien con ambos "agregar" y "eliminar"). El mensaje de rechazo que estás viendo proviene de este gancho incorporado. (Por cierto, este mismo gancho incorporado también rechaza las actualizaciones de sucursales que no son de avance rápido). 1

Pero, aquí está una de las claves para entender lo que está sucediendo, el git push paso no tiene idea de si el control remoto tiene esa etiqueta ahora y, de ser así, qué valor tiene SHA-1. Solo dice "aquí está mi lista completa de etiquetas, junto con sus valores SHA-1". El control remoto compara los valores y, si hay adiciones y / o cambios, ejecuta los ganchos en ellos. (Para las etiquetas que son iguales, no hace nada en absoluto. Para las etiquetas que no tienes que tienen, ¡tampoco hace nada!)

Si elimina la etiqueta localmente, entonces push su inserción simplemente no transfiere la etiqueta. El control remoto supone que no se deben realizar cambios.

Si elimina la etiqueta localmente, créela apuntando a un lugar nuevo, luego push , su inserción transfiere la etiqueta, y el control remoto ve esto como un cambio de etiqueta y rechaza el cambio, a menos que sea una inserción forzada.

Por lo tanto, tiene dos opciones:

  • hacer un empuje forzado, o
  • Eliminar la etiqueta en el control remoto.

Esto último es posible a través de git push2 aunque eliminar la etiqueta localmente e pushing no tiene ningún efecto. Suponiendo que el nombre del control remoto es origin, y la etiqueta que desea eliminar es dev:

git push origin :refs/tags/dev

Esto le pide al control remoto que elimine la etiqueta. La presencia o ausencia de la etiqueta deven su repositorio local es irrelevante; Este tipo de push, con una especificación de referencia, es un push de eliminación pura.:remoteref

El control remoto puede o no permitir la eliminación de etiquetas (dependiendo de los ganchos adicionales agregados). Si permite la eliminación, la etiqueta desaparecerá y, un segundo git push --tags, cuando tenga una devetiqueta local que apunte a algún objeto de confirmación de etiqueta anotada, envíe su nueva devetiqueta. En el control remoto, devahora será una etiqueta recién creada, por lo que el control remoto probablemente permitirá el empuje (nuevamente, esto depende de cualquier gancho adicional agregado).

La fuerza de empuje es más simple. Si desea asegurarse de no actualizar nada más que la etiqueta, solo dígale git pushque inserte solo esa especificación de referencia:

git push --force origin refs/tags/dev:refs/tags/dev

(nota: no es necesario --tagssi está empujando explícitamente solo una etiqueta ref-spec).


1 Por supuesto, la razón de este enlace incorporado es ayudar a reforzar el comportamiento que otros usuarios del mismo repositorio remoto esperan: que las ramas no se rebobinan y las etiquetas no se mueven. Si presiona a la fuerza, debe informar a los demás usuarios que está haciendo esto, para que puedan corregirlo. Tenga en cuenta que "las etiquetas no se mueven en absoluto" es una nueva aplicación de Git 1.8.2; versiones anteriores permitirían que la etiqueta "avance" en el gráfico de confirmación, al igual que los nombres de rama. Ver las notas de lanzamiento de git 1.8.2 .

2 Es trivial si puede iniciar sesión en el control remoto. Simplemente vaya al repositorio de Git allí y ejecute git tag -d dev. Tenga en cuenta que de cualquier manera, eliminando la etiqueta en el control remoto o utilizándola git pushpara eliminarla, hay un período de tiempo en el que cualquiera que acceda al control remoto encontrará que devfalta la etiqueta. (Seguirán teniendo su propia etiqueta anterior, si ya la tienen, e incluso podrían volver a colocar su etiqueta anterior antes de que pueda presionar la nueva).

torek
fuente
¿Está sucediendo esto solo en las nuevas versiones de git? Tengo 1.7.9.5y no tengo este problema ...
Ionică Bizău
2
Probalby: tengo un vago recuerdo de git push --tagssolo cambiar la etiqueta automáticamente en versiones anteriores de git, sin --force. Sin embargo, probé esto en 1.8.4, y usted necesita --force, o la técnica de actualización de dos etapas.
torek
2
@John ツ: actualización: es un nuevo comportamiento a partir de 1.8.2, según las notas de la versión . También editaré esto en la nota 1.
torek
No sé cómo llegué a esta situación, pero esto eliminó una etiqueta y la recreé en un instante.
RiggsFolly
44
¿Cómo haces un empuje forzado si no eres un Jedi?
Fonix
54

En Mac SourceTree solo anule la selección de la casilla de verificación Insertar todas las etiquetas :

ingrese la descripción de la imagen aquí

itzhar
fuente
3
jajaja hombre tan simple, estaba leyendo la respuesta aceptada y pensé que iba a fingir esto
MegaManX
10
Esto es solo para superarlo sin resolver realmente el problema. Esto no resuelve el error de coincidencia de nombre de etiqueta en remoto y local.
amalBit
1
¡funciona para la versión de Windows también! gracias por salvarnos de leer la respuesta largamente aceptada que omite a los usuarios de sourcetree que no les importa lo que está sucediendo en el símbolo del sistema :)
schlingel
19

Es bastante simple si estás usando SourceTree .

ingrese la descripción de la imagen aquí Básicamente, solo necesita eliminar y volver a agregar la etiqueta en conflicto:

  1. Vaya a la pestaña Repositorio -> Etiqueta -> Eliminar etiqueta
  2. Seleccione el nombre de la etiqueta en conflicto
  3. Cheque Eliminar etiqueta de todos los controles remotos
  4. prensa Eliminar
  5. Cree una nueva etiqueta con el mismo nombre para la confirmación adecuada
  6. Asegúrese de marcar Insertar todas las etiquetas al enviar sus cambios a control remoto
choofie
fuente
16

Si desea ACTUALIZAR una etiqueta, digamos1.0.0

  1. git checkout 1.0.0
  2. haz tus cambios
  3. git ci -am 'modify some content'
  4. git tag -f 1.0.0
  5. eliminar etiqueta remota en github: git push origin --delete 1.0.0
  6. git push origin 1.0.0

HECHO

Kaiyu Lee
fuente
12

Parece que llegué tarde a este problema y / o ya se ha respondido, pero lo que se puede hacer es: (en mi caso, solo tenía una etiqueta localmente, así que borré la etiqueta anterior y la volví a colocar con :

git tag -d v1.0
git tag -a v1.0 -m "My commit message"

Luego:

git push --tags -f

Eso actualizará todas las etiquetas en el control remoto.

¡Podría ser peligroso! Uso bajo su propio riesgo.

André Tzermias
fuente
1
¡Esto lo hizo por mí! Las etiquetas eran solo localmente y no en el control remoto :)
pgarciacamou
4

La razón por la que te rechazan es porque tu etiqueta perdió la sincronización con la versión remota. Este es el mismo comportamiento con las ramas.

sincronice con la etiqueta desde el control remoto a través de git pull --rebase <repo_url> +refs/tags/<TAG>y después de sincronizar, debe gestionar los conflictos . Si tiene instalado un diftool (ej. Meld)git mergetool meld para sincronizar el control remoto y mantener sus cambios.

La razón por la que está tirando con el indicador --rebase es que desea colocar su trabajo encima del remoto para evitar otros conflictos.

Además, lo que no entiendo es ¿por qué eliminarías la devetiqueta y la volverías a crear? Las etiquetas se utilizan para especificar versiones de software o hitos. Ejemplo de etiquetas git v0.1dev, v0.0.1alpha, v2.3-cr(cr - Release Candidate) y así sucesivamente ..


Otra forma de resolver esto es emitir un problema git refloge ir al momento en que presionó la devetiqueta en el control remoto. Copie la identificación de confirmación y de git reset --mixed <commmit_id_from_reflog>esta manera sabrá que su etiqueta estaba sincronizada con el control remoto en el momento en que la presionó y no surgirán conflictos.

Daniel Andrei Mincă
fuente
Por ejemplo, si desea etiquetar una confirmación que está actualmente en producción. ¿Tendría que eliminar la etiqueta de producción anterior de una confirmación específica y crear y enviar una nueva etiqueta para la confirmación después de una nueva versión de producción?
Ville Miekk-oja
2

En Windows SourceTree, desmarque Push all tags to remotes.

ingrese la descripción de la imagen aquí

Aplazamiento de pago
fuente
0

Algunas buenas respuestas aquí. Especialmente el de @torek . Pensé que agregaría esta solución alternativa con una pequeña explicación para quienes tienen prisa.

En resumen, lo que sucede es que cuando mueve una etiqueta localmente, cambia la etiqueta de un valor de confirmación no Nulo a un valor diferente. Sin embargo, debido a que git (como comportamiento predeterminado) no permite cambiar etiquetas remotas no nulas, no puede impulsar el cambio.

La solución es eliminar la etiqueta (y marcar eliminar todos los controles remotos). Luego cree la misma etiqueta y presione.

idnavid
fuente