Dans git, est-ce une mauvaise idée de créer une balise avec le même nom qu'une branche supprimée?

20

J'ai un projet avec un modèle de branchement git qui suit à peu près celui du git-flow de nvie .

Nos branches de publication sont nommées dans un format SemVer , par exemplev1.5.2

Une fois qu'une branche de publication reçoit le feu vert pour la production, nous fermons la branche, en la fusionnant dans master, en appliquant une balise, puis en supprimant la branche.

Comme nous supprimons immédiatement la branche de publication, nous utilisons le même identifiant pour baliser la branche, par exemple v1.5.2

Voici les commandes que nous utiliserions pour fermer une branche de publication:

$ git checkout master
$ git merge v1.5.2
$ git tag -a v1.5.2 -m "Version 1.5.2 - foo bar, baz, etc"
$ git branch -d v1.5.2
$ git branch -dr origin/v1.5.2
$ git push origin :v1.5.2
$ git push
$ git push --tags

Cela semble fonctionner dans la majorité des cas, mais cela provoque un problème dans le scénario où une autre instance du dépôt git (par exemple, une autre machine de développement ou un environnement de transfert) a une extraction locale de la branche v1.5.2.

La git push origin :v1.5.2commande supprimera la branche dans la télécommande, mais ne supprimera pas la version locale de la branche (si elle existe) dans tous les référentiels.

Cela conduit à une référence ambiguë, lors de la tentative d'extraction v1.5.2dans ces dépôts:

$ git checkout v1.5.2
warning: refname 'v1.5.2' is ambiguous.

Cela peut-il être évité sans utiliser une syntaxe différente pour les branches, par exemple release-v1.5.2, ou v1.5.2-rc?

Ou est-ce inévitable, et donc une idée fondamentalement mauvaise de créer un tag avec le même nom qu'une branche supprimée?

tommarshall
la source

Réponses:

19

Si vous souhaitez absolument conserver ce schéma de dénomination, vous pouvez:

Décidez que vous ne vous souciez pas de ces avertissements

Autrement dit, si vous êtes satisfait du fait que:

  • git checkout <ref>va vérifier refs/heads/<ref>plus refs/tags/<ref>(voir -git checkout )
  • d'autres commandes utiliseront refs/tags/<ref>over refs/heads/<ref>(voir gitrevisions )

Par exemple, dans ce référentiel de test, la v1.5.2branche pointe vers la validation B, mais la v1.5.2balise pointe vers la validation A.

% git log --oneline --decorate
8060f6f (HEAD, v1.5.2, master) commit B
0e69483 (tag: v1.5.2) commit A

git checkout préfère les noms de branche:

% git checkout v1.5.2
warning: refname 'v1.5.2' is ambiguous.
Switched to branch 'v1.5.2'
% git log --decorate --oneline -1
8060f6f (HEAD, v1.5.2, master) commit B

mais git logutilisera le nom de la balise:

% git log --decorate --oneline -1 v1.5.2
warning: refname 'v1.5.2' is ambiguous.
0e69483 (tag: v1.5.2) commit A

Cela pourrait être déroutant.

Former les gens à supprimer leurs succursales locales lorsqu'ils voient une nouvelle balise

Cela peut être difficile / gênant selon la taille de votre organisation.

Écrivez un wrapper autour de "git pull" et "git fetch"

Autrement dit, écrivez un wrapper qui vérifie s'il existe des balises qui masquent les noms des branches et avertissent (ou suppriment) ces branches. Cela semble douloureux et il pourrait être indésirable si la branche ombrée est actuellement extraite.

Malheureusement, il semble que la façon la plus simple de résoudre ce problème soit de changer la façon dont vous nommez vos branches. Le lien que vous avez publié utilise différents schémas de dénomination pour les balises et les branches: si vous suivez déjà principalement cette méthode, adopter son schéma de dénomination pourrait être la solution la plus simple.

benj
la source
Merci pour la réponse. Très utile. Votre première puce indique que git checkoutla balise sera vérifiée sur la branche lorsqu'il y a une référence ambigüe, mais ce n'est pas le comportement que je vois, ref: gist.github.com/tommarshall/9376724 . Est-ce quelque chose qui a changé dans une version plus moderne de git? Existe-t-il un indicateur que je peux définir gitconfigafin d'obtenir ce comportement?
tommarshall
Vous avez raison, je me suis complètement trompé. Pardon! J'ai corrigé ma réponse et ajouté un exemple.
benj
10

Vous pouvez spécifier explicitement si vous souhaitez une branche ou une balise en utilisant le nom complet:

 git checkout refs/heads/v1.5.2

ou

git checkout refs/tags/v1.5.2
mastahu
la source