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.
dev
: git tag dev
git push --tags
: git push --tags
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:
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 :
Es bastante simple si usa Source Tree .
Básicamente, solo necesita eliminar y volver a agregar la label conflictiva:
Si desea ACTUALIZAR una label, digamos que 1.0.0
git checkout 1.0.0
git ci -am 'modify some content'
git tag -f 1.0.0
git push origin --delete 1.0.0
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
.
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.