El error "label ya existe en el control remoto" después de volver a crear la label git

Aparece el siguiente error después de ejecutar los siguientes pasos:

To git@provider.com:username/repo-name.git ! [rejected] dev -> dev (already exists) error: failed to push some refs to 'git@provider.com:username/repo-name.git' hint: Updates were rejected because the tag already exists in the remote. 
  1. Creado el repository
  2. Clonado el repository en la máquina local.
  3. Modificó el file README, confirmó los cambios y presionó la confirmación.
  4. Creado tag dev : git tag dev
  5. Etiquetas git push --tags : git push --tags
  6. Modificó el file README, confirmó los cambios y presionó la confirmación.
  7. Eliminado tag dev , lo creó de nuevo y presionó tags:

     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 -f para forzar la actualización de la label, pero esto es peligroso (por ejemplo, reescribir una confirmación hecha por error solo en la label, no en la twig).

Editar, 24 de noviembre de 2016: esta respuesta es aparentemente popular, así que estoy agregando una nota aquí. Si reemplaza una label en un server central, cualquiera que tenga la label anterior -cualquier clon del repository del server central que ya tenga la label- podría conservar su label anterior . Entonces, mientras esto le dice cómo hacerlo, esté realmente seguro de que quiere hacerlo. Necesitará que todos los que ya tienen la label "incorrecta" eliminen su "label incorrecta" y la reemplacen con la nueva "label correcta".

Las testings en Git 2.10 / 2.11 muestran que conservar la label anterior es el comportamiento pnetworkingeterminado para los clientes que ejecutan git fetch , y la actualización es el comportamiento pnetworkingeterminado para los clientes que ejecutan git fetch --tags .

(Sigue la respuesta original)


Cuando solicite insert tags, git push --tags envía (junto con cualquier confirmación y otros objects necesarios y cualquier otra actualización ref desde la configuration de inserción) a la request de actualización remota del formulario new-sha1 refs/tags/ name . (Bueno, envía sin embargo muchos: uno de esos para cada label).

La request de actualización es modificada por el control remoto para agregar una old-sha1 (o de nuevo, una para cada label), luego entregada a los ganchos de pre-recepción y / o actualización (cualesquiera ganchos que existan en el control remoto). Esos ganchos pueden decidir si permiten o rechazan la label crear / eliminar / actualizar.

El valor old-sha1 es el SHA-1 "nulo" de todos los ceros si se está creando la label. El new-sha1 es el SHA-1 nulo si la label se está eliminando. De lo contrario, ambos valores de 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 label a less que use la bandera de "fuerza" (aunque el "gancho integrado" siempre está bien con ambos "agregar" y "eliminar"). El post de rechazo que está viendo proviene de este gancho integrado. (Por cierto, este mismo gancho integrado también rechaza actualizaciones de sucursales que no son de avance rápido). 1

Pero, aquí está una de las keys para entender lo que está pasando, el paso de git push no tiene idea de si el control remoto tiene esa label ahora, y si es así, qué valor de SHA-1 tiene. Solo dice "aquí está mi list completa de tags, junto con sus valores SHA-1". El control remoto compara los valores y si hay adiciones y / o cambios, ejecuta los ganchos en esos. (Para las tags que son iguales, no hace nada. Para las tags que no tiene, lo que hace, ¡tampoco hace nada!)

Si elimina la label localmente, luego push , su inserción simplemente no transfiere la label. El control remoto asume que no se debe hacer ningún cambio.

Si elimina la label localmente, luego creela apuntando a un lugar nuevo, luego push , su inserción transfiere la label, y el control remoto ve esto como un cambio de label y rechaza el cambio, a less que sea un empuje forzado.

Por lo tanto, tienes dos opciones:

  • hacer un empuje de fuerza, o
  • eliminar la label en el control remoto.

Esto último es posible a través de git push 2 aunque borrar la label localmente y push ing no tenga ningún efecto. Suponiendo que el nombre del control remoto es origin , y la label que desea eliminar es dev :

 git push origin :refs/tags/dev 

Esto le pide al control remoto que elimine la label. La presencia o ausencia del revelador de label en su repository local es irrelevante; este tipo de push , con : remoteref como un refspec, es un push de eliminación pura.

El control remoto puede o no permitir la eliminación de tags (dependiendo de los ganchos añadidos adicionales). Si permite la eliminación, la label desaparecerá y una segunda git push --tags , cuando tenga una label de desarrollo local que apunte a algún compromiso o un object de repo de label anotado, envíe su nueva label de desarrollo. En el control remoto, dev ahora será una label recién creada, por lo que es probable que el control remoto permita el empuje (de nuevo, esto depende de los ganchos añadidos).

El empuje de fuerza es más simple. Si quiere asegurarse de no actualizar nada más que la label, simplemente dígale a git push que envíe solo ese refspec:

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

(Nota: no necesita --tags si está presionando explícitamente solo una label ref-spec).


1 Por supuesto, la razón de este gancho integrado es ayudar a reforzar el comportamiento que otros usuarios de ese mismo repository remoto esperan: que las twigs no se rebobinan y las tags no se mueven. Si fuerza el push, debe informar a los otros usuarios que está haciendo esto para que puedan corregirlo. Tenga en count que Git 1.8.2 recientemente aplica las "tags no se mueven para nada". las versiones anteriores permitirían que la label "avanzara" en el gráfico de confirmación, al igual que los nombres de las twigs. Ver las notas de la versión de git 1.8.2 .

2 Es trivial si puede iniciar session en el control remoto. Simplemente ve al repository de Git allí y ejecuta la git tag -d dev . Tenga en count que, en cualquier caso, borrar la label en el control remoto o usar git push para eliminarla, hay un período de time en el que cualquiera que acceda al control remoto encontrará que falta la label dev . (Continuarán teniendo su propia label anterior, si es que ya la tienen, e incluso podrían volver a colocar su vieja label antes de que puedas presionar la nueva).

En Mac SourceTree, solo desmarque la checkbox Activar todas las tags :

enter image description here

Es bastante simple si usa Source Tree .

enter image description here Básicamente, solo necesita eliminar y volver a agregar la label conflictiva:

  1. Ir a la pestaña Repositorio -> Etiqueta -> Eliminar label
  2. Seleccione el nombre de la label conflictiva
  3. Marque Eliminar label de todos los controles remotos
  4. Presione Eliminar
  5. Crea una nueva label con el mismo nombre para la confirmación correcta
  6. Asegúrese de marcar Push all tags cuando empuje sus cambios a control remoto

Si desea ACTUALIZAR una label, digamos que 1.0.0

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

HECHO

La razón por la que te rechazan es porque tu label perdió synchronization con la versión remota. Este es el mismo comportamiento con las twigs.

sincronizar con la label desde el control remoto mediante git pull --rebase <repo_url> +refs/tags/<TAG> y después de la synchronization, debe gestionar los conflictos . Si tienes un diftool instalado (por ejemplo, git mergetool meld ) git mergetool meld para sincronizar el control remoto y guarda tus cambios.

La razón por la que está tirando con –rebase flag es que quiere poner su trabajo encima del control remoto para evitar otros conflictos.

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


Otra forma de resolverlo es emitir un git reflog e ir al momento en que presionó la label dev en el control remoto. Copie la identificación del commit y git reset --mixed <commmit_id_from_reflog> esta manera usted sabrá que su label estaba sincronizada con el control remoto en el momento en que la presionó y no popupán conflictos.

En Windows SourceTree, desmarque Push all tags to remotes .

enter image description here

Parece que llegué tarde a este problema y ya se me respondió, pero lo que podría hacerse es: (en mi caso, solo tenía una label localmente, así que … eliminé la label anterior y la retiré con :

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

Entonces:

 git push --tags -f 

Eso actualizará todas las tags en el control remoto.

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