web-dev-qa-db-fra.com

"Balise existe déjà dans la télécommande" après la recréation de la balise

J'obtiens l'erreur suivante après avoir exécuté les étapes ci-dessous:

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. Créé le référentiel
  2. Cloné le dépôt sur la machine locale.
  3. Modification du fichier README, validation des modifications et validation du commit.
  4. Balise créée dev: git tag dev
  5. Balises poussées: git Push --tags
  6. Modification du fichier README, validation des modifications et validation du commit.
  7. Balise supprimée dev, créée à nouveau et balises poussées:

    git tag -d dev
    git tag dev
    git Push --tags
    

Pourquoi cela arrive-t-il?

Je suis sur Mac. Mes amis qui utilisent Linux (Ubuntu) n'ont pas ce problème. Je sais que je peux utiliser git Push --tags -f pour forcer la mise à jour de la balise, mais cela est dangereux (par exemple, la réécriture d'un commit effectué par erreur uniquement dans la balise, pas dans la branche).

129
Luca Boieru

Edit, 24 Nov 2016: cette réponse est apparemment populaire, alors j'ajoute une note ici. Si vous remplacez une balise sur un serveur central, toute personne possédant la balise old (tout clone de ce référentiel de serveur central qui: a déjà la balise - pourrait conserver son ancienne balise . Donc, même si cela vous dit comment le faire, soyez vraiment sûr que vous voulez le faire. Vous devez demander à tous ceux qui possèdent déjà la "mauvaise" balise de supprimer leur "mauvaise balise" et de la remplacer par la nouvelle "balise de droite".

Les tests dans Git 2.10/2.11 montrent que conserver les anciennes balises est le comportement par défaut des clients exécutant _git fetch_ et que la mise à jour est le comportement par défaut des clients exécutant _git fetch --tags_.

(La réponse originale suit.)


Lorsque vous demandez aux balises Push, _git Push --tags_ envoie (avec tous les commits et autres objets nécessaires et toute autre mise à jour de référence à partir des paramètres Push) une demande de mise à jour à distance de la forme _new-sha1 refs/tags/name_. (Et bien, il en envoie cependant plusieurs: un de ceux pour chaque tag.)

La demande de mise à jour est modifiée par la télécommande pour ajouter un old-sha1 (ou encore, une pour chaque balise), puis transmise aux points d'ancrage de pré-réception et/ou de mise à jour. (selon les crochets présents sur la télécommande). Ces points d'ancrage peuvent décider d'autoriser ou de rejeter la balise create/delete/update.

La valeur old-sha1 est le SHA-1 "zéro" tous zéros si la balise est en cours de création. Le new-sha1 est un SHA-1 nul si la balise est en cours de suppression. Sinon, les deux valeurs SHA-1 sont réelles et valides.

Même sans crochet, il y a une sorte de "crochet intégré" qui est également exécuté: la télécommande refusera de déplacer une balise à moins que vous n'utilisiez le drapeau "force" (bien que le "crochet intégré" soit toujours OK avec les deux "ajouter" et "supprimer"). Le message de rejet que vous voyez provient de ce crochet intégré. (Incidemment, ce même crochet intégré rejette également les mises à jour de branche qui ne sont pas des transferts rapides.)1

Mais, voici l'une des clés pour comprendre ce qui se passe, l'étape _git Push_ n'a aucune idée si la télécommande possède maintenant cette balise et, dans l'affirmative, quelle est sa valeur SHA-1. Il dit seulement "voici ma liste complète de tags, avec leurs valeurs SHA-1". La télécommande compare les valeurs et, s'il y a des ajouts et/ou des modifications, exécute les points d'ancrage sur celles-ci. (Pour les balises qui sont identiques, cela ne fait rien du tout. Pour les balises que vous n'avez pas ce qu'elles font, cela ne fait rien non plus!)

Si vous supprimez la balise localement, alors Push, votre Push ne transfère tout simplement pas la balise. La télécommande suppose qu'aucun changement ne devrait être fait.

Si vous supprimez la balise localement, créez-la en pointant vers un nouvel emplacement, puis Push, votre Push transfère la balise, et la télécommande la voit comme une modification de balise et rejette la modification, à moins qu'il s'agisse d'une poussée forcée.

Ainsi, vous avez deux options:

  • faire un push-force, ou
  • supprimer l'étiquette sur la télécommande.

Ce dernier est possible via _git Push_2 bien que la suppression de la balise localement et de Pushing n’ait aucun effet. En supposant que le nom de la télécommande est Origin et que la balise à supprimer soit dev:

_git Push Origin :refs/tags/dev
_

Ceci demande à la télécommande de supprimer le tag. La présence ou l'absence de la balise dev dans votre référentiel local n'est pas pertinente. Ce type de Push, avec _:remoteref_ en tant que refspec, est un push en suppression pure.

La télécommande peut autoriser ou non la suppression des étiquettes (en fonction des points d'ancrage supplémentaires ajoutés). Si la suppression est autorisée, la balise disparaîtra et une deuxième _git Push --tags_, lorsque vous avez une balise locale dev pointant vers un objet de mise en pension de balise commit ou annotée, envoyez votre nouvelle balise dev. Sur la télécommande, dev sera désormais une balise nouvellement créée. Par conséquent, la télécommande autorisera probablement le Push (encore une fois, cela dépend des points d'ancrage supplémentaires ajoutés).

La force-Push est plus simple. Si vous voulez être sûr de ne rien mettre à jour autre que la balise, indiquez simplement _git Push_ pour envoyer uniquement ce refspec:

_git Push --force Origin refs/tags/dev:refs/tags/dev
_

(Remarque: vous n'avez pas besoin de _--tags_ si vous insérez explicitement une seule balise ref-spec).


1Bien entendu, la raison de ce hook intégré consiste à aider à appliquer le comportement attendu par les autres utilisateurs de ce même référentiel distant: les branches ne sont pas rembobinées et les balises ne le sont pas. bouge toi. Si vous forcez le Push, vous devriez informer les autres utilisateurs que vous faites cela, afin qu'ils puissent le corriger. Notez que "les tags ne bougent pas du tout" est récemment appliqué par Git 1.8.2; Les versions précédentes permettaient à la balise de "progresser" dans le graphique de validation, un peu comme les noms de branches. Voir les notes de version de git 1.8.2 .

2C'est trivial si vous pouvez vous connecter sur la télécommande. Allez simplement dans le dépôt Git et lancez _git tag -d dev_. Notez que de toute façon - en supprimant la balise sur la télécommande ou en utilisant _git Push_ pour la supprimer - il y a une période de temps où toute personne accédant à la télécommande trouvera que la balise dev est manquante. (Ils continueront à avoir leur propre vieille balise, s'ils l'ont déjà, et ils pourraient même repousser leur vieille balise avant de pouvoir pousser le nouveau.)

161
torek

Sous Mac SourceTree, désélectionnez uniquement la case à cocher . Toutes les balises :

enter image description here

48
itzhar

C'est assez simple si vous utilisez SourceTree .

enter image description here En gros, il vous suffit de supprimer et d'ajouter de nouveau la balise en conflit:

  1. Aller à l'onglet Repository -> Tag -> Supprimer la balise
  2. Sélectionnez le nom de l'étiquette en conflit
  3. Vérifier Supprimer la balise de toutes les télécommandes
  4. Appuyez sur Supprimer
  5. Créer une nouvelle balise avec le même nom pour le bon commit
  6. Assurez-vous de cocher toutes les balises lorsque vous transmettez vos modifications à distance.
14
choofie

Si vous voulez METTRE À JOUR une balise, disons-le 1.0.0

  1. git checkout 1.0.0
  2. apportez vos modifications
  3. git ci -am 'modify some content'
  4. git tag -f 1.0.0
  5. supprimer la balise distante sur github: git Push Origin --delete 1.0.0
  6. git Push Origin 1.0.0

FAIT

12
Kaiyu Lee

Il semble que je sois en retard sur ce problème et/ou que l’on ait déjà répondu à cette question, mais, ce qui pourrait être fait, c’est: (dans mon cas, je n’avais qu’une balise localement, alors j’ai effacé la vieille balise et l’a repérée avec :

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

Ensuite:

git Push --tags -f

Cela mettra à jour tous les balises sur la télécommande.

Peut être dangereux! Utiliser à vos propres risques.

8
André Tzermias

La raison pour laquelle vous obtenez rejeté est que votre balise a perdu la synchronisation avec la version distante. C'est le même comportement avec les branches.

synchroniser avec la balise de la télécommande via git pull --rebase <repo_url> +refs/tags/<TAG> et après la synchronisation, vous devez gérer les conflits. Si vous avez un outil diftool installé (par exemple, meld), git mergetool meld, utilisez-le pour synchroniser à distance et conserver vos modifications.

La raison pour laquelle vous tirez avec - rebase est que vous voulez placer votre travail au-dessus de celui à distance afin d'éviter d'autres conflits.

Aussi, ce que je ne comprends pas, c'est pourquoi voudriez-vous supprimer la balise dev et la recréer ??? Les balises sont utilisées pour spécifier les versions de logiciel ou les jalons. Exemple de balises git v0.1dev, v0.0.1alpha, v2.3-cr (cr - version candidate), etc.


Une autre façon de résoudre ce problème consiste à envoyer un git reflog et d'aller au moment où vous avez appuyé sur la balise dev de la télécommande. Copiez l'id de commit et git reset --mixed <commmit_id_from_reflog> de cette façon, vous savez que votre balise est synchronisée avec la télécommande au moment où vous l'avez poussée et aucun conflit ne sera résolu. survenir.

4

Dans Windows SourceTree, décochez Push all tags to remotes.

enter image description here

2
Contango